RHI: Remove无效的动态状态方法 - SetDepthStencilState/SetBlendState

重构原因:
- D3D12 PSO是不可变的,SetDepthStencilState/SetBlendState调用原本就是空实现(TODO)
- 这些方法在D3D12中完全无效,是死代码

移除的方法:
- SetDepthStencilState(const DepthStencilState&) - D3D12空实现,OpenGL直接调用GL函数
- SetBlendState(const BlendState&) - D3D12只设置BlendFactor其他忽略,OpenGL直接调用GL函数

保留的真正动态状态:
- SetViewport/SetViewports
- SetScissorRect/SetScissorRects
- SetStencilRef (D3D12动态状态)
- SetBlendFactor (D3D12动态状态)

注:PrimitiveTopology保留在CommandList,因为D3D12允许动态改变topology type

测试状态:150个RHI单元测试全部通过,8个集成测试全部通过
This commit is contained in:
2026-03-25 00:37:18 +08:00
parent f8a2507bdf
commit a2fc8eca02
8 changed files with 31 additions and 132 deletions

View File

@@ -241,6 +241,36 @@ virtual void SetBlendState(const BlendState& state) = 0; // 移到 PSO
virtual void SetPrimitiveTopology(PrimitiveTopology topology) = 0; // 移到 PSO virtual void SetPrimitiveTopology(PrimitiveTopology topology) = 0; // 移到 PSO
``` ```
### 3.3.1 ✅ 已完成:动态状态移至 PSO
**实现状态**2026-03-25 已完成
**移除的无效方法**
| 方法 | 问题 |
|------|------|
| `SetDepthStencilState` | D3D12 中是空实现TODO调用无效OpenGL 中直接调用 GL 函数但状态应通过 PSO 配置 |
| `SetBlendState` | D3D12 中只设置 BlendFactor其他参数被忽略OpenGL 中直接调用 GL 函数但状态应通过 PSO 配置 |
**保留的真正动态状态**
| 方法 | 说明 |
|------|------|
| `SetViewport/SetViewports` | 真正的动态状态 |
| `SetScissorRect/SetScissorRects` | 真正的动态状态 |
| `SetStencilRef` | D3D12 动态状态 |
| `SetBlendFactor` | D3D12 动态状态 |
**修改的文件**
- `RHICommandList.h` - 移除 SetDepthStencilState/SetBlendState 纯虚方法
- `D3D12CommandList.h/cpp` - 移除 SetDepthStencilState/SetBlendState 实现
- `OpenGLCommandList.h/cpp` - 移除 SetDepthStencilState/SetBlendState 实现
- `tests/RHI/unit/test_command_list.cpp` - 移除相关测试
- `tests/RHI/OpenGL/unit/test_command_list.cpp` - 移除相关测试
**说明**
- D3D12 中 PSO 是不可变的SetDepthStencilState/SetBlendState 调用原本就是无效代码
- OpenGL 中状态通过 OpenGLPipelineState::Apply() 在绑定 PSO 时应用
- PrimitiveTopology 保留在 CommandList因为 D3D12 允许动态改变 topology type
--- ---
### 3.4 ResourceView 类型不明确 ✅ 基本完成 ### 3.4 ResourceView 类型不明确 ✅ 基本完成
@@ -507,7 +537,7 @@ class RHITexture : public RHIResource { ... };
|--------|------|--------|----------|------| |--------|------|--------|----------|------|
| 1 | 字符串查找 SetUniform 不符合 D3D12/Vulkan | 🔴 致命 | 高 | ✅ 已完成 | | 1 | 字符串查找 SetUniform 不符合 D3D12/Vulkan | 🔴 致命 | 高 | ✅ 已完成 |
| 2 | 缺少显式 RenderPass | 🔴 致命 | 高 | ✅ 已完成 | | 2 | 缺少显式 RenderPass | 🔴 致命 | 高 | ✅ 已完成 |
| 3 | 动态状态太多 | 🔴 高 | 高 | ❌ 未完成 | | 3 | 动态状态太多 | 🔴 高 | 高 | ✅ 已完成 |
| 4 | ResourceView 类型不明确 | 🟡 中 | 中 | ✅ 基本完成 | | 4 | ResourceView 类型不明确 | 🟡 中 | 中 | ✅ 基本完成 |
| 5 | TransitionBarrier 针对 View 而非 Resource | 🟡 中 | 中 | ✅ 已完成 | | 5 | TransitionBarrier 针对 View 而非 Resource | 🟡 中 | 中 | ✅ 已完成 |
| 6 | SetGlobal* 空操作 | 🟡 中 | 低 | ❌ 未完成 | | 6 | SetGlobal* 空操作 | 🟡 中 | 低 | ❌ 未完成 |

