Command list Submit done.
This commit is contained in:
@@ -13,6 +13,7 @@ namespace Juliet
|
||||
// Opaque types
|
||||
struct CommandList;
|
||||
struct GraphicsDevice;
|
||||
struct Fence;
|
||||
|
||||
// Parameters of an indirect draw command
|
||||
struct IndirectDrawCommand
|
||||
@@ -91,7 +92,7 @@ namespace Juliet
|
||||
|
||||
// Command List
|
||||
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
|
||||
extern JULIET_API void SubmitCommandLists(NonNullPtr<GraphicsDevice> device);
|
||||
extern JULIET_API void SubmitCommandLists(NonNullPtr<CommandList> commandList);
|
||||
|
||||
// RenderPass
|
||||
extern JULIET_API RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Graphics/D3D12/DX12CommandList.h>
|
||||
#include <Graphics/D3D12/DX12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/DX12Utils.h>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
@@ -194,21 +195,116 @@ namespace Juliet::D3D12
|
||||
return reinterpret_cast<CommandList*>(commandList);
|
||||
}
|
||||
|
||||
bool SubmitCommandLists(NonNullPtr<GPUDriver> driver)
|
||||
bool SubmitCommandLists(NonNullPtr<CommandList> commandList)
|
||||
{
|
||||
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
|
||||
bool success = true;
|
||||
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
|
||||
auto* d3d12Driver = d3d12CommandList->Driver;
|
||||
// TODO : Use QueueType to choose the correct CommandList and Command Queue
|
||||
// Only use graphics for now
|
||||
|
||||
uint8 commandLastIndex = d3d12Driver->AvailableCommandListCount;
|
||||
|
||||
// TODO : Get window data from the command list: We associate the swapchain texture to a window with a missing function
|
||||
HRESULT result = IDXGISwapChain_Present(d3d12Driver->WindowData->SwapChain, 0, 1);
|
||||
if (FAILED(result))
|
||||
// Transition present textures to present mode
|
||||
for (uint32 i = 0; i < d3d12CommandList->PresentDataCount; i += 1)
|
||||
{
|
||||
success = false;
|
||||
uint32 swapchainIndex = d3d12CommandList->PresentDatas[i].SwapChainImageIndex;
|
||||
D3D12TextureContainer* container =
|
||||
&d3d12CommandList->PresentDatas[i].WindowData->SwapChainTextureContainers[swapchainIndex];
|
||||
D3D12TextureSubresource* subresource = FetchTextureSubresource(container, 0, 0);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrierDesc;
|
||||
barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrierDesc.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrierDesc.Transition.pResource = subresource->Parent->Resource;
|
||||
barrierDesc.Transition.Subresource = subresource->Index;
|
||||
|
||||
ID3D12GraphicsCommandList_ResourceBarrier(d3d12CommandList->GraphicsCommandList.CommandList, 1, &barrierDesc);
|
||||
}
|
||||
|
||||
// Notify the command buffer that we have completed recording
|
||||
HRESULT result = ID3D12GraphicsCommandList_Close(d3d12CommandList->GraphicsCommandList.CommandList);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(d3d12Driver, "Failed to close command list!", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
ID3D12CommandList* commandLists[1];
|
||||
result = ID3D12GraphicsCommandList_QueryInterface(d3d12CommandList->GraphicsCommandList.CommandList,
|
||||
IID_ID3D12CommandList, reinterpret_cast<void**>(&commandLists[0]));
|
||||
if (FAILED(result))
|
||||
{
|
||||
LogError(d3d12Driver, "Failed to convert command list!", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Submit the command list to the queue
|
||||
ID3D12CommandQueue_ExecuteCommandLists(d3d12Driver->GraphicsQueue, 1, commandLists);
|
||||
|
||||
ID3D12CommandList_Release(commandLists[0]);
|
||||
|
||||
// TODO Fences
|
||||
|
||||
// Mark the command list as submitted
|
||||
if (d3d12Driver->SubmittedCommandBufferCount + 1 >= d3d12Driver->SubmittedCommandListCapacity) {
|
||||
d3d12Driver->SubmittedCommandListCapacity = d3d12Driver->SubmittedCommandBufferCount + 1;
|
||||
|
||||
d3d12Driver->SubmittedCommandLists = static_cast<D3D12CommandList**>(
|
||||
Realloc(d3d12Driver->SubmittedCommandLists, sizeof(D3D12CommandList*) * d3d12Driver->SubmittedCommandListCapacity));
|
||||
}
|
||||
|
||||
d3d12Driver->SubmittedCommandLists[d3d12Driver->SubmittedCommandBufferCount] = d3d12CommandList;
|
||||
d3d12Driver->SubmittedCommandBufferCount += 1;
|
||||
|
||||
bool success = true;
|
||||
for (uint32 i = 0; i < d3d12CommandList->PresentDataCount; i += 1)
|
||||
{
|
||||
D3D12PresentData* presentData = &d3d12CommandList->PresentDatas[i];
|
||||
auto* windowData = presentData->WindowData;
|
||||
|
||||
// NOTE: flip discard always supported since DXGI 1.4 is required
|
||||
uint32 syncInterval = 1;
|
||||
if (windowData->PresentMode == PresentMode::Immediate || windowData->PresentMode == PresentMode::Mailbox)
|
||||
{
|
||||
syncInterval = 0;
|
||||
}
|
||||
|
||||
uint32 presentFlags = 0;
|
||||
if (d3d12Driver->IsTearingSupported && windowData->PresentMode == PresentMode::Immediate)
|
||||
{
|
||||
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
|
||||
}
|
||||
|
||||
result = IDXGISwapChain_Present(windowData->SwapChain, syncInterval, presentFlags);
|
||||
if (FAILED(result))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
ID3D12Resource_Release(windowData->SwapChainTextureContainers[presentData->SwapChainImageIndex].ActiveTexture->Resource);
|
||||
|
||||
//windowData->inFlightFences[windowData->frameCounter] = (SDL_GPUFence*)d3d12CommandBuffer->inFlightFence;
|
||||
//(void)SDL_AtomicIncRef(&d3d12CommandBuffer->inFlightFence->referenceCount);
|
||||
windowData->WindowFrameCounter = (windowData->WindowFrameCounter + 1) % d3d12Driver->FramesInFlight;
|
||||
}
|
||||
|
||||
// TODO : Correctly clean up and destroy
|
||||
d3d12Driver->AvailableCommandListCount = 0;
|
||||
// Check for cleanups
|
||||
// for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
|
||||
// Uint64 fenceValue = ID3D12Fence_GetCompletedValue(
|
||||
// renderer->submittedCommandBuffers[i]->inFlightFence->handle);
|
||||
//
|
||||
// if (fenceValue == D3D12_FENCE_SIGNAL_VALUE) {
|
||||
// result &= D3D12_INTERNAL_CleanCommandBuffer(
|
||||
// renderer,
|
||||
// renderer->submittedCommandBuffers[i],
|
||||
// false);
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO Destroy anything (buffer, texture, etc...)
|
||||
|
||||
++d3d12Driver->FrameCounter;
|
||||
|
||||
return success;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Juliet::D3D12
|
||||
};
|
||||
|
||||
extern CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType);
|
||||
extern bool SubmitCommandLists(NonNullPtr<GPUDriver> driver);
|
||||
extern bool SubmitCommandLists(NonNullPtr<CommandList> commandList);
|
||||
extern void SetViewPort(NonNullPtr<CommandList> commandList, const GraphicsViewPort& viewPort);
|
||||
extern void SetScissorRect(NonNullPtr<CommandList> commandList, const Rectangle& rectangle);
|
||||
extern void SetBlendConstants(NonNullPtr<CommandList> commandList, FColor blendConstants);
|
||||
|
||||
@@ -518,15 +518,18 @@ namespace Juliet::D3D12
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto device = static_cast<GraphicsDevice*>(Calloc(1, sizeof(GraphicsDevice)));
|
||||
if (!device)
|
||||
// Create Pools
|
||||
driver->SubmittedCommandListCapacity = 4;
|
||||
driver->SubmittedCommandBufferCount = 0;
|
||||
driver->SubmittedCommandLists =
|
||||
static_cast<D3D12CommandList**>(Calloc(driver->SubmittedCommandListCapacity, sizeof(D3D12CommandList*)));
|
||||
if (!driver->SubmittedCommandLists)
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create Pools
|
||||
|
||||
// Staging descriptor pools
|
||||
for (uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1)
|
||||
{
|
||||
driver->StagingDescriptorPools[i] =
|
||||
@@ -535,10 +538,17 @@ namespace Juliet::D3D12
|
||||
if (driver->StagingDescriptorPools[i] == nullptr)
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto device = static_cast<GraphicsDevice*>(Calloc(1, sizeof(GraphicsDevice)));
|
||||
if (!device)
|
||||
{
|
||||
DestroyDriver_Internal(driver);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Assign Functions to the device
|
||||
device->DestroyDevice = DestroyGraphicsDevice;
|
||||
|
||||
@@ -551,11 +561,11 @@ namespace Juliet::D3D12
|
||||
device->SubmitCommandLists = SubmitCommandLists;
|
||||
|
||||
device->BeginRenderPass = BeginRenderPass;
|
||||
device->EndRenderPass = EndRenderPass;
|
||||
device->EndRenderPass = EndRenderPass;
|
||||
|
||||
device->SetViewPort = SetViewPort;
|
||||
device->SetScissorRect = SetScissorRect;
|
||||
device->SetBlendConstants = SetBlendConstants;
|
||||
device->SetViewPort = SetViewPort;
|
||||
device->SetScissorRect = SetScissorRect;
|
||||
device->SetBlendConstants = SetBlendConstants;
|
||||
device->SetStencilReference = SetStencilReference;
|
||||
|
||||
device->Driver = driver;
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace Juliet::D3D12
|
||||
|
||||
PresentMode PresentMode;
|
||||
|
||||
Fence* InFlightFences[GPUDriver::kMaxFramesInFlight];
|
||||
|
||||
uint32 WindowFrameCounter; // Specific to that window. See GraphicsDevice for global counter
|
||||
uint32 Width;
|
||||
uint32 Height;
|
||||
@@ -66,9 +68,13 @@ namespace Juliet::D3D12
|
||||
uint8 AvailableCommandListCapacity;
|
||||
uint8 AvailableCommandListCount;
|
||||
|
||||
D3D12CommandList** SubmittedCommandLists;
|
||||
uint8 SubmittedCommandListCapacity;
|
||||
uint8 SubmittedCommandBufferCount;
|
||||
|
||||
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
|
||||
|
||||
uint8 FramesInFlight;
|
||||
uint8 FramesInFlight;
|
||||
uint64 FrameCounter = 0; // Number of frame since inception
|
||||
|
||||
bool IsTearingSupported : 1;
|
||||
|
||||
@@ -103,10 +103,13 @@ namespace Juliet
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
void SubmitCommandLists(NonNullPtr<GraphicsDevice> device)
|
||||
void SubmitCommandLists(NonNullPtr<CommandList> commandList)
|
||||
{
|
||||
GPUDriver* driver = device->Driver;
|
||||
device->SubmitCommandLists(driver);
|
||||
auto* commandListHeader = reinterpret_cast<CommandListHeader*>(commandList.Get());
|
||||
|
||||
commandListHeader->Submitted = true;
|
||||
|
||||
commandListHeader->Device->SubmitCommandLists(commandList);
|
||||
}
|
||||
|
||||
RenderPass* BeginRenderPass(NonNullPtr<CommandList> commandList, ColorTargetInfo& colorTargetInfo)
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Juliet
|
||||
{
|
||||
GraphicsDevice* Device = nullptr;
|
||||
bool AcquiredSwapChain = false;
|
||||
bool Submitted = false;
|
||||
|
||||
GPUPass RenderPass;
|
||||
};
|
||||
@@ -46,7 +47,7 @@ namespace Juliet
|
||||
|
||||
// CommandLists
|
||||
CommandList* (*AcquireCommandList)(NonNullPtr<GPUDriver> driver, QueueType queueType);
|
||||
bool (*SubmitCommandLists)(NonNullPtr<GPUDriver> driver);
|
||||
bool (*SubmitCommandLists)(NonNullPtr<CommandList> commandList);
|
||||
|
||||
// RenderPass
|
||||
void (*BeginRenderPass)(NonNullPtr<CommandList> commandList, NonNullPtr<const ColorTargetInfo> colorTargetInfos,
|
||||
|
||||
@@ -111,7 +111,7 @@ void Win32EditorApplication::Update()
|
||||
}
|
||||
|
||||
// Submit Commands
|
||||
SubmitCommandLists(GraphicsDevice);
|
||||
SubmitCommandLists(cmdList);
|
||||
}
|
||||
|
||||
bool Win32EditorApplication::IsRunning()
|
||||
|
||||
Reference in New Issue
Block a user