diff --git a/Juliet/include/Graphics/Graphics.h b/Juliet/include/Graphics/Graphics.h index 7834f96..f04cf8a 100644 --- a/Juliet/include/Graphics/Graphics.h +++ b/Juliet/include/Graphics/Graphics.h @@ -110,6 +110,11 @@ namespace Juliet extern JULIET_API void SetBlendConstants(NonNullPtr renderPass, FColor blendConstants); extern JULIET_API void SetStencilReference(NonNullPtr renderPass, uint8 reference); + extern JULIET_API void BindGraphicsPipeline(NonNullPtr renderPass, NonNullPtr graphicsPipeline); + + extern JULIET_API void DrawPrimitives(NonNullPtr renderPass, uint32 numVertices, uint32 numInstances, + uint32 firstVertex, uint32 firstInstance); + // Shaders extern JULIET_API Shader* CreateShader(NonNullPtr device, String filename, ShaderCreateInfo& shaderCreateInfo); extern JULIET_API void DestroyShader(NonNullPtr device, NonNullPtr shader); diff --git a/Juliet/src/Graphics/D3D12/D3D12CommandList.h b/Juliet/src/Graphics/D3D12/D3D12CommandList.h index 1a97cac..12b5d07 100644 --- a/Juliet/src/Graphics/D3D12/D3D12CommandList.h +++ b/Juliet/src/Graphics/D3D12/D3D12CommandList.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -52,8 +53,25 @@ namespace Juliet::D3D12 D3D12GraphicsCommandListData ComputeCommandList; D3D12CopyCommandListData CopyCommandList; + D3D12GraphicsPipeline* CurrentGraphicsPipeline; + D3D12TextureSubresource* ColorTargetSubresources[GPUDriver::kMaxColorTargetInfo]; D3D12TextureSubresource* ColorResolveSubresources[GPUDriver::kMaxColorTargetInfo]; + + bool NeedVertexBufferBind : 1; + bool NeedVertexSamplerBind : 1; + bool NeedVertexStorageTextureBind : 1; + bool NeedVertexStorageBufferBind : 1; + + bool NeedFragmentSamplerBind : 1; + bool NeedFragmentStorageTextureBind : 1; + bool NeedFragmentStorageBufferBind : 1; + + bool NeedVertexUniformBufferBind[GPUDriver::kMaxUniformBuffersPerStage]; + bool NeedFragmentUniformBufferBind[GPUDriver::kMaxUniformBuffersPerStage]; + + //D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage]; + //D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage]; }; extern CommandList* AcquireCommandList(NonNullPtr driver, QueueType queueType); diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp index 5a5abe8..268b9e9 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsDevice.cpp @@ -262,7 +262,8 @@ namespace Juliet::D3D12 { // Only supported on Win 11 apparently ID3D12InfoQueue1* infoQueue = nullptr; - HRESULT result = ID3D12Device5_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue1, reinterpret_cast(&infoQueue)); + HRESULT result = + ID3D12Device5_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue1, reinterpret_cast(&infoQueue)); if (FAILED(result)) { return; @@ -729,6 +730,8 @@ namespace Juliet::D3D12 device->SetScissorRect = SetScissorRect; device->SetBlendConstants = SetBlendConstants; device->SetStencilReference = SetStencilReference; + device->BindGraphicsPipeline = BindGraphicsPipeline; + device->DrawPrimitives = DrawPrimitives; device->Wait = Wait; device->QueryFence = QueryFence; device->ReleaseFence = ReleaseFence; diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp index 54d4034..7753abb 100644 --- a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp @@ -705,7 +705,7 @@ namespace Juliet::D3D12 return reinterpret_cast(pipeline); } - extern void DestroyGraphicsPipeline(NonNullPtr driver, NonNullPtr graphicsPipeline) + void DestroyGraphicsPipeline(NonNullPtr driver, NonNullPtr graphicsPipeline) { auto d3d12Driver = static_cast(driver.Get()); auto d3d12GraphicsPipeline = reinterpret_cast(graphicsPipeline.Get()); diff --git a/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp b/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp index 719ae62..450b726 100644 --- a/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp +++ b/Juliet/src/Graphics/D3D12/D3D12RenderPass.cpp @@ -1,12 +1,28 @@ #include +#include +#include #include #include -#include - namespace Juliet::D3D12 { + namespace + { + // clang-format off + D3D12_PRIMITIVE_TOPOLOGY JulietToD3D12_PrimitiveType[] = + { + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D_PRIMITIVE_TOPOLOGY_POINTLIST + }; + // clang-format on + static_assert(sizeof(JulietToD3D12_PrimitiveType) / sizeof(JulietToD3D12_PrimitiveType[0]) == + ToUnderlying(PrimitiveType::Count)); + } // namespace + void BeginRenderPass(NonNullPtr commandList, NonNullPtr colorTargetInfos, uint32 colorTargetInfoCount) { auto* d3d12CommandList = reinterpret_cast(commandList.Get()); @@ -146,7 +162,7 @@ namespace Juliet::D3D12 } // TODO : Write Depth stencil - // TODO : Reset graphics pipeline + d3d12CommandList->CurrentGraphicsPipeline = nullptr; ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList, 0, NULL, false, NULL); @@ -154,7 +170,78 @@ namespace Juliet::D3D12 ZeroArray(d3d12CommandList->ColorTargetSubresources); ZeroArray(d3d12CommandList->ColorResolveSubresources); // TODO : reset depth stencil subresources + // d3d12CommandList->DepthStencilTextureSubresource = NULL; + // TODO : vertex buffer // TODO :Vertex sampler and fragment sampler + + // ZeroArray(d3d12CommandList->VertexBuffers); + // ZeroArray(d3d12CommandList->VertexBufferOffsets); + // d3d12CommandList->VertexBufferCount = 0; + // + // ZeroArray(d3d12CommandList->VertexSamplerTextures); + // ZeroArray(d3d12CommandList->VertexSamplers); + // ZeroArray(d3d12CommandList->VertexStorageTextures); + // ZeroArray(d3d12CommandList->VertexStorageBuffers); + // + // ZeroArray(d3d12CommandList->FragmentSamplerTextures); + // ZeroArray(d3d12CommandList->FragmentSamplers); + // ZeroArray(d3d12CommandList->FragmentStorageTextures); + // ZeroArray(d3d12CommandList->FragmentStorageBuffers); + } + + void BindGraphicsPipeline(NonNullPtr commandList, NonNullPtr graphicsPipeline) + { + auto* d3d12CommandList = reinterpret_cast(commandList.Get()); + auto pipeline = reinterpret_cast(graphicsPipeline.Get()); + + d3d12CommandList->CurrentGraphicsPipeline = pipeline; + + // Set the pipeline state + ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandList->GraphicsCommandList.CommandList, pipeline->PipelineState); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandList->GraphicsCommandList.CommandList, + pipeline->RootSignature->Handle); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandList->GraphicsCommandList.CommandList, + JulietToD3D12_PrimitiveType[ToUnderlying(pipeline->PrimitiveType)]); + + // Mark that bindings are needed + d3d12CommandList->NeedVertexSamplerBind = true; + d3d12CommandList->NeedVertexStorageTextureBind = true; + d3d12CommandList->NeedVertexStorageBufferBind = true; + d3d12CommandList->NeedFragmentSamplerBind = true; + d3d12CommandList->NeedFragmentStorageTextureBind = true; + d3d12CommandList->NeedFragmentStorageBufferBind = true; + + for (uint32 idx = 0; idx < GPUDriver::kMaxUniformBuffersPerStage; ++idx) + { + d3d12CommandList->NeedVertexUniformBufferBind[idx] = true; + d3d12CommandList->NeedFragmentUniformBufferBind[idx] = true; + } + + for (uint32 idx = 0; idx < pipeline->VertexUniformBufferCount; ++idx) + { + // if (d3d12CommandList->VertexUniformBuffers[i] == NULL) + // { + // d3d12CommandList->VertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(d3d12CommandBuffer); + // } + } + + for (uint32 idx = 0; idx < pipeline->FragmentUniformBufferCount; ++idx) + { + // if (d3d12CommandList->FragmentUniformBuffers[i] == NULL) + // { + // d3d12CommandList->FragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(d3d12CommandBuffer); + // } + } + } + + void DrawPrimitives(NonNullPtr commandList, uint32 numVertices, uint32 numInstances, uint32 firstVertex, uint32 firstInstance) + { + auto* d3d12CommandList = reinterpret_cast(commandList.Get()); + // TODO : Last missing piece + // D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer); + + ID3D12GraphicsCommandList_DrawInstanced(d3d12CommandList->GraphicsCommandList.CommandList, numVertices, + numInstances, firstVertex, firstInstance); } } // namespace Juliet::D3D12 diff --git a/Juliet/src/Graphics/D3D12/D3D12RenderPass.h b/Juliet/src/Graphics/D3D12/D3D12RenderPass.h index 0c9854f..fcf448f 100644 --- a/Juliet/src/Graphics/D3D12/D3D12RenderPass.h +++ b/Juliet/src/Graphics/D3D12/D3D12RenderPass.h @@ -9,4 +9,8 @@ namespace Juliet::D3D12 extern void BeginRenderPass(NonNullPtr commandList, NonNullPtr colorTargetInfos, uint32 colorTargetInfoCount); extern void EndRenderPass(NonNullPtr commandList); + + extern void BindGraphicsPipeline(NonNullPtr commandList, NonNullPtr graphicsPipeline); + extern void DrawPrimitives(NonNullPtr commandList, uint32 numVertices, uint32 numInstances, + uint32 firstVertex, uint32 firstInstance); } // namespace Juliet::D3D12 diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp index 52bc6f2..2ef00b4 100644 --- a/Juliet/src/Graphics/Graphics.cpp +++ b/Juliet/src/Graphics/Graphics.cpp @@ -181,6 +181,23 @@ namespace Juliet commandListHeader->Device->SetStencilReference(commandList, reference); } + void BindGraphicsPipeline(NonNullPtr renderPass, NonNullPtr graphicsPipeline) + { + auto* commandList = reinterpret_cast(renderPass.Get())->CommandList; + auto* commandListHeader = reinterpret_cast(commandList); + + commandListHeader->Device->BindGraphicsPipeline(commandList, graphicsPipeline); + } + + void DrawPrimitives(NonNullPtr renderPass, uint32 numVertices, uint32 numInstances, + uint32 firstVertex, uint32 firstInstance) + { + auto* commandList = reinterpret_cast(renderPass.Get())->CommandList; + auto* commandListHeader = reinterpret_cast(commandList); + + commandListHeader->Device->DrawPrimitives(commandList, numVertices, numInstances, firstVertex, firstInstance); + } + // Shaders Shader* CreateShader(NonNullPtr device, String filename, ShaderCreateInfo& shaderCreateInfo) { diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h index c51fd90..e1b08fe 100644 --- a/Juliet/src/Graphics/GraphicsDevice.h +++ b/Juliet/src/Graphics/GraphicsDevice.h @@ -63,6 +63,10 @@ namespace Juliet void (*SetBlendConstants)(NonNullPtr commandList, FColor blendConstants); void (*SetStencilReference)(NonNullPtr commandList, uint8 reference); + void (*BindGraphicsPipeline)(NonNullPtr commandList, NonNullPtr graphicsPipeline); + void (*DrawPrimitives)(NonNullPtr commandList, uint32 numVertices, uint32 numInstances, + uint32 firstVertex, uint32 firstInstance); + // Fences bool (*Wait)(NonNullPtr driver); bool (*QueryFence)(NonNullPtr driver, NonNullPtr fence); diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp index fa523a9..0b75973 100644 --- a/JulietApp/main.cpp +++ b/JulietApp/main.cpp @@ -204,6 +204,8 @@ void JulietApplication::Update() colorTargetInfo.StoreOperation = StoreOperation::Store; RenderPass* renderPass = BeginRenderPass(cmdList, colorTargetInfo); + BindGraphicsPipeline(renderPass, GraphicsPipeline); + DrawPrimitives(renderPass, 3, 1, 0, 0); EndRenderPass(renderPass); }