View File

@@ -104,8 +104,6 @@ public:
void SetGraphicsRootShaderResourceView(uint32_t rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS shaderResource); void SetGraphicsRootShaderResourceView(uint32_t rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS shaderResource);
void SetStencilRef(uint8_t stencilRef) override; void SetStencilRef(uint8_t stencilRef) override;
void SetDepthStencilState(const DepthStencilState& state) override;
void SetBlendState(const BlendState& state) override;
void SetBlendFactor(const float blendFactor[4]); void SetBlendFactor(const float blendFactor[4]);
void SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp); void SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp);

View File

@@ -191,9 +191,7 @@ public:
void SetScissorRect(const Rect& rect) override; void SetScissorRect(const Rect& rect) override;
void SetScissorRects(uint32_t count, const Rect* rects) override; void SetScissorRects(uint32_t count, const Rect* rects) override;
void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) override; void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) override;
void SetDepthStencilState(const DepthStencilState& state) override;
void SetStencilRef(uint8_t ref) override; void SetStencilRef(uint8_t ref) override;
void SetBlendState(const BlendState& state) override;
void SetBlendFactor(const float factor[4]) override; void SetBlendFactor(const float factor[4]) override;
void ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) override; void ClearRenderTarget(RHIResourceView* renderTarget, const float color[4]) override;
void ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) override; void ClearDepthStencil(RHIResourceView* depthStencil, float depth, uint8_t stencil) override;

View File

@@ -95,9 +95,7 @@ public:
virtual void SetScissorRects(uint32_t count, const Rect* rects) = 0; virtual void SetScissorRects(uint32_t count, const Rect* rects) = 0;
virtual void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) = 0; virtual void SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil = nullptr) = 0;
virtual void SetDepthStencilState(const DepthStencilState& state) = 0;
virtual void SetStencilRef(uint8_t ref) = 0; virtual void SetStencilRef(uint8_t ref) = 0;
virtual void SetBlendState(const BlendState& state) = 0;
virtual void SetBlendFactor(const float factor[4]) = 0; virtual void SetBlendFactor(const float factor[4]) = 0;
virtual void SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIResourceView** buffers, const uint64_t* offsets, const uint32_t* strides) = 0; virtual void SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIResourceView** buffers, const uint64_t* offsets, const uint32_t* strides) = 0;

View File

@@ -549,14 +549,6 @@ void D3D12CommandList::SetStencilRef(uint8_t stencilRef) {
m_commandList->OMSetStencilRef(stencilRef); m_commandList->OMSetStencilRef(stencilRef);
} }
void D3D12CommandList::SetDepthStencilState(const DepthStencilState& state) {
// TODO: Implement depth stencil state
}
void D3D12CommandList::SetBlendState(const BlendState& state) {
m_commandList->OMSetBlendFactor(state.blendFactor);
}
void D3D12CommandList::SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp) { void D3D12CommandList::SetDepthBias(float depthBias, float slopeScaledDepthBias, float depthBiasClamp) {
} }

View File

