From c2b1049c7a23700587c5e34d7e5d4503bfeb6b87 Mon Sep 17 00:00:00 2001 From: StarsX Date: Wed, 17 Apr 2024 10:30:02 +0800 Subject: [PATCH] Fix generic pipeline --- XUSG/Core/XUSG.h | 44 +- XUSG/Core/XUSGComputeState_DX12.cpp | 50 +- XUSG/Core/XUSGComputeState_DX12.h | 12 +- XUSG/Core/XUSGGraphicsState_DX12.cpp | 142 ++- XUSG/Core/XUSGGraphicsState_DX12.h | 29 +- ...ate_DX12.cpp => XUSGGenericState_DX12.cpp} | 146 ++- ...amState_DX12.h => XUSGGenericState_DX12.h} | 31 +- XUSG/Ultimate/XUSGPipelineState_DX12.cpp | 851 ++++++++++++++++-- XUSG/Ultimate/XUSGPipelineState_DX12.h | 44 +- XUSG/Ultimate/XUSGUltimate.cpp | 14 +- XUSG/Ultimate/XUSGUltimate.h | 90 +- XUSG/Ultimate/XUSGUltimate_DX12.cpp | 25 +- XUSG/Ultimate/XUSGUltimate_DX12.h | 13 +- XUSG/Ultimate/XUSGWorkGraph_DX12.cpp | 17 +- XUSG/Ultimate/XUSGWorkGraph_DX12.h | 2 +- XUSG/XUSG.vcxproj | 4 +- XUSG/XUSG.vcxproj.filters | 4 +- XUSGRayTracing/RayTracing/XUSGRayTracing.h | 4 +- .../RayTracing/XUSGRayTracingState_DX12.cpp | 17 +- .../RayTracing/XUSGRayTracingState_DX12.h | 2 +- 20 files changed, 1360 insertions(+), 181 deletions(-) rename XUSG/Ultimate/{XUSGProgramState_DX12.cpp => XUSGGenericState_DX12.cpp} (85%) rename XUSG/Ultimate/{XUSGProgramState_DX12.h => XUSGGenericState_DX12.h} (79%) diff --git a/XUSG/Core/XUSG.h b/XUSG/Core/XUSG.h index d0757db..db6ef61 100644 --- a/XUSG/Core/XUSG.h +++ b/XUSG/Core/XUSG.h @@ -2340,12 +2340,30 @@ namespace XUSG virtual Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; virtual Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; - // Get the key of the pipeline cache for XUSG pipeline lib - virtual const std::string& GetKey() const = 0; + virtual PipelineLayout GetPipelineLayout() const = 0; + virtual Blob GetShader(Shader::Stage stage) const = 0; + virtual Blob GetCachedPipeline() const = 0; + virtual uint32_t GetNodeMask() const = 0; + virtual PipelineFlag GetFlags() const = 0; + + virtual uint32_t OMGetSampleMask() const = 0; + virtual const Blend* OMGetBlendState() const = 0; + virtual const Rasterizer* RSGetState() const = 0; + virtual const DepthStencil* DSGetState() const = 0; + + virtual const InputLayout* IAGetInputLayout() const = 0; + virtual PrimitiveTopologyType IAGetPrimitiveTopologyType() const = 0; + virtual IBStripCutValue IAGetIndexBufferStripCutValue() const = 0; + + virtual uint8_t OMGetNumRenderTargets() const = 0; + virtual Format OMGetRTVFormat(uint8_t i) const = 0; + virtual Format OMGetDSVFormat() const = 0; + virtual uint8_t OMGetSampleCount() const = 0; + virtual uint8_t OMGetSampleQuality() const = 0; // Get API native desc of this PSO handle // pInputElements should be a pointer to std::vector<[API]_INPUT_ELEMENT_DESC> - virtual void GetHandleDesc(void* pHandleDesc, void* pInputElements, PipelineLib* pPipelineLib) const = 0; + virtual void GetHandleDesc(void* pHandleDesc, void* pInputElements) const = 0; using uptr = std::unique_ptr; using sptr = std::shared_ptr; @@ -2362,7 +2380,7 @@ namespace XUSG virtual ~PipelineLib() {}; virtual void SetDevice(const Device* pDevice) = 0; - virtual void SetPipeline(const std::string& key, const Pipeline& pipeline) = 0; + virtual void SetPipeline(const State* pState, const Pipeline& pipeline) = 0; virtual void SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements) = 0; virtual const InputLayout* GetInputLayout(uint32_t index) const = 0; @@ -2375,10 +2393,6 @@ namespace XUSG virtual const Rasterizer* GetRasterizer(RasterizerPreset preset) = 0; virtual const DepthStencil* GetDepthStencil(DepthStencilPreset preset) = 0; - // Get API native desc of this PSO handle - // pInputElements should be a pointer to std::vector<[API]_INPUT_ELEMENT_DESC> - virtual void GetHandleDesc(void* pHandleDesc, void* pInputElements, const std::string& key) = 0; - static DepthStencil DepthStencilDefault(); static DepthStencil DepthStencilNone(); static DepthStencil DepthRead(); @@ -2439,11 +2453,14 @@ namespace XUSG virtual Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; virtual Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; - // Get the key of the pipeline cache for XUSG pipeline lib - virtual const std::string& GetKey() const = 0; + virtual PipelineLayout GetPipelineLayout() const = 0; + virtual Blob GetShader() const = 0; + virtual Blob GetCachedPipeline() const = 0; + virtual uint32_t GetNodeMask() const = 0; + virtual PipelineFlag GetFlags() const = 0; // Get API native desc of this PSO handle - virtual void GetHandleDesc(void* pHandleDesc, PipelineLib* pPipelineLib) const = 0; + virtual void GetHandleDesc(void* pHandleDesc) const = 0; using uptr = std::unique_ptr; using sptr = std::shared_ptr; @@ -2460,14 +2477,11 @@ namespace XUSG virtual ~PipelineLib() {}; virtual void SetDevice(const Device* pDevice) = 0; - virtual void SetPipeline(const std::string& key, const Pipeline& pipeline) = 0; + virtual void SetPipeline(const State* pState, const Pipeline& pipeline) = 0; virtual Pipeline CreatePipeline(const State* pState, const wchar_t* name = nullptr) = 0; virtual Pipeline GetPipeline(const State* pState, const wchar_t* name = nullptr) = 0; - // Get API native desc of this PSO handle - virtual void GetHandleDesc(void* pHandleDesc, const std::string& key) = 0; - using uptr = std::unique_ptr; using sptr = std::shared_ptr; diff --git a/XUSG/Core/XUSGComputeState_DX12.cpp b/XUSG/Core/XUSGComputeState_DX12.cpp index e539aaf..faf9670 100644 --- a/XUSG/Core/XUSGComputeState_DX12.cpp +++ b/XUSG/Core/XUSGComputeState_DX12.cpp @@ -57,14 +57,39 @@ Pipeline State_DX12::GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name) return pPipelineLib->GetPipeline(this, name); } -const string& State_DX12::GetKey() const +PipelineLayout State_DX12::GetPipelineLayout() const { - return m_key; + return m_pKey->Layout; +} + +Blob State_DX12::GetShader() const +{ + return m_pKey->Shader; +} + +Blob State_DX12::GetCachedPipeline() const +{ + return m_pKey->CachedPipeline; +} + +uint32_t State_DX12::GetNodeMask() const +{ + return m_pKey->NodeMask; } -void State_DX12::GetHandleDesc(void* pHandleDesc, PipelineLib* pPipelineLib) const +PipelineFlag State_DX12::GetFlags() const { - pPipelineLib->GetHandleDesc(pHandleDesc, GetKey()); + return m_pKey->Flags; +} + +void State_DX12::GetHandleDesc(void* pHandleDesc) const +{ + PipelineLib_DX12::GetHandleDesc(pHandleDesc, GetKey()); +} + +const string& State_DX12::GetKey() const +{ + return m_key; } //-------------------------------------------------------------------------------------- @@ -91,19 +116,28 @@ void PipelineLib_DX12::SetDevice(const Device* pDevice) assert(m_device); } -void PipelineLib_DX12::SetPipeline(const string& key, const Pipeline& pipeline) +void PipelineLib_DX12::SetPipeline(const State* pState, const Pipeline& pipeline) { - m_pipelines[key] = pipeline; + const auto p = dynamic_cast(pState); + assert(p); + + m_pipelines[p->GetKey()] = pipeline; } Pipeline PipelineLib_DX12::CreatePipeline(const State* pState, const wchar_t* name) { - return createPipeline(pState->GetKey(), name); + const auto p = dynamic_cast(pState); + assert(p); + + return createPipeline(p->GetKey(), name); } Pipeline PipelineLib_DX12::GetPipeline(const State* pState, const wchar_t* name) { - return getPipeline(pState->GetKey(), name); + const auto p = dynamic_cast(pState); + assert(p); + + return getPipeline(p->GetKey(), name); } Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name) diff --git a/XUSG/Core/XUSGComputeState_DX12.h b/XUSG/Core/XUSGComputeState_DX12.h index c62f18b..e3656b1 100644 --- a/XUSG/Core/XUSGComputeState_DX12.h +++ b/XUSG/Core/XUSGComputeState_DX12.h @@ -37,7 +37,13 @@ namespace XUSG const std::string& GetKey() const; - void GetHandleDesc(void* pHandleDesc, PipelineLib* pPipelineLib) const; + PipelineLayout GetPipelineLayout() const; + Blob GetShader() const; + Blob GetCachedPipeline() const; + uint32_t GetNodeMask() const; + PipelineFlag GetFlags() const; + + void GetHandleDesc(void* pHandleDesc) const; protected: PipelineDesc* m_pKey; @@ -53,12 +59,12 @@ namespace XUSG virtual ~PipelineLib_DX12(); void SetDevice(const Device* pDevice); - void SetPipeline(const std::string& key, const Pipeline& pipeline); + void SetPipeline(const State* pState, const Pipeline& pipeline); Pipeline CreatePipeline(const State* pState, const wchar_t* name = nullptr); Pipeline GetPipeline(const State* pState, const wchar_t* name = nullptr); - void GetHandleDesc(void* pHandleDesc, const std::string& key); + static void GetHandleDesc(void* pHandleDesc, const std::string& key); protected: virtual Pipeline createPipeline(const std::string& key, const wchar_t* name); diff --git a/XUSG/Core/XUSGGraphicsState_DX12.cpp b/XUSG/Core/XUSGGraphicsState_DX12.cpp index 1513478..6918194 100644 --- a/XUSG/Core/XUSGGraphicsState_DX12.cpp +++ b/XUSG/Core/XUSGGraphicsState_DX12.cpp @@ -140,14 +140,103 @@ Pipeline State_DX12::GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name) return pPipelineLib->GetPipeline(this, name); } -const string& State_DX12::GetKey() const +PipelineLayout State_DX12::GetPipelineLayout() const { - return m_key; + return m_pKey->Layout; +} + +Blob State_DX12::GetShader(Shader::Stage stage) const +{ + assert(stage < Shader::Stage::NUM_GRAPHICS); + + return m_pKey->Shaders[stage]; +} + +Blob State_DX12::GetCachedPipeline() const +{ + return m_pKey->CachedPipeline; +} + +uint32_t State_DX12::GetNodeMask() const +{ + return m_pKey->NodeMask; +} + +PipelineFlag State_DX12::GetFlags() const +{ + return m_pKey->Flags; +} + +uint32_t State_DX12::OMGetSampleMask() const +{ + return m_pKey->SampleMask; } -void State_DX12::GetHandleDesc(void* pHandleDesc, void* pInputElements, PipelineLib* pPipelineLib) const +const Graphics::Blend* State_DX12::OMGetBlendState() const { - pPipelineLib->GetHandleDesc(pHandleDesc, pInputElements, GetKey()); + return m_pKey->pBlend; +} + +const Graphics::Rasterizer* State_DX12::RSGetState() const +{ + return m_pKey->pRasterizer; +} + +const Graphics::DepthStencil* State_DX12::DSGetState() const +{ + return m_pKey->pDepthStencil; +} + +const InputLayout* State_DX12::IAGetInputLayout() const +{ + return m_pKey->pInputLayout; +} + +PrimitiveTopologyType State_DX12::IAGetPrimitiveTopologyType() const +{ + return m_pKey->PrimTopologyType; +} + +IBStripCutValue State_DX12::IAGetIndexBufferStripCutValue() const +{ + return static_cast(m_pKey->IBStripCutValue); +} + +uint8_t State_DX12::OMGetNumRenderTargets() const +{ + return m_pKey->NumRenderTargets; +} + +Format State_DX12::OMGetRTVFormat(uint8_t i) const +{ + assert(i < m_pKey->NumRenderTargets); + + return m_pKey->RTVFormats[i]; +} + +Format State_DX12::OMGetDSVFormat() const +{ + return m_pKey->DSVFormat; +} + +uint8_t State_DX12::OMGetSampleCount() const +{ + return m_pKey->SampleCount; +} + +uint8_t State_DX12::OMGetSampleQuality() const +{ + return m_pKey->SampleQuality; +} + +void State_DX12::GetHandleDesc(void* pHandleDesc, void* pInputElements) const +{ + PipelineLib_DX12::GetHandleDesc(pHandleDesc, pInputElements, GetKey()); +} + +const string& State_DX12::GetKey() const +{ + return m_key; } //-------------------------------------------------------------------------------------- @@ -206,9 +295,12 @@ void PipelineLib_DX12::SetDevice(const Device* pDevice) assert(m_device); } -void PipelineLib_DX12::SetPipeline(const string& key, const Pipeline& pipeline) +void PipelineLib_DX12::SetPipeline(const State* pState, const Pipeline& pipeline) { - m_pipelines[key] = pipeline; + const auto p = dynamic_cast(pState); + assert(p); + + m_pipelines[p->GetKey()] = pipeline; } void PipelineLib_DX12::SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements) @@ -228,15 +320,21 @@ const InputLayout* PipelineLib_DX12::CreateInputLayout(const InputElement* pElem Pipeline PipelineLib_DX12::CreatePipeline(const State* pState, const wchar_t* name) { - return createPipeline(pState->GetKey(), name); + const auto p = dynamic_cast(pState); + assert(p); + + return createPipeline(p->GetKey(), name); } Pipeline PipelineLib_DX12::GetPipeline(const State* pState, const wchar_t* name) { - return getPipeline(pState->GetKey(), name); + const auto p = dynamic_cast(pState); + assert(p); + + return getPipeline(p->GetKey(), name); } -const Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) +const Graphics::Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) { if (m_blends[preset] == nullptr) m_blends[preset] = make_unique(m_pfnBlends[preset](numColorRTs)); @@ -244,7 +342,7 @@ const Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) return m_blends[preset].get(); } -const Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset preset) +const Graphics::Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset preset) { if (m_rasterizers[preset] == nullptr) m_rasterizers[preset] = make_unique(m_pfnRasterizers[preset]()); @@ -308,7 +406,13 @@ void PipelineLib_DX12::GetHandleDesc(void* pHandleDesc, void* pInputElements, co desc.GS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::GS])); // Blend state - const auto pBlend = pDesc->pBlend ? pDesc->pBlend : GetBlend(BlendPreset::DEFAULT_OPAQUE); + unique_ptr blend; + auto pBlend = pDesc->pBlend; + if (pBlend == nullptr) + { + blend = make_unique(DefaultOpaque(pDesc->NumRenderTargets)); + pBlend = blend.get(); + } desc.BlendState.AlphaToCoverageEnable = pBlend->AlphaToCoverageEnable ? TRUE : FALSE; desc.BlendState.IndependentBlendEnable = pBlend->IndependentBlendEnable ? TRUE : FALSE; for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) @@ -329,7 +433,13 @@ void PipelineLib_DX12::GetHandleDesc(void* pHandleDesc, void* pInputElements, co desc.SampleMask = pDesc->SampleMask; // Rasterizer state - const auto pRasterizer = pDesc->pRasterizer ? pDesc->pRasterizer : GetRasterizer(RasterizerPreset::CULL_BACK); + unique_ptr rasterizer; + auto pRasterizer = pDesc->pRasterizer; + if (pRasterizer == nullptr) + { + rasterizer = make_unique(CullBack()); + pRasterizer = rasterizer.get(); + } desc.RasterizerState.FillMode = GetDX12FillMode(pRasterizer->Fill); desc.RasterizerState.CullMode = GetDX12CullMode(pRasterizer->Cull); desc.RasterizerState.FrontCounterClockwise = pRasterizer->FrontCounterClockwise ? TRUE : FALSE; @@ -348,7 +458,13 @@ void PipelineLib_DX12::GetHandleDesc(void* pHandleDesc, void* pInputElements, co D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; // Depth-stencil state - const auto pDepthStencil = pDesc->pDepthStencil ? pDesc->pDepthStencil : GetDepthStencil(DepthStencilPreset::DEFAULT_LESS); + unique_ptr depthStencil; + auto pDepthStencil = pDesc->pDepthStencil; + if (pDepthStencil == nullptr) + { + depthStencil = make_unique(DepthStencilDefault()); + pDepthStencil = depthStencil.get(); + } desc.DepthStencilState.DepthEnable = pDepthStencil->DepthEnable ? TRUE : FALSE; desc.DepthStencilState.DepthWriteMask = pDepthStencil->DepthWriteMask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; desc.DepthStencilState.DepthFunc = GetDX12ComparisonFunc(pDepthStencil->Comparison); diff --git a/XUSG/Core/XUSGGraphicsState_DX12.h b/XUSG/Core/XUSGGraphicsState_DX12.h index fbc1a75..7804e84 100644 --- a/XUSG/Core/XUSGGraphicsState_DX12.h +++ b/XUSG/Core/XUSGGraphicsState_DX12.h @@ -67,9 +67,30 @@ namespace XUSG Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const; Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const; - const std::string& GetKey() const; + PipelineLayout GetPipelineLayout() const; + Blob GetShader(Shader::Stage stage) const; + Blob GetCachedPipeline() const; + uint32_t GetNodeMask() const; + PipelineFlag GetFlags() const; + + uint32_t OMGetSampleMask() const; + const Blend* OMGetBlendState() const; + const Rasterizer* RSGetState() const; + const DepthStencil* DSGetState() const; + + const InputLayout* IAGetInputLayout() const; + PrimitiveTopologyType IAGetPrimitiveTopologyType() const; + IBStripCutValue IAGetIndexBufferStripCutValue() const; - void GetHandleDesc(void* pHandleDesc, void* pInputElements, PipelineLib* pPipelineLib) const; + uint8_t OMGetNumRenderTargets() const; + Format OMGetRTVFormat(uint8_t i) const; + Format OMGetDSVFormat() const; + uint8_t OMGetSampleCount() const; + uint8_t OMGetSampleQuality() const; + + void GetHandleDesc(void* pHandleDesc, void* pInputElements) const; + + const std::string& GetKey() const; protected: PipelineDesc* m_pKey; @@ -85,7 +106,7 @@ namespace XUSG virtual ~PipelineLib_DX12(); void SetDevice(const Device* pDevice); - void SetPipeline(const std::string& key, const Pipeline& pipeline); + void SetPipeline(const State* pState, const Pipeline& pipeline); void SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements); const InputLayout* GetInputLayout(uint32_t index) const; @@ -98,7 +119,7 @@ namespace XUSG const Rasterizer* GetRasterizer(RasterizerPreset preset); const DepthStencil* GetDepthStencil(DepthStencilPreset preset); - void GetHandleDesc(void* pHandleDesc, void* pInputElements, const std::string& key); + static void GetHandleDesc(void* pHandleDesc, void* pInputElements, const std::string& key); protected: Pipeline createPipeline(const std::string& key, const wchar_t* name); diff --git a/XUSG/Ultimate/XUSGProgramState_DX12.cpp b/XUSG/Ultimate/XUSGGenericState_DX12.cpp similarity index 85% rename from XUSG/Ultimate/XUSGProgramState_DX12.cpp rename to XUSG/Ultimate/XUSGGenericState_DX12.cpp index b4278b7..741aadb 100644 --- a/XUSG/Ultimate/XUSGProgramState_DX12.cpp +++ b/XUSG/Ultimate/XUSGGenericState_DX12.cpp @@ -6,12 +6,12 @@ #include "Core/XUSGCommand_DX12.h" #include "Core/XUSGResource_DX12.h" #include "Core/XUSGEnum_DX12.h" -#include "XUSGProgramState_DX12.h" +#include "XUSGGenericState_DX12.h" #include "XUSGUltimate_DX12.h" using namespace std; using namespace XUSG; -using namespace GenericProgram; +using namespace Generic; State_DX12::State_DX12() { @@ -173,6 +173,120 @@ Pipeline State_DX12::GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name) return pPipelineLib->GetPipeline(this, name); } +PipelineLayout State_DX12::GetPipelineLayout() const +{ + return m_pKey->Layout; +} + +Blob State_DX12::GetShaderLibrary(uint8_t index) const +{ + assert(index < Shader::Stage::NUM_STAGE); + + return m_pKey->ShaderLibs[index]; +} + +uint8_t State_DX12::GetShaderLibraryIndex(Shader::Stage stage) const +{ + return m_pKey->ShaderStages[stage].LibIndex; +} + +const wchar_t* State_DX12::GetShaderName(Shader::Stage stage) const +{ + return m_pKey->ShaderStages[stage].ShaderName; +} + +const wchar_t* State_DX12::GetProgramName() const +{ + return m_pKey->Program; +} + +uint32_t State_DX12::GetNodeMask() const +{ + return m_pKey->NodeMask; +} + +PipelineFlag State_DX12::GetFlags() const +{ + return m_pKey->Flags; +} + +uint32_t State_DX12::OMGetSampleMask() const +{ + return m_pKey->SampleMask; +} + +const Graphics::Blend* State_DX12::OMGetBlendState() const +{ + return m_pKey->pBlend; +} + +const Graphics::Rasterizer* State_DX12::RSGetState() const +{ + return m_pKey->pRasterizer; +} + +const Graphics::DepthStencil* State_DX12::DSGetState() const +{ + return m_pKey->pDepthStencil; +} + +const InputLayout* State_DX12::IAGetInputLayout() const +{ + return m_pKey->pInputLayout; +} + +PrimitiveTopologyType State_DX12::IAGetPrimitiveTopologyType() const +{ + return m_pKey->PrimTopologyType; +} + +IBStripCutValue State_DX12::IAGetIndexBufferStripCutValue() const +{ + return static_cast(m_pKey->IBStripCutValue); +} + +uint8_t State_DX12::OMGetNumRenderTargets() const +{ + return m_pKey->NumRenderTargets; +} + +Format State_DX12::OMGetRTVFormat(uint8_t i) const +{ + assert(i < m_pKey->NumRenderTargets); + + return m_pKey->RTVFormats[i]; +} + +Format State_DX12::OMGetDSVFormat() const +{ + return m_pKey->DSVFormat; +} + +uint8_t State_DX12::OMGetSampleCount() const +{ + return m_pKey->SampleCount; +} + +uint8_t State_DX12::OMGetSampleQuality() const +{ + return m_pKey->SampleQuality; +} + +uint8_t State_DX12::GetNumViewInstances(uint8_t n, ViewInstanceFlag flags) const +{ + return m_pKey->NumViewInstances; +} + +ViewInstanceFlag State_DX12::GetViewInstanceFlags() const +{ + return m_pKey->ViewInstanceFlags; +} + +const ViewInstance& State_DX12::GetViewInstance(uint8_t i) const +{ + return m_pKey->ViewInstances[i]; +} + const string& State_DX12::GetKey() const { return m_key; @@ -234,9 +348,12 @@ void PipelineLib_DX12::SetDevice(const Device* pDevice) assert(m_device); } -void PipelineLib_DX12::SetPipeline(const string& key, const Pipeline& pipeline) +void PipelineLib_DX12::SetPipeline(const State* pState, const Pipeline& pipeline) { - m_stateObjects[key] = pipeline; + const auto p = dynamic_cast(pState); + assert(p); + + m_stateObjects[p->GetKey()] = static_cast(pipeline); } void PipelineLib_DX12::SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements) @@ -256,15 +373,21 @@ const InputLayout* PipelineLib_DX12::CreateInputLayout(const InputElement* pElem Pipeline PipelineLib_DX12::CreatePipeline(const State* pState, const wchar_t* name) { - return createStateObject(pState->GetKey(), name).get(); + const auto p = dynamic_cast(pState); + assert(p); + + return createStateObject(p->GetKey(), name).get(); } Pipeline PipelineLib_DX12::GetPipeline(const State* pState, const wchar_t* name) { - return getStateObject(pState->GetKey(), name).get(); + const auto p = dynamic_cast(pState); + assert(p); + + return getStateObject(p->GetKey(), name).get(); } -const Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) +const Generic::Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) { if (m_blends[preset] == nullptr) m_blends[preset] = make_unique(m_pfnBlends[preset](numColorRTs)); @@ -272,7 +395,7 @@ const Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) return m_blends[preset].get(); } -const Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset preset) +const Generic::Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset preset) { if (m_rasterizers[preset] == nullptr) m_rasterizers[preset] = make_unique(m_pfnRasterizers[preset]()); @@ -280,7 +403,7 @@ const Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset preset) return m_rasterizers[preset].get(); } -const GenericProgram::DepthStencil* PipelineLib_DX12::GetDepthStencil(DepthStencilPreset preset) +const Generic::DepthStencil* PipelineLib_DX12::GetDepthStencil(DepthStencilPreset preset) { if (m_depthStencils[preset] == nullptr) m_depthStencils[preset] = make_unique(m_pfnDepthStencils[preset]()); @@ -326,9 +449,8 @@ com_ptr PipelineLib_DX12::createStateObject(const string& key const auto libDXIL = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->ShaderLibs[i])); pLib->SetDXILLibrary(&libDXIL); - const auto& shaderNames = libShaderNames[i]; - if (!shaderNames.empty()) // Export shaders - pLib->DefineExports(shaderNames.data(), static_cast(shaderNames.size())); + for (const auto& shaderName : libShaderNames[i]) // Export shaders + pLib->DefineExport(shaderName, L"*"); // Else, use default shader exports for a DXIL library/collection subobject ~ surface all shaders. } } diff --git a/XUSG/Ultimate/XUSGProgramState_DX12.h b/XUSG/Ultimate/XUSGGenericState_DX12.h similarity index 79% rename from XUSG/Ultimate/XUSGProgramState_DX12.h rename to XUSG/Ultimate/XUSGGenericState_DX12.h index 0cc7808..0ed63fe 100644 --- a/XUSG/Ultimate/XUSGProgramState_DX12.h +++ b/XUSG/Ultimate/XUSGGenericState_DX12.h @@ -9,7 +9,7 @@ namespace XUSG { - namespace GenericProgram + namespace Generic { struct ShaderStages { @@ -82,6 +82,33 @@ namespace XUSG Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const; Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const; + PipelineLayout GetPipelineLayout() const; + Blob GetShaderLibrary(uint8_t index) const; + uint8_t GetShaderLibraryIndex(Shader::Stage stage) const; + const wchar_t* GetShaderName(Shader::Stage stage) const; + const wchar_t* GetProgramName() const; + uint32_t GetNodeMask() const; + PipelineFlag GetFlags() const; + + uint32_t OMGetSampleMask() const; + const Graphics::Blend* OMGetBlendState() const; + const Graphics::Rasterizer* RSGetState() const; + const Graphics::DepthStencil* DSGetState() const; + + const InputLayout* IAGetInputLayout() const; + PrimitiveTopologyType IAGetPrimitiveTopologyType() const; + IBStripCutValue IAGetIndexBufferStripCutValue() const; + + uint8_t OMGetNumRenderTargets() const; + Format OMGetRTVFormat(uint8_t i) const; + Format OMGetDSVFormat() const; + uint8_t OMGetSampleCount() const; + uint8_t OMGetSampleQuality() const; + + uint8_t GetNumViewInstances(uint8_t n, ViewInstanceFlag flags) const; + ViewInstanceFlag GetViewInstanceFlags() const; + const ViewInstance& GetViewInstance(uint8_t i) const; + const std::string& GetKey() const; protected: @@ -98,7 +125,7 @@ namespace XUSG virtual ~PipelineLib_DX12(); void SetDevice(const Device* pDevice); - void SetPipeline(const std::string& key, const Pipeline& pipeline); + void SetPipeline(const State* pState, const Pipeline& pipeline); void SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements); const InputLayout* GetInputLayout(uint32_t index) const; diff --git a/XUSG/Ultimate/XUSGPipelineState_DX12.cpp b/XUSG/Ultimate/XUSGPipelineState_DX12.cpp index 5d813d9..5862fc1 100644 --- a/XUSG/Ultimate/XUSGPipelineState_DX12.cpp +++ b/XUSG/Ultimate/XUSGPipelineState_DX12.cpp @@ -69,18 +69,18 @@ void State_DX12::DSSetState(const Graphics::DepthStencil* pDepthStencil) m_pKey->pDepthStencil = pDepthStencil; } -void State_DX12::OMSetBlendState(BlendPreset preset, PipelineLib* pPipelineLib, +void State_DX12::OMSetBlendState(Graphics::BlendPreset preset, PipelineLib* pPipelineLib, uint8_t numColorRTs, uint32_t sampleMask) { OMSetBlendState(pPipelineLib->GetBlend(preset, numColorRTs), sampleMask); } -void State_DX12::RSSetState(RasterizerPreset preset, PipelineLib* pPipelineLib) +void State_DX12::RSSetState(Graphics::RasterizerPreset preset, PipelineLib* pPipelineLib) { RSSetState(pPipelineLib->GetRasterizer(preset)); } -void State_DX12::DSSetState(DepthStencilPreset preset, PipelineLib* pPipelineLib) +void State_DX12::DSSetState(Graphics::DepthStencilPreset preset, PipelineLib* pPipelineLib) { DSSetState(pPipelineLib->GetDepthStencil(preset)); } @@ -165,6 +165,110 @@ Pipeline State_DX12::GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name) return pPipelineLib->GetPipeline(this, name); } +PipelineLayout State_DX12::GetPipelineLayout() const +{ + return m_pKey->Layout; +} + +Blob State_DX12::GetShader(Shader::Stage stage) const +{ + assert(stage < Shader::Stage::NUM_STAGE); + + return m_pKey->Shaders[stage]; +} + +Blob State_DX12::GetCachedPipeline() const +{ + return m_pKey->CachedPipeline; +} + +uint32_t State_DX12::GetNodeMask() const +{ + return m_pKey->NodeMask; +} + +PipelineFlag State_DX12::GetFlags() const +{ + return m_pKey->Flags; +} + +uint32_t State_DX12::OMGetSampleMask() const +{ + return m_pKey->SampleMask; +} + +const Graphics::Blend* State_DX12::OMGetBlendState() const +{ + return m_pKey->pBlend; +} + +const Graphics::Rasterizer* State_DX12::RSGetState() const +{ + return m_pKey->pRasterizer; +} + +const Graphics::DepthStencil* State_DX12::DSGetState() const +{ + return m_pKey->pDepthStencil; +} + +const InputLayout* State_DX12::IAGetInputLayout() const +{ + return m_pKey->pInputLayout; +} + +PrimitiveTopologyType State_DX12::IAGetPrimitiveTopologyType() const +{ + return m_pKey->PrimTopologyType; +} + +IBStripCutValue State_DX12::IAGetIndexBufferStripCutValue() const +{ + return static_cast(m_pKey->IBStripCutValue); +} + +uint8_t State_DX12::OMGetNumRenderTargets() const +{ + return m_pKey->NumRenderTargets; +} + +Format State_DX12::OMGetRTVFormat(uint8_t i) const +{ + assert(i < m_pKey->NumRenderTargets); + + return m_pKey->RTVFormats[i]; +} + +Format State_DX12::OMGetDSVFormat() const +{ + return m_pKey->DSVFormat; +} + +uint8_t State_DX12::OMGetSampleCount() const +{ + return m_pKey->SampleCount; +} + +uint8_t State_DX12::OMGetSampleQuality() const +{ + return m_pKey->SampleQuality; +} + +uint8_t State_DX12::GetNumViewInstances(uint8_t n, ViewInstanceFlag flags) const +{ + return m_pKey->NumViewInstances; +} + +ViewInstanceFlag State_DX12::GetViewInstanceFlags() const +{ + return m_pKey->ViewInstanceFlags; +} + +const ViewInstance& State_DX12::GetViewInstance(uint8_t i) const +{ + return m_pKey->ViewInstances[i]; +} + const string& State_DX12::GetKey() const { return m_key; @@ -180,34 +284,34 @@ PipelineLib_DX12::PipelineLib_DX12() : m_depthStencils() { // Blend states - m_pfnBlends[BlendPreset::DEFAULT_OPAQUE] = Graphics::PipelineLib::DefaultOpaque; - m_pfnBlends[BlendPreset::PREMULTIPLITED] = Graphics::PipelineLib::Premultiplied; - m_pfnBlends[BlendPreset::ADDTIVE] = Graphics::PipelineLib::Additive; - m_pfnBlends[BlendPreset::NON_PRE_MUL] = Graphics::PipelineLib::NonPremultiplied; - m_pfnBlends[BlendPreset::NON_PREMUL_RT0] = Graphics::PipelineLib::NonPremultipliedRT0; - m_pfnBlends[BlendPreset::ALPHA_TO_COVERAGE] = Graphics::PipelineLib::AlphaToCoverage; - m_pfnBlends[BlendPreset::ACCUMULATIVE] = Graphics::PipelineLib::Accumulative; - m_pfnBlends[BlendPreset::AUTO_NON_PREMUL] = Graphics::PipelineLib::AutoNonPremultiplied; - m_pfnBlends[BlendPreset::ZERO_ALPHA_PREMUL] = Graphics::PipelineLib::ZeroAlphaNonPremultiplied; - m_pfnBlends[BlendPreset::MULTIPLITED] = Graphics::PipelineLib::Multiplied; - m_pfnBlends[BlendPreset::WEIGHTED_PREMUL] = Graphics::PipelineLib::WeightedPremul; - m_pfnBlends[BlendPreset::WEIGHTED_PREMUL_PER_RT] = Graphics::PipelineLib::WeightedPremulPerRT; - m_pfnBlends[BlendPreset::WEIGHTED_PER_RT] = Graphics::PipelineLib::WeightedPerRT; - m_pfnBlends[BlendPreset::SELECT_MIN] = Graphics::PipelineLib::SelectMin; - m_pfnBlends[BlendPreset::SELECT_MAX] = Graphics::PipelineLib::SelectMax; + m_pfnBlends[Graphics::BlendPreset::DEFAULT_OPAQUE] = Graphics::PipelineLib::DefaultOpaque; + m_pfnBlends[Graphics::BlendPreset::PREMULTIPLITED] = Graphics::PipelineLib::Premultiplied; + m_pfnBlends[Graphics::BlendPreset::ADDTIVE] = Graphics::PipelineLib::Additive; + m_pfnBlends[Graphics::BlendPreset::NON_PRE_MUL] = Graphics::PipelineLib::NonPremultiplied; + m_pfnBlends[Graphics::BlendPreset::NON_PREMUL_RT0] = Graphics::PipelineLib::NonPremultipliedRT0; + m_pfnBlends[Graphics::BlendPreset::ALPHA_TO_COVERAGE] = Graphics::PipelineLib::AlphaToCoverage; + m_pfnBlends[Graphics::BlendPreset::ACCUMULATIVE] = Graphics::PipelineLib::Accumulative; + m_pfnBlends[Graphics::BlendPreset::AUTO_NON_PREMUL] = Graphics::PipelineLib::AutoNonPremultiplied; + m_pfnBlends[Graphics::BlendPreset::ZERO_ALPHA_PREMUL] = Graphics::PipelineLib::ZeroAlphaNonPremultiplied; + m_pfnBlends[Graphics::BlendPreset::MULTIPLITED] = Graphics::PipelineLib::Multiplied; + m_pfnBlends[Graphics::BlendPreset::WEIGHTED_PREMUL] = Graphics::PipelineLib::WeightedPremul; + m_pfnBlends[Graphics::BlendPreset::WEIGHTED_PREMUL_PER_RT] = Graphics::PipelineLib::WeightedPremulPerRT; + m_pfnBlends[Graphics::BlendPreset::WEIGHTED_PER_RT] = Graphics::PipelineLib::WeightedPerRT; + m_pfnBlends[Graphics::BlendPreset::SELECT_MIN] = Graphics::PipelineLib::SelectMin; + m_pfnBlends[Graphics::BlendPreset::SELECT_MAX] = Graphics::PipelineLib::SelectMax; // Rasterizer states - m_pfnRasterizers[RasterizerPreset::CULL_BACK] = Graphics::PipelineLib::CullBack; - m_pfnRasterizers[RasterizerPreset::CULL_NONE] = Graphics::PipelineLib::CullNone; - m_pfnRasterizers[RasterizerPreset::CULL_FRONT] = Graphics::PipelineLib::CullFront; - m_pfnRasterizers[RasterizerPreset::FILL_WIREFRAME] = Graphics::PipelineLib::FillWireframe; + m_pfnRasterizers[Graphics::RasterizerPreset::CULL_BACK] = Graphics::PipelineLib::CullBack; + m_pfnRasterizers[Graphics::RasterizerPreset::CULL_NONE] = Graphics::PipelineLib::CullNone; + m_pfnRasterizers[Graphics::RasterizerPreset::CULL_FRONT] = Graphics::PipelineLib::CullFront; + m_pfnRasterizers[Graphics::RasterizerPreset::FILL_WIREFRAME] = Graphics::PipelineLib::FillWireframe; // Depth stencil states - m_pfnDepthStencils[DepthStencilPreset::DEFAULT_LESS] = Graphics::PipelineLib::DepthStencilDefault; - m_pfnDepthStencils[DepthStencilPreset::DEPTH_STENCIL_NONE] = Graphics::PipelineLib::DepthStencilNone; - m_pfnDepthStencils[DepthStencilPreset::DEPTH_READ_LESS] = Graphics::PipelineLib::DepthRead; - m_pfnDepthStencils[DepthStencilPreset::DEPTH_READ_LESS_EQUAL] = Graphics::PipelineLib::DepthReadLessEqual; - m_pfnDepthStencils[DepthStencilPreset::DEPTH_READ_EQUAL] = Graphics::PipelineLib::DepthReadEqual; + m_pfnDepthStencils[Graphics::DepthStencilPreset::DEFAULT_LESS] = Graphics::PipelineLib::DepthStencilDefault; + m_pfnDepthStencils[Graphics::DepthStencilPreset::DEPTH_STENCIL_NONE] = Graphics::PipelineLib::DepthStencilNone; + m_pfnDepthStencils[Graphics::DepthStencilPreset::DEPTH_READ_LESS] = Graphics::PipelineLib::DepthRead; + m_pfnDepthStencils[Graphics::DepthStencilPreset::DEPTH_READ_LESS_EQUAL] = Graphics::PipelineLib::DepthReadLessEqual; + m_pfnDepthStencils[Graphics::DepthStencilPreset::DEPTH_READ_EQUAL] = Graphics::PipelineLib::DepthReadEqual; } PipelineLib_DX12::PipelineLib_DX12(const Device* pDevice) : @@ -226,9 +330,12 @@ void PipelineLib_DX12::SetDevice(const Device* pDevice) assert(m_device); } -void PipelineLib_DX12::SetPipeline(const string& key, const Pipeline& pipeline) +void PipelineLib_DX12::SetPipeline(const State* pState, const Pipeline& pipeline) { - m_pipelines[key] = pipeline; + const auto p = dynamic_cast(pState); + assert(p); + + m_pipelines[p->GetKey()] = pipeline; } void PipelineLib_DX12::SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements) @@ -248,15 +355,21 @@ const InputLayout* PipelineLib_DX12::CreateInputLayout(const InputElement* pElem Pipeline PipelineLib_DX12::CreatePipeline(const State* pState, const wchar_t* name) { - return createPipeline(pState->GetKey(), name); + const auto p = dynamic_cast(pState); + assert(p); + + return createPipeline(p->GetKey(), name); } Pipeline PipelineLib_DX12::GetPipeline(const State* pState, const wchar_t* name) { - return getPipeline(pState->GetKey(), name); + const auto p = dynamic_cast(pState); + assert(p); + + return getPipeline(p->GetKey(), name); } -const Graphics::Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t numColorRTs) +const Graphics::Blend* PipelineLib_DX12::GetBlend(Graphics::BlendPreset preset, uint8_t numColorRTs) { if (m_blends[preset] == nullptr) m_blends[preset] = make_unique(m_pfnBlends[preset](numColorRTs)); @@ -264,7 +377,7 @@ const Graphics::Blend* PipelineLib_DX12::GetBlend(BlendPreset preset, uint8_t nu return m_blends[preset].get(); } -const Graphics::Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset preset) +const Graphics::Rasterizer* PipelineLib_DX12::GetRasterizer(Graphics::RasterizerPreset preset) { if (m_rasterizers[preset] == nullptr) m_rasterizers[preset] = make_unique(m_pfnRasterizers[preset]()); @@ -272,7 +385,7 @@ const Graphics::Rasterizer* PipelineLib_DX12::GetRasterizer(RasterizerPreset pre return m_rasterizers[preset].get(); } -const Graphics::DepthStencil* PipelineLib_DX12::GetDepthStencil(DepthStencilPreset preset) +const Graphics::DepthStencil* PipelineLib_DX12::GetDepthStencil(Graphics::DepthStencilPreset preset) { if (m_depthStencils[preset] == nullptr) m_depthStencils[preset] = make_unique(m_pfnDepthStencils[preset]()); @@ -282,9 +395,97 @@ const Graphics::DepthStencil* PipelineLib_DX12::GetDepthStencil(DepthStencilPres Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name) { - // Fill desc + D3D12_PIPELINE_STATE_STREAM_DESC desc; + vector inputElements; + + com_ptr pipeline = nullptr; + com_ptr dxDevice; + V_RETURN(m_device->QueryInterface(IID_PPV_ARGS(&dxDevice)), cerr, nullptr); + + D3D12_FEATURE_DATA_D3D12_OPTIONS19 featureData = {}; + if (FAILED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS19, &featureData, sizeof(featureData))) || + !featureData.RasterizerDesc2Supported) + { + D3D12_FEATURE_DATA_D3D12_OPTIONS16 featureData = {}; + if (FAILED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &featureData, sizeof(featureData))) || + !featureData.DynamicDepthBiasSupported) + { + D3D12_FEATURE_DATA_D3D12_OPTIONS14 featureData = {}; + if (FAILED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, &featureData, sizeof(featureData))) || + !featureData.IndependentFrontAndBackStencilRefMaskSupported) + { + // Fill desc + CD3DX12_PIPELINE_STATE_STREAM2 stream; + getStream(&stream, &inputElements, key); + + desc.pPipelineStateSubobjectStream = &stream; + desc.SizeInBytes = sizeof(stream); + + // Create pipeline + V_RETURN(dxDevice->CreatePipelineState(&desc, IID_PPV_ARGS(&pipeline)), cerr, nullptr); + } + else + { + // Fill desc + CD3DX12_PIPELINE_STATE_STREAM3 stream; + getStream(&stream, &inputElements, key); + + desc.pPipelineStateSubobjectStream = &stream; + desc.SizeInBytes = sizeof(stream); + + // Create pipeline + V_RETURN(dxDevice->CreatePipelineState(&desc, IID_PPV_ARGS(&pipeline)), cerr, nullptr); + } + } + else + { + // Fill desc + CD3DX12_PIPELINE_STATE_STREAM4 stream; + getStream(&stream, &inputElements, key); + + desc.pPipelineStateSubobjectStream = &stream; + desc.SizeInBytes = sizeof(stream); + + // Create pipeline + V_RETURN(dxDevice->CreatePipelineState(&desc, IID_PPV_ARGS(&pipeline)), cerr, nullptr); + } + } + else + { + // Fill desc + CD3DX12_PIPELINE_STATE_STREAM5 stream; + getStream(&stream, &inputElements, key); + + desc.pPipelineStateSubobjectStream = &stream; + desc.SizeInBytes = sizeof(stream); + + // Create pipeline + V_RETURN(dxDevice->CreatePipelineState(&desc, IID_PPV_ARGS(&pipeline)), cerr, nullptr); + } + + if (name) pipeline->SetName(name); + m_pipelines[key] = pipeline; + + return pipeline.get(); +} + +Pipeline PipelineLib_DX12::getPipeline(const string& key, const wchar_t* name) +{ + const auto pPipeline = m_pipelines.find(key); + + // Create one, if it does not exist + if (pPipeline == m_pipelines.end()) return createPipeline(key, name); + + return pPipeline->second.get(); +} + +void PipelineLib_DX12::getStream(CD3DX12_PIPELINE_STATE_STREAM2* pStream, void* pInputElements, const std::string& key) +{ const auto pDesc = reinterpret_cast(key.data()); - CD3DX12_PIPELINE_STATE_STREAM2 stream = {}; + auto& stream = *static_cast(pStream); + stream = {}; + + // Fill desc if (pDesc->Layout) stream.pRootSignature = static_cast(pDesc->Layout); @@ -306,7 +507,13 @@ Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name stream.AS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::AS])); // Blend state - const auto pBlend = pDesc->pBlend ? pDesc->pBlend : GetBlend(BlendPreset::DEFAULT_OPAQUE); + unique_ptr blend; + auto pBlend = pDesc->pBlend; + if (pBlend == nullptr) + { + blend = make_unique(Graphics::PipelineLib::DefaultOpaque(pDesc->NumRenderTargets)); + pBlend = blend.get(); + } CD3DX12_BLEND_DESC& blendState = stream.BlendState; blendState.AlphaToCoverageEnable = pBlend->AlphaToCoverageEnable ? TRUE : FALSE; blendState.IndependentBlendEnable = pBlend->IndependentBlendEnable ? TRUE : FALSE; @@ -328,7 +535,13 @@ Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name stream.SampleMask = pDesc->SampleMask; // Rasterizer state - const auto pRasterizer = pDesc->pRasterizer ? pDesc->pRasterizer : GetRasterizer(RasterizerPreset::CULL_BACK); + unique_ptr rasterizer; + auto pRasterizer = pDesc->pRasterizer; + if (pRasterizer == nullptr) + { + rasterizer = make_unique(Graphics::PipelineLib::CullBack()); + pRasterizer = rasterizer.get(); + } CD3DX12_RASTERIZER_DESC& rasterizerState = stream.RasterizerState; rasterizerState.FillMode = GetDX12FillMode(pRasterizer->Fill); rasterizerState.CullMode = GetDX12CullMode(pRasterizer->Cull); @@ -348,12 +561,20 @@ Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; // Depth-stencil state - const auto pDepthStencil = pDesc->pDepthStencil ? pDesc->pDepthStencil : GetDepthStencil(DepthStencilPreset::DEFAULT_LESS); + unique_ptr depthStencil; + auto pDepthStencil = pDesc->pDepthStencil; + if (pDepthStencil == nullptr) + { + depthStencil = make_unique(Graphics::PipelineLib::DepthStencilDefault()); + pDepthStencil = depthStencil.get(); + } CD3DX12_DEPTH_STENCIL_DESC1& depthStencilState = stream.DepthStencilState; depthStencilState.DepthEnable = pDepthStencil->DepthEnable ? TRUE : FALSE; depthStencilState.DepthWriteMask = pDepthStencil->DepthWriteMask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; depthStencilState.DepthFunc = GetDX12ComparisonFunc(pDepthStencil->Comparison); depthStencilState.StencilEnable = pDepthStencil->StencilEnable ? TRUE : FALSE; + depthStencilState.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; depthStencilState.FrontFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilFailOp); depthStencilState.FrontFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilDepthFailOp); depthStencilState.FrontFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilPassOp); @@ -365,7 +586,7 @@ Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name depthStencilState.DepthBoundsTestEnable = pDepthStencil->DepthBoundsTestEnable ? TRUE : FALSE; // Input layout - vector inputElements; + auto& inputElements = *static_cast*>(pInputElements); if (pDesc->pInputLayout) { D3D12_INPUT_LAYOUT_DESC& inputLayout = stream.InputLayout; @@ -435,28 +656,542 @@ Pipeline PipelineLib_DX12::createPipeline(const string& key, const wchar_t* name } viewInstancing.pViewInstanceLocations = viewInstances; viewInstancing.Flags = GetDX12ViewInstanceFlags(pDesc->ViewInstanceFlags); +} - D3D12_PIPELINE_STATE_STREAM_DESC desc; - desc.pPipelineStateSubobjectStream = &stream; - desc.SizeInBytes = sizeof(stream); +void PipelineLib_DX12::getStream(CD3DX12_PIPELINE_STATE_STREAM3* pStream, void* pInputElements, const std::string& key) +{ + const auto pDesc = reinterpret_cast(key.data()); + auto& stream = *static_cast(pStream); + stream = {}; - // Create pipeline - com_ptr pipeline = nullptr; - com_ptr dxDevice; - V_RETURN(m_device->QueryInterface(IID_PPV_ARGS(&dxDevice)), cerr, nullptr); - V_RETURN(dxDevice->CreatePipelineState(&desc, IID_PPV_ARGS(&pipeline)), cerr, nullptr); - if (name) pipeline->SetName(name); - m_pipelines[key] = pipeline; + // Fill desc + if (pDesc->Layout) + stream.pRootSignature = static_cast(pDesc->Layout); - return pipeline.get(); -} + if (pDesc->Shaders[Shader::Stage::VS]) + stream.VS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::VS])); + if (pDesc->Shaders[Shader::Stage::PS]) + stream.PS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::PS])); + if (pDesc->Shaders[Shader::Stage::DS]) + stream.DS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::DS])); + if (pDesc->Shaders[Shader::Stage::HS]) + stream.HS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::HS])); + if (pDesc->Shaders[Shader::Stage::GS]) + stream.GS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::GS])); + if (pDesc->Shaders[Shader::Stage::CS]) + stream.CS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::CS])); + if (pDesc->Shaders[Shader::Stage::MS]) + stream.MS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::MS])); + if (pDesc->Shaders[Shader::Stage::AS]) + stream.AS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::AS])); -Pipeline PipelineLib_DX12::getPipeline(const string& key, const wchar_t* name) -{ - const auto pPipeline = m_pipelines.find(key); + // Blend state + unique_ptr blend; + auto pBlend = pDesc->pBlend; + if (pBlend == nullptr) + { + blend = make_unique(Graphics::PipelineLib::DefaultOpaque(pDesc->NumRenderTargets)); + pBlend = blend.get(); + } + CD3DX12_BLEND_DESC& blendState = stream.BlendState; + blendState.AlphaToCoverageEnable = pBlend->AlphaToCoverageEnable ? TRUE : FALSE; + blendState.IndependentBlendEnable = pBlend->IndependentBlendEnable ? TRUE : FALSE; + for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + const auto& src = pBlend->RenderTargets[i]; + auto& dst = blendState.RenderTarget[i]; + dst.BlendEnable = src.BlendEnable ? TRUE : FALSE; + dst.LogicOpEnable = src.LogicOpEnable ? TRUE : FALSE; + dst.SrcBlend = GetDX12Blend(src.SrcBlend); + dst.DestBlend = GetDX12Blend(src.DestBlend); + dst.BlendOp = GetDX12BlendOp(src.BlendOp); + dst.SrcBlendAlpha = GetDX12Blend(src.SrcBlendAlpha); + dst.DestBlendAlpha = GetDX12Blend(src.DestBlendAlpha); + dst.BlendOpAlpha = GetDX12BlendOp(src.BlendOpAlpha); + dst.LogicOp = GetDX12LogicOp(src.LogicOp); + dst.RenderTargetWriteMask = GetDX12ColorWrite(src.WriteMask); + } + stream.SampleMask = pDesc->SampleMask; - // Create one, if it does not exist - if (pPipeline == m_pipelines.end()) return createPipeline(key, name); + // Rasterizer state + unique_ptr rasterizer; + auto pRasterizer = pDesc->pRasterizer; + if (pRasterizer == nullptr) + { + rasterizer = make_unique(Graphics::PipelineLib::CullBack()); + pRasterizer = rasterizer.get(); + } + CD3DX12_RASTERIZER_DESC& rasterizerState = stream.RasterizerState; + rasterizerState.FillMode = GetDX12FillMode(pRasterizer->Fill); + rasterizerState.CullMode = GetDX12CullMode(pRasterizer->Cull); + rasterizerState.FrontCounterClockwise = pRasterizer->FrontCounterClockwise ? TRUE : FALSE; + rasterizerState.DepthBias = static_cast(pRasterizer->DepthBias); + rasterizerState.DepthBiasClamp = pRasterizer->DepthBiasClamp; + rasterizerState.SlopeScaledDepthBias = pRasterizer->SlopeScaledDepthBias; + rasterizerState.DepthClipEnable = pRasterizer->DepthClipEnable ? TRUE : FALSE; + rasterizerState.MultisampleEnable = FALSE; + rasterizerState.AntialiasedLineEnable = FALSE; + if (pRasterizer->LineRasterizationMode == LineRasterization::ALPHA_ANTIALIASED) + rasterizerState.AntialiasedLineEnable = TRUE; + else if (pRasterizer->LineRasterizationMode != LineRasterization::ALIASED) + rasterizerState.MultisampleEnable = TRUE; + rasterizerState.ForcedSampleCount = pRasterizer->ForcedSampleCount; + rasterizerState.ConservativeRaster = pRasterizer->ConservativeRaster ? + D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; - return pPipeline->second.get(); + // Depth-stencil state + unique_ptr depthStencil; + auto pDepthStencil = pDesc->pDepthStencil; + if (pDepthStencil == nullptr) + { + depthStencil = make_unique(Graphics::PipelineLib::DepthStencilDefault()); + pDepthStencil = depthStencil.get(); + } + CD3DX12_DEPTH_STENCIL_DESC2& depthStencilState = stream.DepthStencilState; + depthStencilState.DepthEnable = pDepthStencil->DepthEnable ? TRUE : FALSE; + depthStencilState.DepthWriteMask = pDepthStencil->DepthWriteMask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + depthStencilState.DepthFunc = GetDX12ComparisonFunc(pDepthStencil->Comparison); + depthStencilState.StencilEnable = pDepthStencil->StencilEnable ? TRUE : FALSE; + depthStencilState.FrontFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilFailOp); + depthStencilState.FrontFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilDepthFailOp); + depthStencilState.FrontFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilPassOp); + depthStencilState.FrontFace.StencilFunc = GetDX12ComparisonFunc(pDepthStencil->FrontFace.StencilFunc); + depthStencilState.FrontFace.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.FrontFace.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; + depthStencilState.BackFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilFailOp); + depthStencilState.BackFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilDepthFailOp); + depthStencilState.BackFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilPassOp); + depthStencilState.BackFace.StencilFunc = GetDX12ComparisonFunc(pDepthStencil->BackFace.StencilFunc); + depthStencilState.BackFace.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.BackFace.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; + depthStencilState.DepthBoundsTestEnable = pDepthStencil->DepthBoundsTestEnable ? TRUE : FALSE; + + // Input layout + auto& inputElements = *static_cast*>(pInputElements); + if (pDesc->pInputLayout) + { + D3D12_INPUT_LAYOUT_DESC& inputLayout = stream.InputLayout; + inputLayout.NumElements = static_cast(pDesc->pInputLayout->size()); + inputElements.resize(inputLayout.NumElements); + + for (auto i = 0u; i < inputLayout.NumElements; ++i) + { + const auto& src = pDesc->pInputLayout->at(i); + auto& dst = inputElements[i]; + dst.SemanticName = src.SemanticName; + dst.SemanticIndex = src.SemanticIndex; + dst.Format = GetDXGIFormat(src.Format); + dst.InputSlot = src.InputSlot; + dst.AlignedByteOffset = src.AlignedByteOffset != XUSG_APPEND_ALIGNED_ELEMENT ? src.AlignedByteOffset : D3D12_APPEND_ALIGNED_ELEMENT; + dst.InputSlotClass = GetDX12InputClassification(src.InputSlotClass); + dst.InstanceDataStepRate = src.InstanceDataStepRate; + } + + inputLayout.pInputElementDescs = inputElements.data(); + } + + // Primitive Topology + stream.PrimitiveTopologyType = GetDX12PrimitiveTopologyType(pDesc->PrimTopologyType); + + // RTV formats and DSV format + D3D12_RT_FORMAT_ARRAY& rtvFormats = stream.RTVFormats; + rtvFormats.NumRenderTargets = pDesc->NumRenderTargets; + for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + rtvFormats.RTFormats[i] = GetDXGIFormat(pDesc->RTVFormats[i]); + stream.DSVFormat = GetDXGIFormat(pDesc->DSVFormat); + + // Sample desc + DXGI_SAMPLE_DESC& sampleDesc = stream.SampleDesc; + sampleDesc.Count = pDesc->SampleCount; + sampleDesc.Quality = pDesc->SampleQuality; + + // Cached PSO, node mask, and flags + const auto pCachedPipeline = static_cast(pDesc->CachedPipeline); + D3D12_CACHED_PIPELINE_STATE& cachedPSO = stream.CachedPSO; + cachedPSO.pCachedBlob = pCachedPipeline ? pCachedPipeline->GetBufferPointer() : nullptr; + cachedPSO.CachedBlobSizeInBytes = pCachedPipeline ? pCachedPipeline->GetBufferSize() : 0; + stream.NodeMask = pDesc->NodeMask; + stream.Flags = GetDX12PipelineFlags(pDesc->Flags); + + // IB strip cube value + switch (static_cast(pDesc->IBStripCutValue)) + { + case IBStripCutValue::FFFF: + stream.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF; + break; + case IBStripCutValue::FFFFFFFF: + stream.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; + break; + default: + assert(stream.IBStripCutValue == D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED); + } + + // View instancing + D3D12_VIEW_INSTANCING_DESC& viewInstancing = stream.ViewInstancingDesc; + D3D12_VIEW_INSTANCE_LOCATION viewInstances[D3D12_MAX_VIEW_INSTANCE_COUNT]; + viewInstancing.ViewInstanceCount = pDesc->NumViewInstances; + for (uint8_t i = 0; i < pDesc->NumViewInstances; ++i) + { + viewInstances[i].ViewportArrayIndex = pDesc->ViewInstances[i].ViewportArrayIndex; + viewInstances[i].RenderTargetArrayIndex = pDesc->ViewInstances[i].RenderTargetArrayIndex; + } + viewInstancing.pViewInstanceLocations = viewInstances; + viewInstancing.Flags = GetDX12ViewInstanceFlags(pDesc->ViewInstanceFlags); +} + +void PipelineLib_DX12::getStream(CD3DX12_PIPELINE_STATE_STREAM4* pStream, void* pInputElements, const std::string& key) +{ + const auto pDesc = reinterpret_cast(key.data()); + auto& stream = *static_cast(pStream); + stream = {}; + + // Fill desc + if (pDesc->Layout) + stream.pRootSignature = static_cast(pDesc->Layout); + + if (pDesc->Shaders[Shader::Stage::VS]) + stream.VS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::VS])); + if (pDesc->Shaders[Shader::Stage::PS]) + stream.PS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::PS])); + if (pDesc->Shaders[Shader::Stage::DS]) + stream.DS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::DS])); + if (pDesc->Shaders[Shader::Stage::HS]) + stream.HS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::HS])); + if (pDesc->Shaders[Shader::Stage::GS]) + stream.GS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::GS])); + if (pDesc->Shaders[Shader::Stage::CS]) + stream.CS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::CS])); + if (pDesc->Shaders[Shader::Stage::MS]) + stream.MS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::MS])); + if (pDesc->Shaders[Shader::Stage::AS]) + stream.AS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::AS])); + + // Blend state + unique_ptr blend; + auto pBlend = pDesc->pBlend; + if (pBlend == nullptr) + { + blend = make_unique(Graphics::PipelineLib::DefaultOpaque(pDesc->NumRenderTargets)); + pBlend = blend.get(); + } + CD3DX12_BLEND_DESC& blendState = stream.BlendState; + blendState.AlphaToCoverageEnable = pBlend->AlphaToCoverageEnable ? TRUE : FALSE; + blendState.IndependentBlendEnable = pBlend->IndependentBlendEnable ? TRUE : FALSE; + for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + const auto& src = pBlend->RenderTargets[i]; + auto& dst = blendState.RenderTarget[i]; + dst.BlendEnable = src.BlendEnable ? TRUE : FALSE; + dst.LogicOpEnable = src.LogicOpEnable ? TRUE : FALSE; + dst.SrcBlend = GetDX12Blend(src.SrcBlend); + dst.DestBlend = GetDX12Blend(src.DestBlend); + dst.BlendOp = GetDX12BlendOp(src.BlendOp); + dst.SrcBlendAlpha = GetDX12Blend(src.SrcBlendAlpha); + dst.DestBlendAlpha = GetDX12Blend(src.DestBlendAlpha); + dst.BlendOpAlpha = GetDX12BlendOp(src.BlendOpAlpha); + dst.LogicOp = GetDX12LogicOp(src.LogicOp); + dst.RenderTargetWriteMask = GetDX12ColorWrite(src.WriteMask); + } + stream.SampleMask = pDesc->SampleMask; + + // Rasterizer state + unique_ptr rasterizer; + auto pRasterizer = pDesc->pRasterizer; + if (pRasterizer == nullptr) + { + rasterizer = make_unique(Graphics::PipelineLib::CullBack()); + pRasterizer = rasterizer.get(); + } + CD3DX12_RASTERIZER_DESC1& rasterizerState = stream.RasterizerState; + rasterizerState.FillMode = GetDX12FillMode(pRasterizer->Fill); + rasterizerState.CullMode = GetDX12CullMode(pRasterizer->Cull); + rasterizerState.FrontCounterClockwise = pRasterizer->FrontCounterClockwise ? TRUE : FALSE; + rasterizerState.DepthBias = pRasterizer->DepthBias; + rasterizerState.DepthBiasClamp = pRasterizer->DepthBiasClamp; + rasterizerState.SlopeScaledDepthBias = pRasterizer->SlopeScaledDepthBias; + rasterizerState.DepthClipEnable = pRasterizer->DepthClipEnable ? TRUE : FALSE; + rasterizerState.MultisampleEnable = FALSE; + rasterizerState.AntialiasedLineEnable = FALSE; + if (pRasterizer->LineRasterizationMode == LineRasterization::ALPHA_ANTIALIASED) + rasterizerState.AntialiasedLineEnable = TRUE; + else if (pRasterizer->LineRasterizationMode != LineRasterization::ALIASED) + rasterizerState.MultisampleEnable = TRUE; + rasterizerState.ForcedSampleCount = pRasterizer->ForcedSampleCount; + rasterizerState.ConservativeRaster = pRasterizer->ConservativeRaster ? + D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + + // Depth-stencil state + unique_ptr depthStencil; + auto pDepthStencil = pDesc->pDepthStencil; + if (pDepthStencil == nullptr) + { + depthStencil = make_unique(Graphics::PipelineLib::DepthStencilDefault()); + pDepthStencil = depthStencil.get(); + } + CD3DX12_DEPTH_STENCIL_DESC2& depthStencilState = stream.DepthStencilState; + depthStencilState.DepthEnable = pDepthStencil->DepthEnable ? TRUE : FALSE; + depthStencilState.DepthWriteMask = pDepthStencil->DepthWriteMask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + depthStencilState.DepthFunc = GetDX12ComparisonFunc(pDepthStencil->Comparison); + depthStencilState.StencilEnable = pDepthStencil->StencilEnable ? TRUE : FALSE; + depthStencilState.FrontFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilFailOp); + depthStencilState.FrontFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilDepthFailOp); + depthStencilState.FrontFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilPassOp); + depthStencilState.FrontFace.StencilFunc = GetDX12ComparisonFunc(pDepthStencil->FrontFace.StencilFunc); + depthStencilState.FrontFace.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.FrontFace.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; + depthStencilState.BackFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilFailOp); + depthStencilState.BackFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilDepthFailOp); + depthStencilState.BackFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilPassOp); + depthStencilState.BackFace.StencilFunc = GetDX12ComparisonFunc(pDepthStencil->BackFace.StencilFunc); + depthStencilState.BackFace.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.BackFace.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; + depthStencilState.DepthBoundsTestEnable = pDepthStencil->DepthBoundsTestEnable ? TRUE : FALSE; + + // Input layout + auto& inputElements = *static_cast*>(pInputElements); + if (pDesc->pInputLayout) + { + D3D12_INPUT_LAYOUT_DESC& inputLayout = stream.InputLayout; + inputLayout.NumElements = static_cast(pDesc->pInputLayout->size()); + inputElements.resize(inputLayout.NumElements); + + for (auto i = 0u; i < inputLayout.NumElements; ++i) + { + const auto& src = pDesc->pInputLayout->at(i); + auto& dst = inputElements[i]; + dst.SemanticName = src.SemanticName; + dst.SemanticIndex = src.SemanticIndex; + dst.Format = GetDXGIFormat(src.Format); + dst.InputSlot = src.InputSlot; + dst.AlignedByteOffset = src.AlignedByteOffset != XUSG_APPEND_ALIGNED_ELEMENT ? src.AlignedByteOffset : D3D12_APPEND_ALIGNED_ELEMENT; + dst.InputSlotClass = GetDX12InputClassification(src.InputSlotClass); + dst.InstanceDataStepRate = src.InstanceDataStepRate; + } + + inputLayout.pInputElementDescs = inputElements.data(); + } + + // Primitive Topology + stream.PrimitiveTopologyType = GetDX12PrimitiveTopologyType(pDesc->PrimTopologyType); + + // RTV formats and DSV format + D3D12_RT_FORMAT_ARRAY& rtvFormats = stream.RTVFormats; + rtvFormats.NumRenderTargets = pDesc->NumRenderTargets; + for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + rtvFormats.RTFormats[i] = GetDXGIFormat(pDesc->RTVFormats[i]); + stream.DSVFormat = GetDXGIFormat(pDesc->DSVFormat); + + // Sample desc + DXGI_SAMPLE_DESC& sampleDesc = stream.SampleDesc; + sampleDesc.Count = pDesc->SampleCount; + sampleDesc.Quality = pDesc->SampleQuality; + + // Cached PSO, node mask, and flags + const auto pCachedPipeline = static_cast(pDesc->CachedPipeline); + D3D12_CACHED_PIPELINE_STATE& cachedPSO = stream.CachedPSO; + cachedPSO.pCachedBlob = pCachedPipeline ? pCachedPipeline->GetBufferPointer() : nullptr; + cachedPSO.CachedBlobSizeInBytes = pCachedPipeline ? pCachedPipeline->GetBufferSize() : 0; + stream.NodeMask = pDesc->NodeMask; + stream.Flags = GetDX12PipelineFlags(pDesc->Flags); + + // IB strip cube value + switch (static_cast(pDesc->IBStripCutValue)) + { + case IBStripCutValue::FFFF: + stream.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF; + break; + case IBStripCutValue::FFFFFFFF: + stream.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; + break; + default: + assert(stream.IBStripCutValue == D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED); + } + + // View instancing + D3D12_VIEW_INSTANCING_DESC& viewInstancing = stream.ViewInstancingDesc; + D3D12_VIEW_INSTANCE_LOCATION viewInstances[D3D12_MAX_VIEW_INSTANCE_COUNT]; + viewInstancing.ViewInstanceCount = pDesc->NumViewInstances; + for (uint8_t i = 0; i < pDesc->NumViewInstances; ++i) + { + viewInstances[i].ViewportArrayIndex = pDesc->ViewInstances[i].ViewportArrayIndex; + viewInstances[i].RenderTargetArrayIndex = pDesc->ViewInstances[i].RenderTargetArrayIndex; + } + viewInstancing.pViewInstanceLocations = viewInstances; + viewInstancing.Flags = GetDX12ViewInstanceFlags(pDesc->ViewInstanceFlags); +} + +void PipelineLib_DX12::getStream(CD3DX12_PIPELINE_STATE_STREAM5* pStream, void* pInputElements, const std::string& key) +{ + const auto pDesc = reinterpret_cast(key.data()); + auto& stream = *static_cast(pStream); + stream = {}; + + // Fill desc + if (pDesc->Layout) + stream.pRootSignature = static_cast(pDesc->Layout); + + if (pDesc->Shaders[Shader::Stage::VS]) + stream.VS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::VS])); + if (pDesc->Shaders[Shader::Stage::PS]) + stream.PS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::PS])); + if (pDesc->Shaders[Shader::Stage::DS]) + stream.DS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::DS])); + if (pDesc->Shaders[Shader::Stage::HS]) + stream.HS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::HS])); + if (pDesc->Shaders[Shader::Stage::GS]) + stream.GS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::GS])); + if (pDesc->Shaders[Shader::Stage::CS]) + stream.CS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::CS])); + if (pDesc->Shaders[Shader::Stage::MS]) + stream.MS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::MS])); + if (pDesc->Shaders[Shader::Stage::AS]) + stream.AS = CD3DX12_SHADER_BYTECODE(static_cast(pDesc->Shaders[Shader::Stage::AS])); + + // Blend state + unique_ptr blend; + auto pBlend = pDesc->pBlend; + if (pBlend == nullptr) + { + blend = make_unique(Graphics::PipelineLib::DefaultOpaque(pDesc->NumRenderTargets)); + pBlend = blend.get(); + } + CD3DX12_BLEND_DESC& blendState = stream.BlendState; + blendState.AlphaToCoverageEnable = pBlend->AlphaToCoverageEnable ? TRUE : FALSE; + blendState.IndependentBlendEnable = pBlend->IndependentBlendEnable ? TRUE : FALSE; + for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + { + const auto& src = pBlend->RenderTargets[i]; + auto& dst = blendState.RenderTarget[i]; + dst.BlendEnable = src.BlendEnable ? TRUE : FALSE; + dst.LogicOpEnable = src.LogicOpEnable ? TRUE : FALSE; + dst.SrcBlend = GetDX12Blend(src.SrcBlend); + dst.DestBlend = GetDX12Blend(src.DestBlend); + dst.BlendOp = GetDX12BlendOp(src.BlendOp); + dst.SrcBlendAlpha = GetDX12Blend(src.SrcBlendAlpha); + dst.DestBlendAlpha = GetDX12Blend(src.DestBlendAlpha); + dst.BlendOpAlpha = GetDX12BlendOp(src.BlendOpAlpha); + dst.LogicOp = GetDX12LogicOp(src.LogicOp); + dst.RenderTargetWriteMask = GetDX12ColorWrite(src.WriteMask); + } + stream.SampleMask = pDesc->SampleMask; + + // Rasterizer state + unique_ptr rasterizer; + auto pRasterizer = pDesc->pRasterizer; + if (pRasterizer == nullptr) + { + rasterizer = make_unique(Graphics::PipelineLib::CullBack()); + pRasterizer = rasterizer.get(); + } + CD3DX12_RASTERIZER_DESC2& rasterizerState = stream.RasterizerState; + rasterizerState.FillMode = GetDX12FillMode(pRasterizer->Fill); + rasterizerState.CullMode = GetDX12CullMode(pRasterizer->Cull); + rasterizerState.FrontCounterClockwise = pRasterizer->FrontCounterClockwise ? TRUE : FALSE; + rasterizerState.DepthBias = pRasterizer->DepthBias; + rasterizerState.DepthBiasClamp = pRasterizer->DepthBiasClamp; + rasterizerState.SlopeScaledDepthBias = pRasterizer->SlopeScaledDepthBias; + rasterizerState.DepthClipEnable = pRasterizer->DepthClipEnable ? TRUE : FALSE; + rasterizerState.LineRasterizationMode = GetDX12LineRasterizationMode(pRasterizer->LineRasterizationMode); + rasterizerState.ForcedSampleCount = pRasterizer->ForcedSampleCount; + rasterizerState.ConservativeRaster = pRasterizer->ConservativeRaster ? + D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + + // Depth-stencil state + unique_ptr depthStencil; + auto pDepthStencil = pDesc->pDepthStencil; + if (pDepthStencil == nullptr) + { + depthStencil = make_unique(Graphics::PipelineLib::DepthStencilDefault()); + pDepthStencil = depthStencil.get(); + } + CD3DX12_DEPTH_STENCIL_DESC2& depthStencilState = stream.DepthStencilState; + depthStencilState.DepthEnable = pDepthStencil->DepthEnable ? TRUE : FALSE; + depthStencilState.DepthWriteMask = pDepthStencil->DepthWriteMask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + depthStencilState.DepthFunc = GetDX12ComparisonFunc(pDepthStencil->Comparison); + depthStencilState.StencilEnable = pDepthStencil->StencilEnable ? TRUE : FALSE; + depthStencilState.FrontFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilFailOp); + depthStencilState.FrontFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilDepthFailOp); + depthStencilState.FrontFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->FrontFace.StencilPassOp); + depthStencilState.FrontFace.StencilFunc = GetDX12ComparisonFunc(pDepthStencil->FrontFace.StencilFunc); + depthStencilState.FrontFace.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.FrontFace.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; + depthStencilState.BackFace.StencilFailOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilFailOp); + depthStencilState.BackFace.StencilDepthFailOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilDepthFailOp); + depthStencilState.BackFace.StencilPassOp = GetDX12StencilOp(pDepthStencil->BackFace.StencilPassOp); + depthStencilState.BackFace.StencilFunc = GetDX12ComparisonFunc(pDepthStencil->BackFace.StencilFunc); + depthStencilState.BackFace.StencilReadMask = pDepthStencil->FrontFace.StencilReadMask; + depthStencilState.BackFace.StencilWriteMask = pDepthStencil->FrontFace.StencilWriteMask; + depthStencilState.DepthBoundsTestEnable = pDepthStencil->DepthBoundsTestEnable ? TRUE : FALSE; + + // Input layout + auto& inputElements = *static_cast*>(pInputElements); + if (pDesc->pInputLayout) + { + D3D12_INPUT_LAYOUT_DESC& inputLayout = stream.InputLayout; + inputLayout.NumElements = static_cast(pDesc->pInputLayout->size()); + inputElements.resize(inputLayout.NumElements); + + for (auto i = 0u; i < inputLayout.NumElements; ++i) + { + const auto& src = pDesc->pInputLayout->at(i); + auto& dst = inputElements[i]; + dst.SemanticName = src.SemanticName; + dst.SemanticIndex = src.SemanticIndex; + dst.Format = GetDXGIFormat(src.Format); + dst.InputSlot = src.InputSlot; + dst.AlignedByteOffset = src.AlignedByteOffset != XUSG_APPEND_ALIGNED_ELEMENT ? src.AlignedByteOffset : D3D12_APPEND_ALIGNED_ELEMENT; + dst.InputSlotClass = GetDX12InputClassification(src.InputSlotClass); + dst.InstanceDataStepRate = src.InstanceDataStepRate; + } + + inputLayout.pInputElementDescs = inputElements.data(); + } + + // Primitive Topology + stream.PrimitiveTopologyType = GetDX12PrimitiveTopologyType(pDesc->PrimTopologyType); + + // RTV formats and DSV format + D3D12_RT_FORMAT_ARRAY& rtvFormats = stream.RTVFormats; + rtvFormats.NumRenderTargets = pDesc->NumRenderTargets; + for (uint8_t i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + rtvFormats.RTFormats[i] = GetDXGIFormat(pDesc->RTVFormats[i]); + stream.DSVFormat = GetDXGIFormat(pDesc->DSVFormat); + + // Sample desc + DXGI_SAMPLE_DESC& sampleDesc = stream.SampleDesc; + sampleDesc.Count = pDesc->SampleCount; + sampleDesc.Quality = pDesc->SampleQuality; + + // Cached PSO, node mask, and flags + const auto pCachedPipeline = static_cast(pDesc->CachedPipeline); + D3D12_CACHED_PIPELINE_STATE& cachedPSO = stream.CachedPSO; + cachedPSO.pCachedBlob = pCachedPipeline ? pCachedPipeline->GetBufferPointer() : nullptr; + cachedPSO.CachedBlobSizeInBytes = pCachedPipeline ? pCachedPipeline->GetBufferSize() : 0; + stream.NodeMask = pDesc->NodeMask; + stream.Flags = GetDX12PipelineFlags(pDesc->Flags); + + // IB strip cube value + switch (static_cast(pDesc->IBStripCutValue)) + { + case IBStripCutValue::FFFF: + stream.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF; + break; + case IBStripCutValue::FFFFFFFF: + stream.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; + break; + default: + assert(stream.IBStripCutValue == D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED); + } + + // View instancing + D3D12_VIEW_INSTANCING_DESC& viewInstancing = stream.ViewInstancingDesc; + D3D12_VIEW_INSTANCE_LOCATION viewInstances[D3D12_MAX_VIEW_INSTANCE_COUNT]; + viewInstancing.ViewInstanceCount = pDesc->NumViewInstances; + for (uint8_t i = 0; i < pDesc->NumViewInstances; ++i) + { + viewInstances[i].ViewportArrayIndex = pDesc->ViewInstances[i].ViewportArrayIndex; + viewInstances[i].RenderTargetArrayIndex = pDesc->ViewInstances[i].RenderTargetArrayIndex; + } + viewInstancing.pViewInstanceLocations = viewInstances; + viewInstancing.Flags = GetDX12ViewInstanceFlags(pDesc->ViewInstanceFlags); } diff --git a/XUSG/Ultimate/XUSGPipelineState_DX12.h b/XUSG/Ultimate/XUSGPipelineState_DX12.h index b7f72a5..3f868f0 100644 --- a/XUSG/Ultimate/XUSGPipelineState_DX12.h +++ b/XUSG/Ultimate/XUSGPipelineState_DX12.h @@ -52,10 +52,10 @@ namespace XUSG void RSSetState(const Graphics::Rasterizer* pRasterizer); void DSSetState(const Graphics::DepthStencil* pDepthStencil); - void OMSetBlendState(BlendPreset preset, PipelineLib* pPipelineLib, + void OMSetBlendState(Graphics::BlendPreset preset, PipelineLib* pPipelineLib, uint8_t numColorRTs = 1, uint32_t sampleMask = UINT_MAX); - void RSSetState(RasterizerPreset preset, PipelineLib* pPipelineLib); - void DSSetState(DepthStencilPreset preset, PipelineLib* pPipelineLib); + void RSSetState(Graphics::RasterizerPreset preset, PipelineLib* pPipelineLib); + void DSSetState(Graphics::DepthStencilPreset preset, PipelineLib* pPipelineLib); void IASetInputLayout(const InputLayout* pLayout); void IASetPrimitiveTopologyType(PrimitiveTopologyType type); @@ -74,6 +74,31 @@ namespace XUSG Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const; Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const; + PipelineLayout GetPipelineLayout() const; + Blob GetShader(Shader::Stage stage) const; + Blob GetCachedPipeline() const; + uint32_t GetNodeMask() const; + PipelineFlag GetFlags() const; + + uint32_t OMGetSampleMask() const; + const Graphics::Blend* OMGetBlendState() const; + const Graphics::Rasterizer* RSGetState() const; + const Graphics::DepthStencil* DSGetState() const; + + const InputLayout* IAGetInputLayout() const; + PrimitiveTopologyType IAGetPrimitiveTopologyType() const; + IBStripCutValue IAGetIndexBufferStripCutValue() const; + + uint8_t OMGetNumRenderTargets() const; + Format OMGetRTVFormat(uint8_t i) const; + Format OMGetDSVFormat() const; + uint8_t OMGetSampleCount() const; + uint8_t OMGetSampleQuality() const; + + uint8_t GetNumViewInstances(uint8_t n, ViewInstanceFlag flags) const; + ViewInstanceFlag GetViewInstanceFlags() const; + const ViewInstance& GetViewInstance(uint8_t i) const; + const std::string& GetKey() const; protected: @@ -90,7 +115,7 @@ namespace XUSG virtual ~PipelineLib_DX12(); void SetDevice(const Device* pDevice); - void SetPipeline(const std::string& key, const Pipeline& pipeline); + void SetPipeline(const State* pState, const Pipeline& pipeline); void SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements); const InputLayout* GetInputLayout(uint32_t index) const; @@ -99,14 +124,19 @@ namespace XUSG Pipeline CreatePipeline(const State* pState, const wchar_t* name = nullptr); Pipeline GetPipeline(const State* pState, const wchar_t* name = nullptr); - const Graphics::Blend* GetBlend(BlendPreset preset, uint8_t numColorRTs = 1); - const Graphics::Rasterizer* GetRasterizer(RasterizerPreset preset); - const Graphics::DepthStencil* GetDepthStencil(DepthStencilPreset preset); + const Graphics::Blend* GetBlend(Graphics::BlendPreset preset, uint8_t numColorRTs = 1); + const Graphics::Rasterizer* GetRasterizer(Graphics::RasterizerPreset preset); + const Graphics::DepthStencil* GetDepthStencil(Graphics::DepthStencilPreset preset); protected: Pipeline createPipeline(const std::string& key, const wchar_t* name); Pipeline getPipeline(const std::string& key, const wchar_t* name); + static void getStream(CD3DX12_PIPELINE_STATE_STREAM2* pStream, void* pInputElements, const std::string& key); + static void getStream(CD3DX12_PIPELINE_STATE_STREAM3* pStream, void* pInputElements, const std::string& key); + static void getStream(CD3DX12_PIPELINE_STATE_STREAM4* pStream, void* pInputElements, const std::string& key); + static void getStream(CD3DX12_PIPELINE_STATE_STREAM5* pStream, void* pInputElements, const std::string& key); + com_ptr m_device; InputLayoutLib_DX12 m_inputLayoutLib; diff --git a/XUSG/Ultimate/XUSGUltimate.cpp b/XUSG/Ultimate/XUSGUltimate.cpp index 019f9c5..578c4ed 100644 --- a/XUSG/Ultimate/XUSGUltimate.cpp +++ b/XUSG/Ultimate/XUSGUltimate.cpp @@ -8,7 +8,7 @@ #include "XUSGUltimate_DX12.h" #include "XUSGPipelineState_DX12.h" #include "XUSGWorkGraph_DX12.h" -#include "XUSGProgramState_DX12.h" +#include "XUSGGenericState_DX12.h" using namespace std; using namespace XUSG; @@ -108,32 +108,32 @@ WorkGraph::PipelineLib::sptr WorkGraph::PipelineLib::MakeShared(const Device* pD return make_shared(pDevice); } -GenericProgram::State::uptr GenericProgram::State::MakeUnique(API api) +Generic::State::uptr Generic::State::MakeUnique(API api) { return make_unique(); } -GenericProgram::State::sptr GenericProgram::State::MakeShared(API api) +Generic::State::sptr Generic::State::MakeShared(API api) { return make_shared(); } -GenericProgram::PipelineLib::uptr GenericProgram::PipelineLib::MakeUnique(API api) +Generic::PipelineLib::uptr Generic::PipelineLib::MakeUnique(API api) { return make_unique(); } -GenericProgram::PipelineLib::sptr GenericProgram::PipelineLib::MakeShared(API api) +Generic::PipelineLib::sptr Generic::PipelineLib::MakeShared(API api) { return make_shared(); } -GenericProgram::PipelineLib::uptr GenericProgram::PipelineLib::MakeUnique(const Device* pDevice, API api) +Generic::PipelineLib::uptr Generic::PipelineLib::MakeUnique(const Device* pDevice, API api) { return make_unique(pDevice); } -GenericProgram::PipelineLib::sptr GenericProgram::PipelineLib::MakeShared(const Device* pDevice, API api) +Generic::PipelineLib::sptr Generic::PipelineLib::MakeShared(const Device* pDevice, API api) { return make_shared(pDevice); } diff --git a/XUSG/Ultimate/XUSGUltimate.h b/XUSG/Ultimate/XUSGUltimate.h index 0a513f1..8e3c7b8 100644 --- a/XUSG/Ultimate/XUSGUltimate.h +++ b/XUSG/Ultimate/XUSGUltimate.h @@ -130,12 +130,12 @@ namespace XUSG uint32_t ThreadGroupCountY, uint32_t ThreadGroupCountZ) const = 0; - virtual void SetProgram(ProgramType type, ProgramIdentifier identifier, WorkGraphFlag flags, + virtual void SetProgram(ProgramType type, ProgramIdentifier identifier, WorkGraphFlag flags = WorkGraphFlag::NONE, uint64_t backingMemoryAddress = 0, uint64_t backingMemoryByteSize = 0, uint64_t localRootArgTableAddress = 0, uint64_t localRootArgTableByteSize = 0, - uint64_t localRootArgTableByteStride = 0) const = 0; + uint64_t localRootArgTableByteStride = 0) = 0; virtual void DispatchGraph(uint32_t numNodeInputs, const NodeCPUInput* pNodeInputs, uint64_t nodeInputByteStride = 0) = 0; - virtual void DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiNodes = false) const = 0; + virtual void DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiNodes = false) = 0; using uptr = std::unique_ptr; using sptr = std::shared_ptr; @@ -149,10 +149,6 @@ namespace XUSG //-------------------------------------------------------------------------------------- // Pipeline state //-------------------------------------------------------------------------------------- - using BlendPreset = Graphics::BlendPreset; - using RasterizerPreset = Graphics::RasterizerPreset; - using DepthStencilPreset = Graphics::DepthStencilPreset; - class PipelineLib; class XUSG_INTERFACE State @@ -171,10 +167,10 @@ namespace XUSG virtual void RSSetState(const Graphics::Rasterizer* pRasterizer) = 0; virtual void DSSetState(const Graphics::DepthStencil* pDepthStencil) = 0; - virtual void OMSetBlendState(BlendPreset preset, PipelineLib* pPipelineLib, + virtual void OMSetBlendState(Graphics::BlendPreset preset, PipelineLib* pPipelineLib, uint8_t numColorRTs = 1, uint32_t sampleMask = UINT_MAX) = 0; - virtual void RSSetState(RasterizerPreset preset, PipelineLib* pPipelineLib) = 0; - virtual void DSSetState(DepthStencilPreset preset, PipelineLib* pPipelineLib) = 0; + virtual void RSSetState(Graphics::RasterizerPreset preset, PipelineLib* pPipelineLib) = 0; + virtual void DSSetState(Graphics::DepthStencilPreset preset, PipelineLib* pPipelineLib) = 0; virtual void IASetInputLayout(const InputLayout* pLayout) = 0; virtual void IASetPrimitiveTopologyType(PrimitiveTopologyType type) = 0; @@ -193,7 +189,30 @@ namespace XUSG virtual Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; virtual Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; - virtual const std::string& GetKey() const = 0; + virtual PipelineLayout GetPipelineLayout() const = 0; + virtual Blob GetShader(Shader::Stage stage) const = 0; + virtual Blob GetCachedPipeline() const = 0; + virtual uint32_t GetNodeMask() const = 0; + virtual PipelineFlag GetFlags() const = 0; + + virtual uint32_t OMGetSampleMask() const = 0; + virtual const Graphics::Blend* OMGetBlendState() const = 0; + virtual const Graphics::Rasterizer* RSGetState() const = 0; + virtual const Graphics::DepthStencil* DSGetState() const = 0; + + virtual const InputLayout* IAGetInputLayout() const = 0; + virtual PrimitiveTopologyType IAGetPrimitiveTopologyType() const = 0; + virtual IBStripCutValue IAGetIndexBufferStripCutValue() const = 0; + + virtual uint8_t OMGetNumRenderTargets() const = 0; + virtual Format OMGetRTVFormat(uint8_t i) const = 0; + virtual Format OMGetDSVFormat() const = 0; + virtual uint8_t OMGetSampleCount() const = 0; + virtual uint8_t OMGetSampleQuality() const = 0; + + virtual uint8_t GetNumViewInstances(uint8_t n, ViewInstanceFlag flags) const = 0; + virtual ViewInstanceFlag GetViewInstanceFlags() const = 0; + virtual const ViewInstance& GetViewInstance(uint8_t i) const = 0; using uptr = std::unique_ptr; using sptr = std::shared_ptr; @@ -210,7 +229,7 @@ namespace XUSG virtual ~PipelineLib() {}; virtual void SetDevice(const Device* pDevice) = 0; - virtual void SetPipeline(const std::string& key, const Pipeline& pipeline) = 0; + virtual void SetPipeline(const State* pState, const Pipeline& pipeline) = 0; virtual void SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements) = 0; virtual const InputLayout* GetInputLayout(uint32_t index) const = 0; @@ -219,9 +238,9 @@ namespace XUSG virtual Pipeline CreatePipeline(const State* pState, const wchar_t* name = nullptr) = 0; virtual Pipeline GetPipeline(const State* pState, const wchar_t* name = nullptr) = 0; - virtual const Graphics::Blend* GetBlend(BlendPreset preset, uint8_t numColorRTs = 1) = 0; - virtual const Graphics::Rasterizer* GetRasterizer(RasterizerPreset preset) = 0; - virtual const Graphics::DepthStencil* GetDepthStencil(DepthStencilPreset preset) = 0; + virtual const Graphics::Blend* GetBlend(Graphics::BlendPreset preset, uint8_t numColorRTs = 1) = 0; + virtual const Graphics::Rasterizer* GetRasterizer(Graphics::RasterizerPreset preset) = 0; + virtual const Graphics::DepthStencil* GetDepthStencil(Graphics::DepthStencilPreset preset) = 0; using uptr = std::unique_ptr; using sptr = std::shared_ptr; @@ -320,8 +339,6 @@ namespace XUSG virtual Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) = 0; virtual Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) = 0; - virtual const std::string& GetKey() = 0; - virtual const wchar_t* GetProgramName(uint32_t workGraphIndex) const = 0; virtual uint32_t GetNumWorkGraphs() const = 0; @@ -355,7 +372,7 @@ namespace XUSG virtual ~PipelineLib() {} virtual void SetDevice(const Device* pDevice) = 0; - virtual void SetPipeline(const std::string& key, const Pipeline& pipeline) = 0; + virtual void SetPipeline(State* pState, const Pipeline& pipeline) = 0; virtual Pipeline CreatePipeline(State* pState, const wchar_t* name = nullptr) = 0; virtual Pipeline GetPipeline(State* pState, const wchar_t* name = nullptr) = 0; @@ -373,11 +390,11 @@ namespace XUSG //-------------------------------------------------------------------------------------- // Generic program pipeline state //-------------------------------------------------------------------------------------- - namespace GenericProgram + namespace Generic { - using BlendPreset = Ultimate::BlendPreset; - using RasterizerPreset = Ultimate::RasterizerPreset; - using DepthStencilPreset = Ultimate::DepthStencilPreset; + using BlendPreset = Graphics::BlendPreset; + using RasterizerPreset = Graphics::RasterizerPreset; + using DepthStencilPreset = Graphics::DepthStencilPreset; using Blend = Graphics::Blend; using Rasterizer = Graphics::Rasterizer; @@ -427,7 +444,32 @@ namespace XUSG virtual Pipeline CreatePipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; virtual Pipeline GetPipeline(PipelineLib* pPipelineLib, const wchar_t* name = nullptr) const = 0; - virtual const std::string& GetKey() const = 0; + virtual PipelineLayout GetPipelineLayout() const = 0; + virtual Blob GetShaderLibrary(uint8_t index) const = 0; + virtual uint8_t GetShaderLibraryIndex(Shader::Stage stage) const = 0; + virtual const wchar_t* GetShaderName(Shader::Stage stage) const = 0; + virtual const wchar_t* GetProgramName() const = 0; + virtual uint32_t GetNodeMask() const = 0; + virtual PipelineFlag GetFlags() const = 0; + + virtual uint32_t OMGetSampleMask() const = 0; + virtual const Graphics::Blend* OMGetBlendState() const = 0; + virtual const Graphics::Rasterizer* RSGetState() const = 0; + virtual const Graphics::DepthStencil* DSGetState() const = 0; + + virtual const InputLayout* IAGetInputLayout() const = 0; + virtual PrimitiveTopologyType IAGetPrimitiveTopologyType() const = 0; + virtual IBStripCutValue IAGetIndexBufferStripCutValue() const = 0; + + virtual uint8_t OMGetNumRenderTargets() const = 0; + virtual Format OMGetRTVFormat(uint8_t i) const = 0; + virtual Format OMGetDSVFormat() const = 0; + virtual uint8_t OMGetSampleCount() const = 0; + virtual uint8_t OMGetSampleQuality() const = 0; + + virtual uint8_t GetNumViewInstances(uint8_t n, ViewInstanceFlag flags) const = 0; + virtual ViewInstanceFlag GetViewInstanceFlags() const = 0; + virtual const ViewInstance& GetViewInstance(uint8_t i) const = 0; using uptr = std::unique_ptr; using sptr = std::shared_ptr; @@ -444,7 +486,7 @@ namespace XUSG virtual ~PipelineLib() {}; virtual void SetDevice(const Device* pDevice) = 0; - virtual void SetPipeline(const std::string& key, const Pipeline& pipeline) = 0; + virtual void SetPipeline(const State* pState, const Pipeline& pipeline) = 0; virtual void SetInputLayout(uint32_t index, const InputElement* pElements, uint32_t numElements) = 0; virtual const InputLayout* GetInputLayout(uint32_t index) const = 0; diff --git a/XUSG/Ultimate/XUSGUltimate_DX12.cpp b/XUSG/Ultimate/XUSGUltimate_DX12.cpp index d142232..dff4a4c 100644 --- a/XUSG/Ultimate/XUSGUltimate_DX12.cpp +++ b/XUSG/Ultimate/XUSGUltimate_DX12.cpp @@ -117,7 +117,7 @@ void CommandList_DX12::DispatchMesh(uint32_t threadGroupCountX, uint32_t threadG void CommandList_DX12::SetProgram(ProgramType type, ProgramIdentifier identifier, WorkGraphFlag flags, uint64_t backingMemoryAddress, uint64_t backingMemoryByteSize, uint64_t localRootArgTableAddress, - uint64_t localRootArgTableByteSize, uint64_t localRootArgTableByteStride) const + uint64_t localRootArgTableByteSize, uint64_t localRootArgTableByteStride) { D3D12_SET_PROGRAM_DESC desc = {}; @@ -152,7 +152,8 @@ void CommandList_DX12::SetProgram(ProgramType type, ProgramIdentifier identifier desc.GenericPipeline.ProgramIdentifier.OpaqueData[3] = identifier.OpaqueData[3]; } - m_commandListU->SetProgram(&desc); + createAgilityInterface(); + m_commandListA->SetProgram(&desc); } void CommandList_DX12::DispatchGraph(uint32_t numNodeInputs, const NodeCPUInput* pNodeInputs, uint64_t nodeInputByteStride) @@ -182,10 +183,11 @@ void CommandList_DX12::DispatchGraph(uint32_t numNodeInputs, const NodeCPUInput* desc.MultiNodeCPUInput.pNodeInputs = m_nodeInputs.data(); } - m_commandListU->DispatchGraph(&desc); + createAgilityInterface(); + m_commandListA->DispatchGraph(&desc); } -void CommandList_DX12::DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiNodes) const +void CommandList_DX12::DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiNodes) { D3D12_DISPATCH_GRAPH_DESC desc = {}; if (isMultiNodes) @@ -199,14 +201,25 @@ void CommandList_DX12::DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiN desc.NodeGPUInput = nodeGPUInputAddress; } - m_commandListU->DispatchGraph(&desc); + createAgilityInterface(); + m_commandListA->DispatchGraph(&desc); } -XUSG::com_ptr& CommandList_DX12::GetGraphicsCommandList() +XUSG::com_ptr& CommandList_DX12::GetGraphicsCommandList() { return m_commandListU; } +void CommandList_DX12::createAgilityInterface() +{ + if (m_commandListA == nullptr) + { + const auto hr = m_commandList->QueryInterface(IID_PPV_ARGS(&m_commandListA)); + + if (FAILED(hr)) OutputDebugString(L"Couldn't get DirectX agility interface for the command list.\n"); + } +} + //-------------------------------------------------------------------------------------- // Sampler feedback //-------------------------------------------------------------------------------------- diff --git a/XUSG/Ultimate/XUSGUltimate_DX12.h b/XUSG/Ultimate/XUSGUltimate_DX12.h index 75822c7..7805b42 100644 --- a/XUSG/Ultimate/XUSGUltimate_DX12.h +++ b/XUSG/Ultimate/XUSGUltimate_DX12.h @@ -36,17 +36,20 @@ namespace XUSG uint32_t ThreadGroupCountY, uint32_t ThreadGroupCountZ) const; - void SetProgram(ProgramType type, ProgramIdentifier identifier, WorkGraphFlag flags, + void SetProgram(ProgramType type, ProgramIdentifier identifier, WorkGraphFlag flags = WorkGraphFlag::NONE, uint64_t backingMemoryAddress = 0, uint64_t backingMemoryByteSize = 0, uint64_t localRootArgTableAddress = 0, uint64_t localRootArgTableByteSize = 0, - uint64_t localRootArgTableByteStride = 0) const; + uint64_t localRootArgTableByteStride = 0); void DispatchGraph(uint32_t numNodeInputs, const NodeCPUInput* pNodeInputs, uint64_t nodeInputByteStride = 0); - void DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiNodes = false) const; + void DispatchGraph(uint64_t nodeGPUInputAddress, bool isMultiNodes = false); - com_ptr& GetGraphicsCommandList(); + com_ptr& GetGraphicsCommandList(); protected: - com_ptr m_commandListU; + void createAgilityInterface(); + + com_ptr m_commandListU; + com_ptr m_commandListA; std::vector m_nodeInputs; }; diff --git a/XUSG/Ultimate/XUSGWorkGraph_DX12.cpp b/XUSG/Ultimate/XUSGWorkGraph_DX12.cpp index 9a7b700..6d74a18 100644 --- a/XUSG/Ultimate/XUSGWorkGraph_DX12.cpp +++ b/XUSG/Ultimate/XUSGWorkGraph_DX12.cpp @@ -344,19 +344,28 @@ void PipelineLib_DX12::SetDevice(const Device* pDevice) assert(m_device); } -void PipelineLib_DX12::SetPipeline(const string& key, const Pipeline& pipeline) +void PipelineLib_DX12::SetPipeline(State* pState, const Pipeline& pipeline) { - m_stateObjects[key] = static_cast(pipeline); + const auto p = dynamic_cast(pState); + assert(p); + + m_stateObjects[p->GetKey()] = static_cast(pipeline); } Pipeline PipelineLib_DX12::CreatePipeline(State* pState, const wchar_t* name) { - return CreateStateObject(pState->GetKey(), name).get(); + const auto p = dynamic_cast(pState); + assert(p); + + return CreateStateObject(p->GetKey(), name).get(); } Pipeline PipelineLib_DX12::GetPipeline(State* pState, const wchar_t* name) { - return GetStateObject(pState->GetKey(), name).get(); + const auto p = dynamic_cast(pState); + assert(p); + + return GetStateObject(p->GetKey(), name).get(); } com_ptr PipelineLib_DX12::CreateStateObject(const string& key, const wchar_t* name) diff --git a/XUSG/Ultimate/XUSGWorkGraph_DX12.h b/XUSG/Ultimate/XUSGWorkGraph_DX12.h index a6c588f..63b6f35 100644 --- a/XUSG/Ultimate/XUSGWorkGraph_DX12.h +++ b/XUSG/Ultimate/XUSGWorkGraph_DX12.h @@ -125,7 +125,7 @@ namespace XUSG virtual ~PipelineLib_DX12(); void SetDevice(const Device* pDevice); - void SetPipeline(const std::string& key, const Pipeline& pipeline); + void SetPipeline(State* pState, const Pipeline& pipeline); Pipeline CreatePipeline(State* pState, const wchar_t* name = nullptr); Pipeline GetPipeline(State* pState, const wchar_t* name = nullptr); diff --git a/XUSG/XUSG.vcxproj b/XUSG/XUSG.vcxproj index 53d13a6..ac9055d 100644 --- a/XUSG/XUSG.vcxproj +++ b/XUSG/XUSG.vcxproj @@ -53,7 +53,7 @@ - + @@ -201,7 +201,7 @@ stdafx.h stdafx.h - + stdafx.h stdafx.h stdafx.h diff --git a/XUSG/XUSG.vcxproj.filters b/XUSG/XUSG.vcxproj.filters index cfce3a7..2607819 100644 --- a/XUSG/XUSG.vcxproj.filters +++ b/XUSG/XUSG.vcxproj.filters @@ -160,7 +160,7 @@ Ultimate\Header Files - + Ultimate\Header Files @@ -237,7 +237,7 @@ Ultimate\Source Files - + Ultimate\Source Files diff --git a/XUSGRayTracing/RayTracing/XUSGRayTracing.h b/XUSGRayTracing/RayTracing/XUSGRayTracing.h index 9dfe548..edf326b 100644 --- a/XUSGRayTracing/RayTracing/XUSGRayTracing.h +++ b/XUSGRayTracing/RayTracing/XUSGRayTracing.h @@ -366,8 +366,6 @@ namespace XUSG virtual Pipeline CreatePipeline(PipelineLib* pPipelineCache, const wchar_t* name = nullptr) = 0; virtual Pipeline GetPipeline(PipelineLib* pPipelineCache, const wchar_t* name = nullptr) = 0; - virtual const std::string& GetKey() = 0; - virtual const wchar_t* GetHitGroupName(uint32_t index) = 0; virtual uint32_t GetNumHitGroups() = 0; @@ -386,7 +384,7 @@ namespace XUSG virtual ~PipelineLib() {} virtual void SetDevice(const Device* pDevice) = 0; - virtual void SetPipeline(const std::string& key, const Pipeline& pipeline) = 0; + virtual void SetPipeline(State* pState, const Pipeline& pipeline) = 0; virtual Pipeline CreatePipeline(State* pState, const wchar_t* name = nullptr) = 0; virtual Pipeline GetPipeline(State* pState, const wchar_t* name = nullptr) = 0; diff --git a/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.cpp b/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.cpp index 3216d85..4cc4c4b 100644 --- a/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.cpp +++ b/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.cpp @@ -216,19 +216,28 @@ void PipelineLib_DX12::SetDevice(const RayTracing::Device* pDevice) assert(m_device); } -void PipelineLib_DX12::SetPipeline(const string& key, const Pipeline& pipeline) +void PipelineLib_DX12::SetPipeline(State* pState, const Pipeline& pipeline) { - m_stateObjects[key] = static_cast(pipeline); + const auto p = dynamic_cast(pState); + assert(p); + + m_stateObjects[p->GetKey()] = static_cast(pipeline); } Pipeline PipelineLib_DX12::CreatePipeline(State* pState, const wchar_t* name) { - return createStateObject(pState->GetKey(), name).get(); + const auto p = dynamic_cast(pState); + assert(p); + + return createStateObject(p->GetKey(), name).get(); } Pipeline PipelineLib_DX12::GetPipeline(State* pState, const wchar_t* name) { - return getStateObject(pState->GetKey(), name).get(); + const auto p = dynamic_cast(pState); + assert(p); + + return getStateObject(p->GetKey(), name).get(); } com_ptr PipelineLib_DX12::createStateObject(const string& key, const wchar_t* name) diff --git a/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.h b/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.h index 82775df..a2ac874 100644 --- a/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.h +++ b/XUSGRayTracing/RayTracing/XUSGRayTracingState_DX12.h @@ -104,7 +104,7 @@ namespace XUSG virtual ~PipelineLib_DX12(); void SetDevice(const Device* pDevice); - void SetPipeline(const std::string& key, const Pipeline& pipeline); + void SetPipeline(State* pState, const Pipeline& pipeline); Pipeline CreatePipeline(State* pState, const wchar_t* name = nullptr); Pipeline GetPipeline(State* pState, const wchar_t* name = nullptr);