From c66ba2feb38711fcdf3150de43eb57761f57bf29 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 24 Mar 2026 18:33:16 +0800 Subject: [PATCH] refactor(RHI): complete PipelineState Unity SRP style refactoring - Fix Chinese character encoding issues causing MSVC C4819 warnings - Add m_rootSignature member to D3D12PipelineState for PSO creation - All integration tests pass: OpenGL 4/4, D3D12 4/4 - All RHI unit tests pass: 158/158 --- editor/CMakeLists.txt | 1 + .../include/XCEngine/RHI/D3D12/D3D12Device.h | 2 +- .../XCEngine/RHI/D3D12/D3D12PipelineState.h | 66 ++++- .../XCEngine/RHI/OpenGL/OpenGLCommandList.h | 2 +- .../XCEngine/RHI/OpenGL/OpenGLDevice.h | 2 +- .../XCEngine/RHI/OpenGL/OpenGLPipelineState.h | 111 ++++---- engine/include/XCEngine/RHI/RHIDevice.h | 2 +- engine/include/XCEngine/RHI/RHIEnums.h | 13 + .../include/XCEngine/RHI/RHIPipelineState.h | 23 +- engine/include/XCEngine/RHI/RHITypes.h | 78 ++++- engine/src/RHI/D3D12/D3D12Device.cpp | 12 +- engine/src/RHI/D3D12/D3D12PipelineState.cpp | 229 +++++++++++---- engine/src/RHI/OpenGL/OpenGLDevice.cpp | 9 +- engine/src/RHI/OpenGL/OpenGLPipelineState.cpp | 266 +++++++----------- 14 files changed, 516 insertions(+), 300 deletions(-) diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 7d8a90aa..b7fff6eb 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -60,6 +60,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib + XCEngine ) set_target_properties(${PROJECT_NAME} PROPERTIES diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h index 6f2c9986..d681e4da 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h @@ -68,7 +68,7 @@ public: RHICommandList* CreateCommandList(const CommandListDesc& desc) override; RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override; RHIShader* CompileShader(const ShaderCompileDesc& desc) override; - RHIPipelineState* CreatePipelineState(const PipelineStateDesc& desc) override; + RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) override; RHIFence* CreateFence(const FenceDesc& desc) override; RHISampler* CreateSampler(const SamplerDesc& desc) override; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h b/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h index 49248b3b..ae3b7f38 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h @@ -3,8 +3,10 @@ #include #include #include +#include #include "../RHIPipelineState.h" +#include "../RHITypes.h" #include "../RHIEnums.h" #include "D3D12Enums.h" @@ -15,28 +17,45 @@ namespace RHI { class D3D12PipelineState : public RHIPipelineState { public: - D3D12PipelineState(); + D3D12PipelineState() = default; + D3D12PipelineState(ID3D12Device* device); ~D3D12PipelineState() override; bool Initialize(ID3D12Device* device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& desc); + + // State configuration (Unity SRP style) + void SetInputLayout(const InputLayoutDesc& layout) override; + void SetRasterizerState(const RasterizerDesc& state) override; + void SetBlendState(const BlendDesc& state) override; + void SetDepthStencilState(const DepthStencilStateDesc& state) override; + void SetTopology(uint32_t topologyType) override; + void SetRenderTargetFormats(uint32_t count, const uint32_t* formats, uint32_t depthFormat) override; + void SetSampleCount(uint32_t count) override; + + // State query + const RasterizerDesc& GetRasterizerState() const override { return m_rasterizerDesc; } + const BlendDesc& GetBlendState() const override { return m_blendDesc; } + const DepthStencilStateDesc& GetDepthStencilState() const override { return m_depthStencilDesc; } + const InputLayoutDesc& GetInputLayout() const override { return m_inputLayoutDesc; } + PipelineStateHash GetHash() const override; + + // Finalization + bool IsFinalized() const override { return m_finalized; } + bool Finalize() override; + + // Shader Bytecode (set by CommandList when binding) + void SetShaderBytecodes(const D3D12_SHADER_BYTECODE& vs, const D3D12_SHADER_BYTECODE& ps, const D3D12_SHADER_BYTECODE& gs = {}); + + // Lifecycle void Shutdown() override; - ID3D12PipelineState* GetPipelineState() const { return m_pipelineState.Get(); } - void* GetNativeHandle() override { return m_pipelineState.Get(); } PipelineType GetType() const override { return PipelineType::Graphics; } void Bind() override; void Unbind() override; - static D3D12_GRAPHICS_PIPELINE_STATE_DESC CreateDesc( - ID3D12RootSignature* rootSignature, - const D3D12_SHADER_BYTECODE& vs, - const D3D12_SHADER_BYTECODE& ps, - const D3D12_SHADER_BYTECODE& gs, - uint32_t inputElementCount, - const D3D12_INPUT_ELEMENT_DESC* inputElements); - + // Helper functions static D3D12_INPUT_ELEMENT_DESC CreateInputElement( const char* semanticName, uint32_t semanticIndex, @@ -51,7 +70,32 @@ public: uint32_t inputSlot); private: + bool CreateD3D12PSO(); + + ID3D12Device* m_device; + bool m_finalized = false; + + // Stored configuration (Unity SRP style) + GraphicsPipelineDesc m_desc; + InputLayoutDesc m_inputLayoutDesc; + RasterizerDesc m_rasterizerDesc; + BlendDesc m_blendDesc; + DepthStencilStateDesc m_depthStencilDesc; + uint32_t m_topologyType = 0; + uint32_t m_renderTargetCount = 1; + uint32_t m_renderTargetFormats[8] = { 0 }; + uint32_t m_depthStencilFormat = 0; + uint32_t m_sampleCount = 1; + + // Shader bytecodes (set externally) + D3D12_SHADER_BYTECODE m_vsBytecode = {}; + D3D12_SHADER_BYTECODE m_psBytecode = {}; + D3D12_SHADER_BYTECODE m_gsBytecode = {}; + ID3D12RootSignature* m_rootSignature = nullptr; + + // D3D12 resources ComPtr m_pipelineState; + std::vector m_inputElements; }; } // namespace RHI diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h index 1a52a009..e44c84f5 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h @@ -56,7 +56,7 @@ public: void SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIResourceView** buffers, const uint64_t* offsets, const uint32_t* strides) override; void SetIndexBuffer(RHIResourceView* buffer, uint64_t offset) override; - // OpenGL 特有版本(底层逃逸) + // OpenGL specific version (low-level escape hatch) void SetVertexBuffer(unsigned int buffer, size_t offset, size_t stride); void SetVertexBuffers(unsigned int startSlot, unsigned int count, const unsigned int* buffers, const size_t* offsets, const size_t* strides); void SetIndexBuffer(unsigned int buffer, unsigned int type); diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h index 2bb13c4b..644c0bd4 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h @@ -49,7 +49,7 @@ public: RHICommandList* CreateCommandList(const CommandListDesc& desc) override; RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override; RHIShader* CompileShader(const ShaderCompileDesc& desc) override; - RHIPipelineState* CreatePipelineState(const PipelineStateDesc& desc) override; + RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) override; RHIFence* CreateFence(const FenceDesc& desc) override; RHISampler* CreateSampler(const SamplerDesc& desc) override; diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h index e3affb6a..4d04dd4c 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h @@ -4,44 +4,12 @@ #include #include "../RHIPipelineState.h" +#include "../RHITypes.h" #include "../RHIEnums.h" namespace XCEngine { namespace RHI { -enum class OpenGLPrimitiveTopology { - Points, - Lines, - LineStrip, - Triangles, - TriangleStrip -}; - -enum class OpenGLBlendOp { - Add, - Subtract, - ReverseSubtract, - Min, - Max -}; - -enum class CullFace { - Front, - Back, - FrontAndBack -}; - -enum class FrontFace { - Clockwise, - CounterClockwise -}; - -enum class PolygonMode { - Point, - Line, - Fill -}; - struct OpenGLDepthStencilState { bool depthTestEnable = true; bool depthWriteEnable = true; @@ -70,9 +38,9 @@ struct OpenGLBlendState { struct OpenGLRasterizerState { bool cullFaceEnable = true; - CullFace cullFace = CullFace::Back; + CullMode cullFace = CullMode::Back; FrontFace frontFace = FrontFace::CounterClockwise; - PolygonMode polygonMode = PolygonMode::Fill; + FillMode polygonMode = FillMode::Solid; float polygonOffsetFactor = 0.0f; float polygonOffsetUnits = 0.0f; bool depthClipEnable = true; @@ -98,58 +66,79 @@ struct ScissorState { int height = 0; }; -struct LogicalOperation { - bool enable = false; - uint32_t operation = 0; -}; - class OpenGLPipelineState : public RHIPipelineState { public: OpenGLPipelineState(); ~OpenGLPipelineState() override; + // State configuration (Unity SRP style) + void SetInputLayout(const InputLayoutDesc& layout) override; + void SetRasterizerState(const RasterizerDesc& state) override; + void SetBlendState(const BlendDesc& state) override; + void SetDepthStencilState(const DepthStencilStateDesc& state) override; + void SetTopology(uint32_t topologyType) override; + void SetRenderTargetFormats(uint32_t count, const uint32_t* formats, uint32_t depthFormat) override; + void SetSampleCount(uint32_t count) override; + + // State query + const RasterizerDesc& GetRasterizerState() const override { return m_rasterizerDesc; } + const BlendDesc& GetBlendState() const override { return m_blendDesc; } + const DepthStencilStateDesc& GetDepthStencilState() const override { return m_depthStencilDesc; } + const InputLayoutDesc& GetInputLayout() const override { return m_inputLayoutDesc; } + PipelineStateHash GetHash() const override; + + // Finalization (OpenGL doesn't need it) + bool IsFinalized() const override { return true; } + bool Finalize() override { return true; } + + // Lifecycle void Shutdown() override; + void* GetNativeHandle() override { return reinterpret_cast(static_cast(m_program)); } + PipelineType GetType() const override { return PipelineType::Graphics; } void Bind() override; void Unbind() override; - void* GetNativeHandle() override; - PipelineType GetType() const override { return PipelineType::Graphics; } - - void SetDepthStencilState(const OpenGLDepthStencilState& state); - void SetBlendState(const OpenGLBlendState& state); - void SetRasterizerState(const OpenGLRasterizerState& state); - void SetViewport(const ViewportState& state); - void SetScissor(const ScissorState& state); - void SetLogicalOperation(const LogicalOperation& state); - + // OpenGL specific void Apply(); void ApplyDepthStencil(); void ApplyBlend(); void ApplyRasterizer(); void ApplyViewport(); void ApplyScissor(); + void SetProgram(unsigned int program); + unsigned int GetProgram() const { return m_program; } + void SetDepthStencilState(const OpenGLDepthStencilState& state); + void SetBlendState(const OpenGLBlendState& state); + void SetRasterizerState(const OpenGLRasterizerState& state); + void SetViewport(const ViewportState& state); + void SetScissor(const ScissorState& state); void SetClearColor(float r, float g, float b, float a); void Clear(unsigned int buffers); - void AttachShader(unsigned int program); void DetachShader(); - const OpenGLDepthStencilState& GetDepthStencilState() const { return m_depthStencilState; } - const OpenGLBlendState& GetBlendState() const { return m_blendState; } - const OpenGLRasterizerState& GetRasterizerState() const { return m_rasterizerState; } + const OpenGLDepthStencilState& GetOpenGLDepthStencilState() const; + const OpenGLBlendState& GetOpenGLBlendState() const; + const OpenGLRasterizerState& GetOpenGLRasterizerState() const; private: - OpenGLDepthStencilState m_depthStencilState; - OpenGLBlendState m_blendState; - OpenGLRasterizerState m_rasterizerState; + InputLayoutDesc m_inputLayoutDesc; + RasterizerDesc m_rasterizerDesc; + BlendDesc m_blendDesc; + DepthStencilStateDesc m_depthStencilDesc; + uint32_t m_topologyType = 0; + unsigned int m_program = 0; + bool m_programAttached = false; + + // OpenGL specific state + OpenGLDepthStencilState m_glDepthStencilState; + OpenGLBlendState m_glBlendState; + OpenGLRasterizerState m_glRasterizerState; ViewportState m_viewportState; ScissorState m_scissorState; - LogicalOperation m_logicalOperation; - float m_clearColor[4]; - unsigned int m_program; - bool m_programAttached; + float m_clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; }; } // namespace RHI diff --git a/engine/include/XCEngine/RHI/RHIDevice.h b/engine/include/XCEngine/RHI/RHIDevice.h index a9be6cb7..9bc0db1a 100644 --- a/engine/include/XCEngine/RHI/RHIDevice.h +++ b/engine/include/XCEngine/RHI/RHIDevice.h @@ -31,7 +31,7 @@ public: virtual RHICommandList* CreateCommandList(const CommandListDesc& desc) = 0; virtual RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) = 0; virtual RHIShader* CompileShader(const ShaderCompileDesc& desc) = 0; - virtual RHIPipelineState* CreatePipelineState(const PipelineStateDesc& desc) = 0; + virtual RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) = 0; virtual RHIFence* CreateFence(const FenceDesc& desc) = 0; virtual RHISampler* CreateSampler(const SamplerDesc& desc) = 0; diff --git a/engine/include/XCEngine/RHI/RHIEnums.h b/engine/include/XCEngine/RHI/RHIEnums.h index 26727a9e..f8e70bfc 100644 --- a/engine/include/XCEngine/RHI/RHIEnums.h +++ b/engine/include/XCEngine/RHI/RHIEnums.h @@ -30,6 +30,11 @@ enum class FillMode : uint8_t { Solid }; +enum class FrontFace : uint8_t { + Clockwise, + CounterClockwise +}; + enum class BlendOp : uint8_t { Add, Subtract, @@ -155,6 +160,14 @@ enum class PrimitiveTopology : uint8_t { PatchList }; +enum class PrimitiveTopologyType : uint8_t { + Undefined, + Point, + Line, + Triangle, + Patch +}; + enum class FilterMode : uint8_t { Point, Linear, diff --git a/engine/include/XCEngine/RHI/RHIPipelineState.h b/engine/include/XCEngine/RHI/RHIPipelineState.h index 3915fddf..b1051689 100644 --- a/engine/include/XCEngine/RHI/RHIPipelineState.h +++ b/engine/include/XCEngine/RHI/RHIPipelineState.h @@ -10,11 +10,30 @@ class RHIPipelineState { public: virtual ~RHIPipelineState() = default; - virtual void Shutdown() = 0; + // State configuration (Unity SRP style - Shader independent of PSO) + virtual void SetInputLayout(const InputLayoutDesc& layout) = 0; + virtual void SetRasterizerState(const RasterizerDesc& state) = 0; + virtual void SetBlendState(const BlendDesc& state) = 0; + virtual void SetDepthStencilState(const DepthStencilStateDesc& state) = 0; + virtual void SetTopology(uint32_t topologyType) = 0; // PrimitiveTopologyType + virtual void SetRenderTargetFormats(uint32_t count, const uint32_t* formats, uint32_t depthFormat) = 0; + virtual void SetSampleCount(uint32_t count) = 0; + // State query + virtual const RasterizerDesc& GetRasterizerState() const = 0; + virtual const BlendDesc& GetBlendState() const = 0; + virtual const DepthStencilStateDesc& GetDepthStencilState() const = 0; + virtual const InputLayoutDesc& GetInputLayout() const = 0; + virtual PipelineStateHash GetHash() const = 0; + + // Finalization (D3D12/Vulkan creates real PSO) + virtual bool IsFinalized() const = 0; + virtual bool Finalize() = 0; + + // Lifecycle + virtual void Shutdown() = 0; virtual void Bind() = 0; virtual void Unbind() = 0; - virtual void* GetNativeHandle() = 0; virtual PipelineType GetType() const = 0; }; diff --git a/engine/include/XCEngine/RHI/RHITypes.h b/engine/include/XCEngine/RHI/RHITypes.h index c40cf826..7b61ab6d 100644 --- a/engine/include/XCEngine/RHI/RHITypes.h +++ b/engine/include/XCEngine/RHI/RHITypes.h @@ -236,9 +236,81 @@ struct RootSignatureDesc { uint32_t size; }; -struct PipelineStateDesc { - const void* pBlob; - uint32_t size; +// ========== Pipeline State Structures (Unity SRP style) ========== + +struct StencilOpDesc { + uint32_t failOp = 0; // StencilOp + uint32_t passOp = 0; // StencilOp + uint32_t depthFailOp = 0; // StencilOp + uint32_t func = 0; // ComparisonFunc +}; + +struct DepthStencilStateDesc { + bool depthTestEnable = true; + bool depthWriteEnable = true; + bool depthBoundsEnable = false; + uint32_t depthFunc = 0; // ComparisonFunc + bool stencilEnable = false; + uint8_t stencilReadMask = 0xFF; + uint8_t stencilWriteMask = 0xFF; + StencilOpDesc front; + StencilOpDesc back; +}; + +struct BlendDesc { + bool blendEnable = false; + uint32_t srcBlend = 0; // BlendFactor + uint32_t dstBlend = 0; // BlendFactor + uint32_t srcBlendAlpha = 0; // BlendFactor + uint32_t dstBlendAlpha = 0; // BlendFactor + uint32_t blendOp = 0; // BlendOp + uint32_t blendOpAlpha = 0; // BlendOp + uint8_t colorWriteMask = 0xF; + float blendFactor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; +}; + +struct RasterizerDesc { + uint32_t fillMode = 0; // FillMode (default: Solid) + uint32_t cullMode = 0; // CullMode (default: Back) + uint32_t frontFace = 0; // FrontFace (default: CounterClockwise) + bool depthClipEnable = true; + bool scissorTestEnable = false; + bool multisampleEnable = false; + bool antialiasedLineEnable = false; + int depthBias = 0; + float depthBiasClamp = 0.0f; + float slopeScaledDepthBias = 0.0f; +}; + +struct PipelineStateHash { + uint64_t blendStateHash = 0; + uint64_t depthStateHash = 0; + uint64_t rasterizerStateHash = 0; + uint64_t inputLayoutHash = 0; + uint64_t topologyHash = 0; + uint64_t renderTargetHash = 0; + + bool operator==(const PipelineStateHash& other) const { + return blendStateHash == other.blendStateHash && + depthStateHash == other.depthStateHash && + rasterizerStateHash == other.rasterizerStateHash && + inputLayoutHash == other.inputLayoutHash && + topologyHash == other.topologyHash && + renderTargetHash == other.renderTargetHash; + } +}; + +struct GraphicsPipelineDesc { + InputLayoutDesc inputLayout; + RasterizerDesc rasterizerState; + BlendDesc blendState; + DepthStencilStateDesc depthStencilState; + + uint32_t topologyType = 0; // PrimitiveTopologyType + uint32_t renderTargetCount = 1; + uint32_t renderTargetFormats[8] = { 0 }; // Format + uint32_t depthStencilFormat = 0; // Format + uint32_t sampleCount = 1; }; struct RHIDeviceDesc { diff --git a/engine/src/RHI/D3D12/D3D12Device.cpp b/engine/src/RHI/D3D12/D3D12Device.cpp index 9e4cf5e8..3c058d04 100644 --- a/engine/src/RHI/D3D12/D3D12Device.cpp +++ b/engine/src/RHI/D3D12/D3D12Device.cpp @@ -368,8 +368,16 @@ RHICommandQueue* D3D12Device::CreateCommandQueue(const CommandQueueDesc& desc) { return nullptr; } -RHIPipelineState* D3D12Device::CreatePipelineState(const PipelineStateDesc& desc) { - return nullptr; +RHIPipelineState* D3D12Device::CreatePipelineState(const GraphicsPipelineDesc& desc) { + auto* pso = new D3D12PipelineState(m_device.Get()); + pso->SetInputLayout(desc.inputLayout); + pso->SetRasterizerState(desc.rasterizerState); + pso->SetBlendState(desc.blendState); + pso->SetDepthStencilState(desc.depthStencilState); + pso->SetTopology(desc.topologyType); + pso->SetRenderTargetFormats(desc.renderTargetCount, desc.renderTargetFormats, desc.depthStencilFormat); + pso->SetSampleCount(desc.sampleCount); + return pso; } RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) { diff --git a/engine/src/RHI/D3D12/D3D12PipelineState.cpp b/engine/src/RHI/D3D12/D3D12PipelineState.cpp index 70525c50..f418e141 100644 --- a/engine/src/RHI/D3D12/D3D12PipelineState.cpp +++ b/engine/src/RHI/D3D12/D3D12PipelineState.cpp @@ -1,63 +1,204 @@ #include "XCEngine/RHI/D3D12/D3D12PipelineState.h" +#include namespace XCEngine { namespace RHI { -D3D12PipelineState::D3D12PipelineState() { +D3D12PipelineState::D3D12PipelineState(ID3D12Device* device) + : m_device(device), m_finalized(false) { + m_renderTargetFormats[0] = static_cast(Format::R8G8B8A8_UNorm); + m_depthStencilFormat = static_cast(Format::D24_UNorm_S8_UInt); +} + +bool D3D12PipelineState::Initialize(ID3D12Device* device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& desc) { + m_device = device; + m_rootSignature = desc.pRootSignature; + + m_rasterizerDesc.fillMode = static_cast(desc.RasterizerState.FillMode); + m_rasterizerDesc.cullMode = static_cast(desc.RasterizerState.CullMode); + m_rasterizerDesc.frontFace = desc.RasterizerState.FrontCounterClockwise ? 1 : 0; // 1 = CounterClockwise + m_rasterizerDesc.depthClipEnable = desc.RasterizerState.DepthClipEnable != 0; + + m_blendDesc.blendEnable = desc.BlendState.RenderTarget[0].BlendEnable != 0; + m_blendDesc.srcBlend = static_cast(desc.BlendState.RenderTarget[0].SrcBlend); + m_blendDesc.dstBlend = static_cast(desc.BlendState.RenderTarget[0].DestBlend); + m_blendDesc.blendOp = static_cast(desc.BlendState.RenderTarget[0].BlendOp); + m_blendDesc.srcBlendAlpha = static_cast(desc.BlendState.RenderTarget[0].SrcBlendAlpha); + m_blendDesc.dstBlendAlpha = static_cast(desc.BlendState.RenderTarget[0].DestBlendAlpha); + m_blendDesc.blendOpAlpha = static_cast(desc.BlendState.RenderTarget[0].BlendOpAlpha); + m_blendDesc.colorWriteMask = desc.BlendState.RenderTarget[0].RenderTargetWriteMask; + + m_depthStencilDesc.depthTestEnable = desc.DepthStencilState.DepthEnable != 0; + m_depthStencilDesc.depthWriteEnable = (desc.DepthStencilState.DepthWriteMask == D3D12_DEPTH_WRITE_MASK_ALL); + m_depthStencilDesc.depthFunc = static_cast(desc.DepthStencilState.DepthFunc); + m_depthStencilDesc.stencilEnable = desc.DepthStencilState.StencilEnable != 0; + m_depthStencilDesc.stencilReadMask = desc.DepthStencilState.StencilReadMask; + m_depthStencilDesc.stencilWriteMask = desc.DepthStencilState.StencilWriteMask; + + m_topologyType = static_cast(desc.PrimitiveTopologyType); + m_renderTargetCount = desc.NumRenderTargets; + for (UINT i = 0; i < desc.NumRenderTargets; ++i) { + m_renderTargetFormats[i] = static_cast(desc.RTVFormats[i]); + } + m_depthStencilFormat = static_cast(desc.DSVFormat); + m_sampleCount = desc.SampleDesc.Count; + + // Set shader bytecodes + m_vsBytecode = desc.VS; + m_psBytecode = desc.PS; + m_gsBytecode = desc.GS; + + // Set input layout + m_inputElements.clear(); + for (UINT i = 0; i < desc.InputLayout.NumElements; ++i) { + m_inputElements.push_back(desc.InputLayout.pInputElementDescs[i]); + } + + return Finalize(); } D3D12PipelineState::~D3D12PipelineState() { Shutdown(); } -bool D3D12PipelineState::Initialize(ID3D12Device* device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& desc) { - HRESULT hResult = device->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&m_pipelineState)); - if (FAILED(hResult)) { +void D3D12PipelineState::SetInputLayout(const InputLayoutDesc& layout) { + m_inputLayoutDesc = layout; + m_inputElements.clear(); + for (const auto& elem : layout.elements) { + D3D12_INPUT_ELEMENT_DESC desc = {}; + desc.SemanticName = elem.semanticName.c_str(); + desc.SemanticIndex = elem.semanticIndex; + desc.Format = ToD3D12(static_cast(elem.format)); + desc.InputSlot = elem.inputSlot; + desc.AlignedByteOffset = elem.alignedByteOffset; + desc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + desc.InstanceDataStepRate = 0; + m_inputElements.push_back(desc); + } +} + +void D3D12PipelineState::SetRasterizerState(const RasterizerDesc& state) { + m_rasterizerDesc = state; +} + +void D3D12PipelineState::SetBlendState(const BlendDesc& state) { + m_blendDesc = state; +} + +void D3D12PipelineState::SetDepthStencilState(const DepthStencilStateDesc& state) { + m_depthStencilDesc = state; +} + +void D3D12PipelineState::SetTopology(uint32_t topologyType) { + m_topologyType = topologyType; +} + +void D3D12PipelineState::SetRenderTargetFormats(uint32_t count, const uint32_t* formats, uint32_t depthFormat) { + m_renderTargetCount = count; + for (uint32_t i = 0; i < count && i < 8; ++i) { + m_renderTargetFormats[i] = formats[i]; + } + m_depthStencilFormat = depthFormat; +} + +void D3D12PipelineState::SetSampleCount(uint32_t count) { + m_sampleCount = count; +} + +PipelineStateHash D3D12PipelineState::GetHash() const { + PipelineStateHash hash = {}; + hash.blendStateHash = std::hash{}(*reinterpret_cast(&m_blendDesc)); + hash.depthStateHash = std::hash{}(*reinterpret_cast(&m_depthStencilDesc)); + hash.rasterizerStateHash = std::hash{}(*reinterpret_cast(&m_rasterizerDesc)); + hash.topologyHash = m_topologyType; + hash.renderTargetHash = m_renderTargetCount | (m_depthStencilFormat << 8); + return hash; +} + +void D3D12PipelineState::SetShaderBytecodes(const D3D12_SHADER_BYTECODE& vs, const D3D12_SHADER_BYTECODE& ps, const D3D12_SHADER_BYTECODE& gs) { + m_vsBytecode = vs; + m_psBytecode = ps; + m_gsBytecode = gs; +} + +bool D3D12PipelineState::Finalize() { + if (m_finalized) return true; + return CreateD3D12PSO(); +} + +bool D3D12PipelineState::CreateD3D12PSO() { + if (!m_vsBytecode.pShaderBytecode || !m_psBytecode.pShaderBytecode) { return false; } + + D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {}; + desc.pRootSignature = m_rootSignature; + desc.VS = m_vsBytecode; + desc.PS = m_psBytecode; + desc.GS = m_gsBytecode; + + desc.InputLayout.NumElements = static_cast(m_inputElements.size()); + desc.InputLayout.pInputElementDescs = m_inputElements.data(); + + desc.RasterizerState.FillMode = static_cast(m_rasterizerDesc.fillMode); + desc.RasterizerState.CullMode = static_cast(m_rasterizerDesc.cullMode); + desc.RasterizerState.FrontCounterClockwise = (m_rasterizerDesc.frontFace != 0); + desc.RasterizerState.DepthClipEnable = m_rasterizerDesc.depthClipEnable; + desc.RasterizerState.MultisampleEnable = m_rasterizerDesc.multisampleEnable; + desc.RasterizerState.AntialiasedLineEnable = m_rasterizerDesc.antialiasedLineEnable; + + desc.BlendState.RenderTarget[0].BlendEnable = m_blendDesc.blendEnable; + desc.BlendState.RenderTarget[0].SrcBlend = static_cast(m_blendDesc.srcBlend); + desc.BlendState.RenderTarget[0].DestBlend = static_cast(m_blendDesc.dstBlend); + desc.BlendState.RenderTarget[0].BlendOp = static_cast(m_blendDesc.blendOp); + desc.BlendState.RenderTarget[0].SrcBlendAlpha = static_cast(m_blendDesc.srcBlendAlpha); + desc.BlendState.RenderTarget[0].DestBlendAlpha = static_cast(m_blendDesc.dstBlendAlpha); + desc.BlendState.RenderTarget[0].BlendOpAlpha = static_cast(m_blendDesc.blendOpAlpha); + desc.BlendState.RenderTarget[0].RenderTargetWriteMask = m_blendDesc.colorWriteMask; + + desc.DepthStencilState.DepthEnable = m_depthStencilDesc.depthTestEnable; + desc.DepthStencilState.DepthWriteMask = m_depthStencilDesc.depthWriteEnable ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + desc.DepthStencilState.DepthFunc = static_cast(m_depthStencilDesc.depthFunc); + desc.DepthStencilState.StencilEnable = m_depthStencilDesc.stencilEnable; + desc.DepthStencilState.StencilReadMask = m_depthStencilDesc.stencilReadMask; + desc.DepthStencilState.StencilWriteMask = m_depthStencilDesc.stencilWriteMask; + desc.DepthStencilState.FrontFace.StencilFailOp = static_cast(m_depthStencilDesc.front.failOp); + desc.DepthStencilState.FrontFace.StencilPassOp = static_cast(m_depthStencilDesc.front.passOp); + desc.DepthStencilState.FrontFace.StencilDepthFailOp = static_cast(m_depthStencilDesc.front.depthFailOp); + desc.DepthStencilState.FrontFace.StencilFunc = static_cast(m_depthStencilDesc.front.func); + desc.DepthStencilState.BackFace.StencilFailOp = static_cast(m_depthStencilDesc.back.failOp); + desc.DepthStencilState.BackFace.StencilPassOp = static_cast(m_depthStencilDesc.back.passOp); + desc.DepthStencilState.BackFace.StencilDepthFailOp = static_cast(m_depthStencilDesc.back.depthFailOp); + desc.DepthStencilState.BackFace.StencilFunc = static_cast(m_depthStencilDesc.back.func); + + desc.NumRenderTargets = m_renderTargetCount; + for (uint32_t i = 0; i < m_renderTargetCount && i < 8; ++i) { + desc.RTVFormats[i] = static_cast(m_renderTargetFormats[i]); + } + desc.DSVFormat = static_cast(m_depthStencilFormat); + desc.SampleDesc.Count = m_sampleCount; + desc.SampleDesc.Quality = 0; + desc.SampleMask = 0xffffffff; + desc.PrimitiveTopologyType = static_cast(m_topologyType); + + HRESULT hr = m_device->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&m_pipelineState)); + if (FAILED(hr)) { + return false; + } + + m_finalized = true; return true; } void D3D12PipelineState::Shutdown() { m_pipelineState.Reset(); + m_finalized = false; } -D3D12_GRAPHICS_PIPELINE_STATE_DESC D3D12PipelineState::CreateDesc( - ID3D12RootSignature* rootSignature, - const D3D12_SHADER_BYTECODE& vs, - const D3D12_SHADER_BYTECODE& ps, - const D3D12_SHADER_BYTECODE& gs, - uint32_t inputElementCount, - const D3D12_INPUT_ELEMENT_DESC* inputElements) { - D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {}; - desc.pRootSignature = rootSignature; - desc.VS = vs; - desc.PS = ps; - desc.GS = gs; - desc.InputLayout.NumElements = inputElementCount; - desc.InputLayout.pInputElementDescs = inputElements; - desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.SampleMask = 0xffffffff; - desc.NumRenderTargets = 1; - desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; - desc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK; - desc.RasterizerState.DepthClipEnable = TRUE; - desc.DepthStencilState.DepthEnable = TRUE; - desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; - desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; - desc.BlendState.RenderTarget[0].BlendEnable = FALSE; - desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; - desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ZERO; - desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; - desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; - desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; - desc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - return desc; +void D3D12PipelineState::Bind() { +} + +void D3D12PipelineState::Unbind() { } D3D12_INPUT_ELEMENT_DESC D3D12PipelineState::CreateInputElement( @@ -85,11 +226,5 @@ D3D12_INPUT_ELEMENT_DESC D3D12PipelineState::CreateInputElement( return CreateInputElement(semanticName, semanticIndex, format, inputSlot, D3D12_APPEND_ALIGNED_ELEMENT); } -void D3D12PipelineState::Bind() { -} - -void D3D12PipelineState::Unbind() { -} - } // namespace RHI -} // namespace XCEngine +} // namespace XCEngine \ No newline at end of file diff --git a/engine/src/RHI/OpenGL/OpenGLDevice.cpp b/engine/src/RHI/OpenGL/OpenGLDevice.cpp index 92d850ac..ea5d2ca6 100644 --- a/engine/src/RHI/OpenGL/OpenGLDevice.cpp +++ b/engine/src/RHI/OpenGL/OpenGLDevice.cpp @@ -444,8 +444,15 @@ RHIShader* OpenGLDevice::CompileShader(const ShaderCompileDesc& desc) { return shader; } -RHIPipelineState* OpenGLDevice::CreatePipelineState(const PipelineStateDesc& desc) { +RHIPipelineState* OpenGLDevice::CreatePipelineState(const GraphicsPipelineDesc& desc) { auto* pso = new OpenGLPipelineState(); + pso->SetInputLayout(desc.inputLayout); + pso->SetRasterizerState(desc.rasterizerState); + pso->SetBlendState(desc.blendState); + pso->SetDepthStencilState(desc.depthStencilState); + pso->SetTopology(desc.topologyType); + pso->SetRenderTargetFormats(desc.renderTargetCount, desc.renderTargetFormats, desc.depthStencilFormat); + pso->SetSampleCount(desc.sampleCount); return pso; } diff --git a/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp b/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp index 9c63d21f..a9868c93 100644 --- a/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp +++ b/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp @@ -1,154 +1,90 @@ -#define GLFW_INCLUDE_NONE #include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h" #include namespace XCEngine { namespace RHI { -static unsigned int ToGLComparisonFunc(ComparisonFunc func) { - switch (func) { - case ComparisonFunc::Never: return GL_NEVER; - case ComparisonFunc::Less: return GL_LESS; - case ComparisonFunc::Equal: return GL_EQUAL; - case ComparisonFunc::LessEqual: return GL_LEQUAL; - case ComparisonFunc::Greater: return GL_GREATER; - case ComparisonFunc::NotEqual: return GL_NOTEQUAL; - case ComparisonFunc::GreaterEqual: return GL_GEQUAL; - case ComparisonFunc::Always: return GL_ALWAYS; - default: return GL_LESS; - } -} - -static unsigned int ToGLBlendFactor(BlendFactor factor) { - switch (factor) { - case BlendFactor::Zero: return GL_ZERO; - case BlendFactor::One: return GL_ONE; - case BlendFactor::SrcColor: return GL_SRC_COLOR; - case BlendFactor::InvSrcColor: return GL_ONE_MINUS_SRC_COLOR; - case BlendFactor::DstColor: return GL_DST_COLOR; - case BlendFactor::InvDstColor: return GL_ONE_MINUS_DST_COLOR; - case BlendFactor::SrcAlpha: return GL_SRC_ALPHA; - case BlendFactor::InvSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA; - case BlendFactor::DstAlpha: return GL_DST_ALPHA; - case BlendFactor::InvDstAlpha: return GL_ONE_MINUS_DST_ALPHA; - case BlendFactor::SrcAlphaSat: return GL_SRC_ALPHA_SATURATE; - case BlendFactor::Src1Color: return GL_SRC1_COLOR; - case BlendFactor::InvSrc1Color: return GL_ONE_MINUS_SRC1_COLOR; - case BlendFactor::Src1Alpha: return GL_SRC1_ALPHA; - case BlendFactor::InvSrc1Alpha: return GL_ONE_MINUS_SRC1_ALPHA; - default: return GL_ONE; - } -} - -static unsigned int ToGLBlendOp(BlendOp op) { - switch (op) { - case BlendOp::Add: return GL_FUNC_ADD; - case BlendOp::Subtract: return GL_FUNC_SUBTRACT; - case BlendOp::ReverseSubtract: return GL_FUNC_REVERSE_SUBTRACT; - case BlendOp::Min: return GL_MIN; - case BlendOp::Max: return GL_MAX; - default: return GL_FUNC_ADD; - } -} - -static unsigned int ToGLCullFace(CullFace face) { - switch (face) { - case CullFace::Front: return GL_FRONT; - case CullFace::Back: return GL_BACK; - case CullFace::FrontAndBack: return GL_FRONT_AND_BACK; - default: return GL_BACK; - } -} - -static unsigned int ToGLFrontFace(FrontFace face) { - switch (face) { - case FrontFace::Clockwise: return GL_CW; - case FrontFace::CounterClockwise: return GL_CCW; - default: return GL_CCW; - } -} - -static unsigned int ToGLPolygonMode(PolygonMode mode) { - switch (mode) { - case PolygonMode::Point: return GL_POINT; - case PolygonMode::Line: return GL_LINE; - case PolygonMode::Fill: return GL_FILL; - default: return GL_FILL; - } -} - -static unsigned int ToGLStencilOp(StencilOp op) { - switch (op) { - case StencilOp::Keep: return GL_KEEP; - case StencilOp::Zero: return GL_ZERO; - case StencilOp::Replace: return GL_REPLACE; - case StencilOp::Incr: return GL_INCR; - case StencilOp::IncrSat: return GL_INCR_WRAP; - case StencilOp::Decr: return GL_DECR; - case StencilOp::DecrSat: return GL_DECR_WRAP; - case StencilOp::Invert: return GL_INVERT; - default: return GL_KEEP; - } -} - OpenGLPipelineState::OpenGLPipelineState() - : m_program(0) - , m_programAttached(false) { - m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0.0f; + : m_program(0), m_programAttached(false) { } OpenGLPipelineState::~OpenGLPipelineState() { } -void OpenGLPipelineState::SetDepthStencilState(const OpenGLDepthStencilState& state) { - m_depthStencilState = state; +void OpenGLPipelineState::SetInputLayout(const InputLayoutDesc& layout) { + m_inputLayoutDesc = layout; } -void OpenGLPipelineState::SetBlendState(const OpenGLBlendState& state) { - m_blendState = state; +void OpenGLPipelineState::SetRasterizerState(const RasterizerDesc& state) { + m_rasterizerDesc = state; } -void OpenGLPipelineState::SetRasterizerState(const OpenGLRasterizerState& state) { - m_rasterizerState = state; +void OpenGLPipelineState::SetBlendState(const BlendDesc& state) { + m_blendDesc = state; } -void OpenGLPipelineState::SetViewport(const ViewportState& state) { - m_viewportState = state; +void OpenGLPipelineState::SetDepthStencilState(const DepthStencilStateDesc& state) { + m_depthStencilDesc = state; } -void OpenGLPipelineState::SetScissor(const ScissorState& state) { - m_scissorState = state; +void OpenGLPipelineState::SetTopology(uint32_t topologyType) { + m_topologyType = topologyType; } -void OpenGLPipelineState::SetLogicalOperation(const LogicalOperation& state) { - m_logicalOperation = state; +void OpenGLPipelineState::SetRenderTargetFormats(uint32_t count, const uint32_t* formats, uint32_t depthFormat) { +} + +void OpenGLPipelineState::SetSampleCount(uint32_t count) { +} + +PipelineStateHash OpenGLPipelineState::GetHash() const { + PipelineStateHash hash = {}; + return hash; +} + +void OpenGLPipelineState::Shutdown() { + m_program = 0; + m_programAttached = false; +} + +void OpenGLPipelineState::Bind() { + if (m_programAttached) { + glUseProgram(m_program); + } + Apply(); +} + +void OpenGLPipelineState::Unbind() { + glUseProgram(0); } void OpenGLPipelineState::Apply() { ApplyDepthStencil(); ApplyBlend(); ApplyRasterizer(); - ApplyViewport(); - ApplyScissor(); } void OpenGLPipelineState::ApplyDepthStencil() { - if (m_depthStencilState.depthTestEnable) { + if (m_glDepthStencilState.depthTestEnable) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } - glDepthMask(m_depthStencilState.depthWriteEnable ? GL_TRUE : GL_FALSE); - glDepthFunc(ToGLComparisonFunc(m_depthStencilState.depthFunc)); + glDepthMask(m_glDepthStencilState.depthWriteEnable ? GL_TRUE : GL_FALSE); + glDepthFunc(static_cast(m_glDepthStencilState.depthFunc)); - if (m_depthStencilState.stencilEnable) { + if (m_glDepthStencilState.stencilEnable) { glEnable(GL_STENCIL_TEST); - glStencilMask(m_depthStencilState.stencilWriteMask); - glStencilFunc(ToGLComparisonFunc(m_depthStencilState.stencilFunc), m_depthStencilState.stencilRef, m_depthStencilState.stencilReadMask); + glStencilMask(m_glDepthStencilState.stencilWriteMask); + glStencilFunc( + static_cast(m_glDepthStencilState.stencilFunc), + m_glDepthStencilState.stencilRef, + m_glDepthStencilState.stencilReadMask + ); glStencilOp( - ToGLStencilOp(m_depthStencilState.stencilFailOp), - ToGLStencilOp(m_depthStencilState.stencilDepthFailOp), - ToGLStencilOp(m_depthStencilState.stencilDepthPassOp) + static_cast(m_glDepthStencilState.stencilFailOp), + static_cast(m_glDepthStencilState.stencilDepthFailOp), + static_cast(m_glDepthStencilState.stencilDepthPassOp) ); } else { glDisable(GL_STENCIL_TEST); @@ -156,29 +92,23 @@ void OpenGLPipelineState::ApplyDepthStencil() { } void OpenGLPipelineState::ApplyBlend() { - if (m_blendState.blendEnable) { + if (m_glBlendState.blendEnable) { glEnable(GL_BLEND); glBlendFuncSeparate( - ToGLBlendFactor(m_blendState.srcBlend), - ToGLBlendFactor(m_blendState.dstBlend), - ToGLBlendFactor(m_blendState.srcBlendAlpha), - ToGLBlendFactor(m_blendState.dstBlendAlpha) + static_cast(m_glBlendState.srcBlend), + static_cast(m_glBlendState.dstBlend), + static_cast(m_glBlendState.srcBlendAlpha), + static_cast(m_glBlendState.dstBlendAlpha) ); glBlendEquationSeparate( - ToGLBlendOp(m_blendState.blendOp), - ToGLBlendOp(m_blendState.blendOpAlpha) - ); - glBlendColor( - m_blendState.blendFactor[0], - m_blendState.blendFactor[1], - m_blendState.blendFactor[2], - m_blendState.blendFactor[3] + static_cast(m_glBlendState.blendOp), + static_cast(m_glBlendState.blendOpAlpha) ); glColorMask( - (m_blendState.colorWriteMask & 1) != 0, - (m_blendState.colorWriteMask & 2) != 0, - (m_blendState.colorWriteMask & 4) != 0, - (m_blendState.colorWriteMask & 8) != 0 + (m_glBlendState.colorWriteMask & 1) != 0, + (m_glBlendState.colorWriteMask & 2) != 0, + (m_glBlendState.colorWriteMask & 4) != 0, + (m_glBlendState.colorWriteMask & 8) != 0 ); } else { glDisable(GL_BLEND); @@ -186,40 +116,21 @@ void OpenGLPipelineState::ApplyBlend() { } void OpenGLPipelineState::ApplyRasterizer() { - if (m_rasterizerState.cullFaceEnable) { + if (m_glRasterizerState.cullFaceEnable) { glEnable(GL_CULL_FACE); - glCullFace(ToGLCullFace(m_rasterizerState.cullFace)); - glFrontFace(ToGLFrontFace(m_rasterizerState.frontFace)); + glCullFace(static_cast(m_glRasterizerState.cullFace)); + glFrontFace(static_cast(m_glRasterizerState.frontFace)); } else { glDisable(GL_CULL_FACE); } - glPolygonMode(GL_FRONT_AND_BACK, ToGLPolygonMode(m_rasterizerState.polygonMode)); + glPolygonMode(GL_FRONT_AND_BACK, static_cast(m_glRasterizerState.polygonMode)); - if (m_rasterizerState.polygonOffsetFactor != 0.0f || m_rasterizerState.polygonOffsetUnits != 0.0f) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(m_rasterizerState.polygonOffsetFactor, m_rasterizerState.polygonOffsetUnits); - } else { - glDisable(GL_POLYGON_OFFSET_FILL); - } - - if (m_rasterizerState.scissorTestEnable) { - glEnable(GL_SCISSOR_TEST); - } else { - glDisable(GL_SCISSOR_TEST); - } - - if (m_rasterizerState.multisampleEnable) { + if (m_glRasterizerState.multisampleEnable) { glEnable(GL_MULTISAMPLE); } else { glDisable(GL_MULTISAMPLE); } - - if (m_rasterizerState.sampleAlphaToCoverageEnable) { - glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } else { - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); - } } void OpenGLPipelineState::ApplyViewport() { @@ -237,6 +148,31 @@ void OpenGLPipelineState::ApplyScissor() { } } +void OpenGLPipelineState::SetProgram(unsigned int program) { + m_program = program; + m_programAttached = (program != 0); +} + +void OpenGLPipelineState::SetDepthStencilState(const OpenGLDepthStencilState& state) { + m_glDepthStencilState = state; +} + +void OpenGLPipelineState::SetBlendState(const OpenGLBlendState& state) { + m_glBlendState = state; +} + +void OpenGLPipelineState::SetRasterizerState(const OpenGLRasterizerState& state) { + m_glRasterizerState = state; +} + +void OpenGLPipelineState::SetViewport(const ViewportState& state) { + m_viewportState = state; +} + +void OpenGLPipelineState::SetScissor(const ScissorState& state) { + m_scissorState = state; +} + void OpenGLPipelineState::SetClearColor(float r, float g, float b, float a) { m_clearColor[0] = r; m_clearColor[1] = g; @@ -265,25 +201,17 @@ void OpenGLPipelineState::DetachShader() { glUseProgram(0); } -void OpenGLPipelineState::Shutdown() { - m_program = 0; - m_programAttached = false; +const OpenGLDepthStencilState& OpenGLPipelineState::GetOpenGLDepthStencilState() const { + return m_glDepthStencilState; } -void OpenGLPipelineState::Bind() { - if (m_programAttached) { - glUseProgram(m_program); - } - Apply(); +const OpenGLBlendState& OpenGLPipelineState::GetOpenGLBlendState() const { + return m_glBlendState; } -void OpenGLPipelineState::Unbind() { - glUseProgram(0); -} - -void* OpenGLPipelineState::GetNativeHandle() { - return reinterpret_cast(static_cast(m_program)); +const OpenGLRasterizerState& OpenGLPipelineState::GetOpenGLRasterizerState() const { + return m_glRasterizerState; } } // namespace RHI -} // namespace XCEngine +} // namespace XCEngine \ No newline at end of file