@@ -813,58 +813,10 @@ void OpenGLCommandList::SetPrimitiveTopology(PrimitiveTopology topology) {
m_primitiveType = ToGLPrimitiveTopology(topology); m_primitiveType = ToGLPrimitiveTopology(topology);
} }
void OpenGLCommandList::SetDepthStencilState(const DepthStencilState& state) {
if (state.depthEnable) {
glEnable(GL_DEPTH_TEST);
glDepthFunc(ToGLComparisonFunc(state.depthFunc));
glDepthMask(state.depthWriteMask ? GL_TRUE : GL_FALSE);
} else {
glDisable(GL_DEPTH_TEST);
}
if (state.stencilEnable) {
glEnable(GL_STENCIL_TEST);
glStencilMask(state.stencilWriteMask);
glStencilFunc(ToGLComparisonFunc(state.frontFace.stencilFunc), 0, state.stencilReadMask);
glStencilOp(
ToGLStencilOp(state.frontFace.stencilFailOp),
ToGLStencilOp(state.frontFace.stencilDepthFailOp),
ToGLStencilOp(state.frontFace.stencilPassOp)
);
} else {
glDisable(GL_STENCIL_TEST);
}
}
void OpenGLCommandList::SetStencilRef(uint8_t ref) { void OpenGLCommandList::SetStencilRef(uint8_t ref) {
glStencilFunc(GL_FRONT_AND_BACK, ref, 0xFF); glStencilFunc(GL_FRONT_AND_BACK, ref, 0xFF);
} }
void OpenGLCommandList::SetBlendState(const BlendState& state) {
if (state.alphaToCoverageEnable) {
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
} else {
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}
const auto& rt = state.renderTargets[0];
if (rt.blendEnable) {
glEnable(GL_BLEND);
glBlendFuncSeparate(
ToGLBlendFactor(rt.srcBlend),
ToGLBlendFactor(rt.dstBlend),
ToGLBlendFactor(rt.srcBlendAlpha),
ToGLBlendFactor(rt.dstBlendAlpha)
);
glBlendEquationSeparate(
ToGLBlendOp(rt.blendOp),
ToGLBlendOp(rt.blendOpAlpha)
);
} else {
glDisable(GL_BLEND);
}
}
void OpenGLCommandList::SetBlendFactor(const float factor[4]) { void OpenGLCommandList::SetBlendFactor(const float factor[4]) {
glBlendColor(factor[0], factor[1], factor[2], factor[3]); glBlendColor(factor[0], factor[1], factor[2], factor[3]);
} }

View File

@@ -147,36 +147,6 @@ TEST_F(OpenGLTestFixture, CommandList_SetPrimitiveTopology) {
EXPECT_EQ(error, GL_NO_ERROR); EXPECT_EQ(error, GL_NO_ERROR);
} }
TEST_F(OpenGLTestFixture, CommandList_SetDepthStencilState) {
OpenGLCommandList cmdList;
DepthStencilState state = {};
state.depthEnable = true;
state.depthWriteMask = true;
state.depthFunc = ComparisonFunc::Less;
cmdList.SetDepthStencilState(state);
GLint depthTest = 0;
glGetIntegerv(GL_DEPTH_TEST, &depthTest);
EXPECT_EQ(depthTest, 1);
}
TEST_F(OpenGLTestFixture, CommandList_SetBlendState) {
OpenGLCommandList cmdList;
BlendState state = {};
state.renderTargets[0].blendEnable = true;
state.renderTargets[0].srcBlend = BlendFactor::SrcAlpha;
state.renderTargets[0].dstBlend = BlendFactor::InvSrcAlpha;
cmdList.SetBlendState(state);
GLint blend = 0;
glGetIntegerv(GL_BLEND, &blend);
EXPECT_EQ(blend, 1);
}
TEST_F(OpenGLTestFixture, CommandList_SetBlendFactor) { TEST_F(OpenGLTestFixture, CommandList_SetBlendFactor) {
OpenGLCommandList cmdList; OpenGLCommandList cmdList;

View File

@@ -147,45 +147,6 @@ TEST_P(RHITestFixture, CommandList_ClearRenderTarget) {
delete cmdList; delete cmdList;
} }
TEST_P(RHITestFixture, CommandList_SetDepthStencilState) {
CommandListDesc cmdDesc = {};
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
ASSERT_NE(cmdList, nullptr);
DepthStencilState dsState = {};
dsState.depthEnable = true;
dsState.depthWriteMask = true;
dsState.depthFunc = ComparisonFunc::Less;
cmdList->Reset();
cmdList->SetDepthStencilState(dsState);
cmdList->Close();
cmdList->Shutdown();
delete cmdList;
}
TEST_P(RHITestFixture, CommandList_SetBlendState) {
CommandListDesc cmdDesc = {};
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
ASSERT_NE(cmdList, nullptr);
BlendState blendState = {};
blendState.alphaToCoverageEnable = false;
blendState.independentBlendEnable = false;
cmdList->Reset();
cmdList->SetBlendState(blendState);
cmdList->Close();
cmdList->Shutdown();
delete cmdList;
}
TEST_P(RHITestFixture, CommandList_SetStencilRef) { TEST_P(RHITestFixture, CommandList_SetStencilRef) {
CommandListDesc cmdDesc = {}; CommandListDesc cmdDesc = {};
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct); cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);