RHI: Replace IsFinalized/Finalize with IsValid/EnsureValid

Unified PSO validation semantics across D3D12 and OpenGL backends:
- IsValid() returns whether PSO is ready to use
- EnsureValid() ensures PSO is valid (compiles if needed)

Behavior by backend:
- D3D12: IsValid=false after creation, true after EnsureValid() with shaders
- OpenGL: IsValid always=true (immediate model)

Also added test_pipeline_state.cpp with 10 tests for RHIPipelineState.
This commit is contained in:
2026-03-25 12:28:33 +08:00
parent ca0d73c197
commit f808f8d197
7 changed files with 225 additions and 106 deletions

View File

@@ -42,9 +42,9 @@ public:
RHIShader* GetComputeShader() const override { return m_computeShader; }
bool HasComputeShader() const override { return m_csBytecode.pShaderBytecode != nullptr && m_csBytecode.BytecodeLength > 0; }
// Finalization
bool IsFinalized() const override { return m_finalized; }
bool Finalize() override;
// Validation
bool IsValid() const override { return m_finalized; }
void EnsureValid() 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 = {});

View File

@@ -90,9 +90,9 @@ public:
RHIShader* GetComputeShader() const override { return m_computeShader; }
bool HasComputeShader() const override { return m_computeProgram != 0; }
// Finalization (OpenGL doesn't need it)
bool IsFinalized() const override { return true; }
bool Finalize() override { return true; }
// Validation (OpenGL总是有效,即时模型)
bool IsValid() const override { return true; }
void EnsureValid() override {}
// Lifecycle
void Shutdown() override;

View File

@@ -31,9 +31,9 @@ public:
virtual RHIShader* GetComputeShader() const = 0;
virtual bool HasComputeShader() const = 0;
// Finalization (D3D12/Vulkan creates real PSO)
virtual bool IsFinalized() const = 0;
virtual bool Finalize() = 0;
// Validation (统一语义D3D12需要编译OpenGL总是有效)
virtual bool IsValid() const = 0;
virtual void EnsureValid() = 0;
// Lifecycle
virtual void Shutdown() = 0;

View File

@@ -55,7 +55,8 @@ bool D3D12PipelineState::Initialize(ID3D12Device* device, const D3D12_GRAPHICS_P
m_inputElements.push_back(desc.InputLayout.pInputElementDescs[i]);
}
return Finalize();
EnsureValid();
return m_finalized;
}
D3D12PipelineState::~D3D12PipelineState() {
@@ -130,12 +131,13 @@ void D3D12PipelineState::SetComputeShaderBytecodes(const D3D12_SHADER_BYTECODE&
m_csBytecode = cs;
}
bool D3D12PipelineState::Finalize() {
if (m_finalized) return true;
void D3D12PipelineState::EnsureValid() {
if (m_finalized) return;
if (HasComputeShader()) {
return CreateD3D12ComputePSO();
CreateD3D12ComputePSO();
} else {
CreateD3D12PSO();
}
return CreateD3D12PSO();
}
bool D3D12PipelineState::CreateD3D12PSO() {