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:
172
tests/RHI/unit/test_pipeline_state.cpp
Normal file
172
tests/RHI/unit/test_pipeline_state.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#include "fixtures/RHITestFixture.h"
|
||||
#include "XCEngine/RHI/RHIPipelineState.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_Create_DefaultDesc) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
if (pso != nullptr) {
|
||||
if (GetBackendType() == RHIType::D3D12) {
|
||||
EXPECT_FALSE(pso->IsValid());
|
||||
} else {
|
||||
EXPECT_TRUE(pso->IsValid());
|
||||
}
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_SetGet_RasterizerState) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
RasterizerDesc rasterizer = {};
|
||||
rasterizer.fillMode = 2;
|
||||
rasterizer.cullMode = 2;
|
||||
rasterizer.depthClipEnable = true;
|
||||
pso->SetRasterizerState(rasterizer);
|
||||
|
||||
const RasterizerDesc& retrieved = pso->GetRasterizerState();
|
||||
EXPECT_EQ(retrieved.cullMode, 2u);
|
||||
EXPECT_EQ(retrieved.fillMode, 2u);
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_SetGet_BlendState) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
BlendDesc blend = {};
|
||||
blend.blendEnable = true;
|
||||
blend.srcBlend = 1;
|
||||
blend.dstBlend = 0;
|
||||
pso->SetBlendState(blend);
|
||||
|
||||
const BlendDesc& retrieved = pso->GetBlendState();
|
||||
EXPECT_TRUE(retrieved.blendEnable);
|
||||
EXPECT_EQ(retrieved.srcBlend, 1u);
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_SetGet_DepthStencilState) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
DepthStencilStateDesc ds = {};
|
||||
ds.depthTestEnable = true;
|
||||
ds.depthWriteEnable = true;
|
||||
ds.depthFunc = 3;
|
||||
pso->SetDepthStencilState(ds);
|
||||
|
||||
const DepthStencilStateDesc& retrieved = pso->GetDepthStencilState();
|
||||
EXPECT_TRUE(retrieved.depthTestEnable);
|
||||
EXPECT_TRUE(retrieved.depthWriteEnable);
|
||||
EXPECT_EQ(retrieved.depthFunc, 3u);
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_SetGet_InputLayout) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
InputElementDesc element = {};
|
||||
element.semanticName = "POSITION";
|
||||
element.semanticIndex = 0;
|
||||
element.format = static_cast<uint32_t>(Format::R32G32B32A32_Float);
|
||||
element.inputSlot = 0;
|
||||
element.alignedByteOffset = 0;
|
||||
|
||||
InputLayoutDesc layoutDesc = {};
|
||||
layoutDesc.elements.push_back(element);
|
||||
pso->SetInputLayout(layoutDesc);
|
||||
|
||||
const InputLayoutDesc& retrieved = pso->GetInputLayout();
|
||||
ASSERT_EQ(retrieved.elements.size(), 1u);
|
||||
EXPECT_EQ(retrieved.elements[0].semanticName, "POSITION");
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_SetTopology) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
pso->SetTopology(3);
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_SetRenderTargetFormats) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
uint32_t formats[] = { static_cast<uint32_t>(Format::R8G8B8A8_UNorm) };
|
||||
pso->SetRenderTargetFormats(1, formats, static_cast<uint32_t>(Format::D24_UNorm_S8_UInt));
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_EnsureValid_IsValid) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
desc.renderTargetFormats[0] = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||
desc.depthStencilFormat = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
if (GetBackendType() == RHIType::D3D12) {
|
||||
EXPECT_FALSE(pso->IsValid());
|
||||
pso->EnsureValid();
|
||||
EXPECT_FALSE(pso->IsValid());
|
||||
} else {
|
||||
EXPECT_TRUE(pso->IsValid());
|
||||
pso->EnsureValid();
|
||||
EXPECT_TRUE(pso->IsValid());
|
||||
}
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_Shutdown_Invalidates) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
desc.renderTargetFormats[0] = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||
desc.depthStencilFormat = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
pso->EnsureValid();
|
||||
pso->Shutdown();
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineState_GetType) {
|
||||
GraphicsPipelineDesc desc = {};
|
||||
RHIPipelineState* pso = GetDevice()->CreatePipelineState(desc);
|
||||
ASSERT_NE(pso, nullptr);
|
||||
|
||||
PipelineType type = pso->GetType();
|
||||
EXPECT_EQ(type, PipelineType::Graphics);
|
||||
|
||||
pso->Shutdown();
|
||||
delete pso;
|
||||
}
|
||||
Reference in New Issue
Block a user