From aae780ec6da9dbacfaa8b2d1355232ef366fe4ca Mon Sep 17 00:00:00 2001 From: Patedam Date: Sun, 9 Mar 2025 16:54:26 -0400 Subject: [PATCH] First pass graphics pipeline. Not functional --- Juliet/Juliet.vcxproj | 3 + Juliet/include/Graphics/Graphics.h | 10 ++- Juliet/include/Graphics/GraphicsPipeline.h | 61 +++++++++++++++++++ Juliet/include/Graphics/RenderPass.h | 11 ++++ .../Graphics/D3D12/D3D12GraphicsPipeline.cpp | 14 +++++ .../Graphics/D3D12/D3D12GraphicsPipeline.h | 15 +++++ .../src/Graphics/D3D12/DX12GraphicsDevice.cpp | 44 ++++++------- Juliet/src/Graphics/D3D12/DX12SwapChain.cpp | 15 +++++ Juliet/src/Graphics/D3D12/DX12SwapChain.h | 1 + Juliet/src/Graphics/Graphics.cpp | 9 +++ Juliet/src/Graphics/GraphicsDevice.h | 5 ++ JulietApp/main.cpp | 38 +++++++++--- 12 files changed, 194 insertions(+), 32 deletions(-) create mode 100644 Juliet/include/Graphics/GraphicsPipeline.h create mode 100644 Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp create mode 100644 Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj index c23400c..43918ae 100644 --- a/Juliet/Juliet.vcxproj +++ b/Juliet/Juliet.vcxproj @@ -144,6 +144,7 @@ + @@ -165,6 +166,7 @@ + @@ -206,6 +208,7 @@ + diff --git a/Juliet/include/Graphics/Graphics.h b/Juliet/include/Graphics/Graphics.h index f06f776..9d3e12d 100644 --- a/Juliet/include/Graphics/Graphics.h +++ b/Juliet/include/Graphics/Graphics.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -12,6 +13,7 @@ // Graphics Interface namespace Juliet { + // Opaque types struct CommandList; struct GraphicsDevice; @@ -91,6 +93,7 @@ namespace Juliet // SwapChain extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture); + extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr device, NonNullPtr window); // Command List extern JULIET_API CommandList* AcquireCommandList(NonNullPtr device, QueueType queueType = QueueType::Graphics); @@ -109,5 +112,10 @@ namespace Juliet // Shaders extern JULIET_API Shader* CreateShader(NonNullPtr device, String filename, ShaderCreateInfo& shaderCreateInfo); - extern JULIET_API void DestroyShader(NonNullPtr driver, NonNullPtr shader); + extern JULIET_API void DestroyShader(NonNullPtr device, NonNullPtr shader); + + // Pipelines + extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr device, + GraphicsPipelineCreateInfo& createInfo); + } // namespace Juliet diff --git a/Juliet/include/Graphics/GraphicsPipeline.h b/Juliet/include/Graphics/GraphicsPipeline.h new file mode 100644 index 0000000..76d66d4 --- /dev/null +++ b/Juliet/include/Graphics/GraphicsPipeline.h @@ -0,0 +1,61 @@ +#pragma once +#include + +namespace Juliet +{ + // Forward Declare + struct ColorTargetDescription; + + enum class FillMode : uint8 + { + Wireframe, + Solid + }; + + enum class CullMode : uint8 + { + None, + Front, + Back + }; + + enum class FrontFace : uint8 + { + CounterClockwise, + Clockwise + }; + + enum class PrimitiveType : uint8 + { + TriangleList, + TriangleStrip, + LineList, + LineStrip, + PointList, + }; + + struct RasterizerState + { + FillMode FillMode; + CullMode CullMode; + FrontFace FrontFace; + }; + + struct GraphicsPipelineTargetInfo + { + const ColorTargetDescription* ColorTargetDescriptions; + size_t NumColorTargets; + }; + + struct GraphicsPipelineCreateInfo + { + Shader* VertexShader; + Shader* FragmentShader; + RasterizerState RasterizerState; + PrimitiveType PrimitiveType; + GraphicsPipelineTargetInfo TargetInfo; + }; + + // Opaque type + struct GraphicsPipeline; +} // namespace Juliet diff --git a/Juliet/include/Graphics/RenderPass.h b/Juliet/include/Graphics/RenderPass.h index b5abb46..b8de189 100644 --- a/Juliet/include/Graphics/RenderPass.h +++ b/Juliet/include/Graphics/RenderPass.h @@ -41,6 +41,17 @@ namespace Juliet StoreOperation StoreOperation; }; + struct ColorTargetBlendState + { + + }; + + struct ColorTargetDescription + { + TextureFormat Format; + ColorTargetBlendState BlendState; + }; + // Opaque Type struct RenderPass; } // namespace Juliet diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp new file mode 100644 index 0000000..267b3ba --- /dev/null +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp @@ -0,0 +1,14 @@ +#include + +#include + +#include +#include + +namespace Juliet::D3D12 +{ + GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr driver, GraphicsPipelineCreateInfo& createInfo) + { + return nullptr; + } +} // namespace Juliet::D3D12 diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h new file mode 100644 index 0000000..b7efc14 --- /dev/null +++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace Juliet +{ + struct GraphicsPipelineCreateInfo; + struct GPUDriver; + struct GraphicsPipeline; +} // namespace Juliet + +namespace Juliet::D3D12 +{ + extern GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr driver, GraphicsPipelineCreateInfo& createInfo); +} diff --git a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp index f405818..4acfdda 100644 --- a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp +++ b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -596,30 +597,25 @@ namespace Juliet::D3D12 } // Assign Functions to the device - device->DestroyDevice = DestroyGraphicsDevice; - - device->AttachToWindow = AttachToWindow; - device->DetachFromWindow = DetachFromWindow; - - device->AcquireSwapChainTexture = AcquireSwapChainTexture; - - device->AcquireCommandList = AcquireCommandList; - device->SubmitCommandLists = SubmitCommandLists; - - device->BeginRenderPass = BeginRenderPass; - device->EndRenderPass = EndRenderPass; - - device->SetViewPort = SetViewPort; - device->SetScissorRect = SetScissorRect; - device->SetBlendConstants = SetBlendConstants; - device->SetStencilReference = SetStencilReference; - - device->Wait = Wait; - device->QueryFence = QueryFence; - device->ReleaseFence = ReleaseFence; - - device->CreateShader = CreateShader; - device->DestroyShader = DestroyShader; + device->DestroyDevice = DestroyGraphicsDevice; + device->AttachToWindow = AttachToWindow; + device->DetachFromWindow = DetachFromWindow; + device->AcquireSwapChainTexture = AcquireSwapChainTexture; + device->GetSwapChainTextureFormat = GetSwapChainTextureFormat; + device->AcquireCommandList = AcquireCommandList; + device->SubmitCommandLists = SubmitCommandLists; + device->BeginRenderPass = BeginRenderPass; + device->EndRenderPass = EndRenderPass; + device->SetViewPort = SetViewPort; + device->SetScissorRect = SetScissorRect; + device->SetBlendConstants = SetBlendConstants; + device->SetStencilReference = SetStencilReference; + device->Wait = Wait; + device->QueryFence = QueryFence; + device->ReleaseFence = ReleaseFence; + device->CreateShader = CreateShader; + device->DestroyShader = DestroyShader; + device->CreateGraphicsPipeline = CreateGraphicsPipeline; device->Driver = driver; driver->GraphicsDevice = device; diff --git a/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp b/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp index 08f2792..216eead 100644 --- a/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp +++ b/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp @@ -192,6 +192,21 @@ namespace Juliet::D3D12 return AcquireSwapChainTexture(false, commandList, window, swapChainTexture); } + TextureFormat GetSwapChainTextureFormat(NonNullPtr driver, NonNullPtr window) + { + auto* d3d12Driver = static_cast(driver.Get()); + + auto* windowData = d3d12Driver->WindowData; + if (!windowData) + { + LogError(LogCategory::Graphics, "Cannot get swapchain format. Window has no Swapchain"); + return TextureFormat::Invalid; + } + + Assert(windowData->Window == window.Get()); + return windowData->SwapChainTextureContainers[windowData->WindowFrameCounter].Header.CreateInfo.Format; + } + namespace Internal { bool CreateSwapChain(NonNullPtr driver, NonNullPtr windowData, diff --git a/Juliet/src/Graphics/D3D12/DX12SwapChain.h b/Juliet/src/Graphics/D3D12/DX12SwapChain.h index fc12aec..c9f95e4 100644 --- a/Juliet/src/Graphics/D3D12/DX12SwapChain.h +++ b/Juliet/src/Graphics/D3D12/DX12SwapChain.h @@ -8,6 +8,7 @@ namespace Juliet::D3D12 struct D3D12WindowData; extern bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture); +extern TextureFormat GetSwapChainTextureFormat(NonNullPtr driver, NonNullPtr window); namespace Internal { diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp index 3ef6b47..539a9b3 100644 --- a/Juliet/src/Graphics/Graphics.cpp +++ b/Juliet/src/Graphics/Graphics.cpp @@ -88,6 +88,11 @@ namespace Juliet return true; } + TextureFormat GetSwapChainTextureFormat(NonNullPtr device, NonNullPtr window) + { + return device->GetSwapChainTextureFormat(device->Driver, window); + } + CommandList* AcquireCommandList(NonNullPtr device, QueueType queueType /* = QueueType::Graphics */) { GPUDriver* driver = device->Driver; @@ -213,4 +218,8 @@ namespace Juliet device->DestroyShader(device->Driver, shader); } + GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr device, GraphicsPipelineCreateInfo& createInfo) + { + device->CreateGraphicsPipeline(device->Driver, createInfo); + } } // namespace Juliet diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h index 2615fce..b09c6d6 100644 --- a/Juliet/src/Graphics/GraphicsDevice.h +++ b/Juliet/src/Graphics/GraphicsDevice.h @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace Juliet @@ -44,6 +45,7 @@ namespace Juliet // SwapChain bool (*AcquireSwapChainTexture)(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture); + TextureFormat (*GetSwapChainTextureFormat)(NonNullPtr driver, NonNullPtr window); // CommandLists CommandList* (*AcquireCommandList)(NonNullPtr driver, QueueType queueType); @@ -68,6 +70,9 @@ namespace Juliet Shader* (*CreateShader)(NonNullPtr driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo); void (*DestroyShader)(NonNullPtr driver, NonNullPtr shader); + // Pipeline + GraphicsPipeline* (*CreateGraphicsPipeline)(NonNullPtr driver, GraphicsPipelineCreateInfo& createInfo); + const char* Name = "Unknown"; GPUDriver* Driver = nullptr; }; diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp index bbca511..0e21167 100644 --- a/JulietApp/main.cpp +++ b/JulietApp/main.cpp @@ -14,6 +14,7 @@ #include #include #include +#include // TODO : Replace with message box from framework + call main and not winmain + subsystem // TODO : Think how to do the draw pipeline. @@ -60,15 +61,38 @@ void JulietApplication::Init() { // Create graphics pipeline - // TODO: Assets management that handles path to assets or something. - String shaderPath = WrapString("../../../Assets/compiled/Triangle.vert.dxil"); + String entryPoint = WrapString("main"); ShaderCreateInfo shaderCI = {}; - shaderCI.Stage = ShaderStage::Vertex; - shaderCI.EntryPoint = WrapString("main"); - Shader* shader = CreateShader(GraphicsDevice, shaderPath, shaderCI); - if (shader) + shaderCI.EntryPoint = entryPoint; + + // TODO: Assets management that handles path to assets or something. + String shaderPath = WrapString("../../../Assets/compiled/Triangle.vert.dxil"); + shaderCI.Stage = ShaderStage::Vertex; + Shader* vertexShader = CreateShader(GraphicsDevice, shaderPath, shaderCI); + + shaderPath = WrapString("../../../Assets/compiled/SolidColor.frag.dxil"); + shaderCI.Stage = ShaderStage::Fragment; + Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI); + + ColorTargetDescription colorTargetDescription = { .Format = GetSwapChainTextureFormat(GraphicsDevice, MainWindow) }; + GraphicsPipelineCreateInfo pipelineCI = { + .VertexShader = vertexShader, + .FragmentShader = fragmentShader, + .PrimitiveType = PrimitiveType::TriangleList, + .TargetInfo = { + .ColorTargetDescriptions = &colorTargetDescription, + .NumColorTargets = 1, + }, + }; + pipelineCI.RasterizerState.FillMode = FillMode::Solid; + + if (vertexShader) { - DestroyShader(GraphicsDevice, shader); + DestroyShader(GraphicsDevice, vertexShader); + } + if (fragmentShader) + { + DestroyShader(GraphicsDevice, fragmentShader); } }