Command list Submit done.

This commit is contained in:
2025-02-18 21:52:49 -05:00
parent ed9482b8f8
commit 857f8c4e69
8 changed files with 143 additions and 26 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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,

View File

@@ -111,7 +111,7 @@ void Win32EditorApplication::Update()
}
// Submit Commands
SubmitCommandLists(GraphicsDevice);
SubmitCommandLists(cmdList);
}
bool Win32EditorApplication::IsRunning()