fix(rhi): make opengl descriptor binding set-aware
This commit is contained in:
@@ -122,10 +122,10 @@ MatrixBufferData CreateMatrixBufferData() {
|
||||
}
|
||||
|
||||
const char kSphereHlsl[] = R"(
|
||||
Texture2D gDiffuseTexture : register(t0);
|
||||
SamplerState gSampler : register(s0);
|
||||
Texture2D gDiffuseTexture : register(t1);
|
||||
SamplerState gSampler : register(s1);
|
||||
|
||||
cbuffer MatrixBuffer : register(b0) {
|
||||
cbuffer MatrixBuffer : register(b1) {
|
||||
float4x4 gProjectionMatrix;
|
||||
float4x4 gViewMatrix;
|
||||
float4x4 gModelMatrix;
|
||||
@@ -159,7 +159,7 @@ const char kSphereVertexShader[] = R"(#version 430
|
||||
layout(location = 0) in vec4 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
|
||||
layout(std140, binding = 0) uniform MatrixBuffer {
|
||||
layout(std140, binding = 1) uniform MatrixBuffer {
|
||||
mat4 gProjectionMatrix;
|
||||
mat4 gViewMatrix;
|
||||
mat4 gModelMatrix;
|
||||
@@ -176,7 +176,7 @@ void main() {
|
||||
)";
|
||||
|
||||
const char kSphereFragmentShader[] = R"(#version 430
|
||||
layout(binding = 0) uniform sampler2D uTexture;
|
||||
layout(binding = 1) uniform sampler2D uTexture;
|
||||
|
||||
in vec2 vTexCoord;
|
||||
|
||||
@@ -454,8 +454,24 @@ void SphereTest::InitializeSphereResources() {
|
||||
ASSERT_NE(mSamplerSet, nullptr);
|
||||
mSamplerSet->UpdateSampler(0, mSampler);
|
||||
|
||||
DescriptorSetLayoutBinding reservedSetBindings[3] = {};
|
||||
reservedSetBindings[0].binding = 0;
|
||||
reservedSetBindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||
reservedSetBindings[0].count = 1;
|
||||
reservedSetBindings[1].binding = 0;
|
||||
reservedSetBindings[1].type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||
reservedSetBindings[1].count = 1;
|
||||
reservedSetBindings[2].binding = 0;
|
||||
reservedSetBindings[2].type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||
reservedSetBindings[2].count = 1;
|
||||
|
||||
DescriptorSetLayoutDesc reservedLayoutDesc = {};
|
||||
reservedLayoutDesc.bindings = reservedSetBindings;
|
||||
reservedLayoutDesc.bindingCount = 3;
|
||||
|
||||
DescriptorSetLayoutDesc setLayouts[kSphereDescriptorSetCount] = {};
|
||||
// Reserve set0 so the integration test exercises non-zero firstSet binding.
|
||||
// Reserve slot0 so the bound sets land on binding point 1 for every descriptor class.
|
||||
setLayouts[0] = reservedLayoutDesc;
|
||||
setLayouts[1] = constantLayoutDesc;
|
||||
setLayouts[2] = textureLayoutDesc;
|
||||
setLayouts[3] = samplerLayoutDesc;
|
||||
|
||||
@@ -362,3 +362,59 @@ TEST_P(RHITestFixture, PipelineLayout_D3D12SeparatesOverlappingBindingsAcrossSet
|
||||
layout->Shutdown();
|
||||
delete layout;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, PipelineLayout_OpenGLSeparatesOverlappingBindingsAcrossSetSlots) {
|
||||
if (GetBackendType() != RHIType::OpenGL) {
|
||||
GTEST_SKIP() << "OpenGL-specific binding point verification";
|
||||
}
|
||||
|
||||
DescriptorSetLayoutBinding set0Bindings[3] = {};
|
||||
set0Bindings[0].binding = 0;
|
||||
set0Bindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||
set0Bindings[0].count = 1;
|
||||
set0Bindings[1].binding = 0;
|
||||
set0Bindings[1].type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||
set0Bindings[1].count = 1;
|
||||
set0Bindings[2].binding = 0;
|
||||
set0Bindings[2].type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||
set0Bindings[2].count = 1;
|
||||
|
||||
DescriptorSetLayoutBinding set1Bindings[3] = {};
|
||||
set1Bindings[0].binding = 0;
|
||||
set1Bindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||
set1Bindings[0].count = 1;
|
||||
set1Bindings[1].binding = 0;
|
||||
set1Bindings[1].type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||
set1Bindings[1].count = 1;
|
||||
set1Bindings[2].binding = 0;
|
||||
set1Bindings[2].type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||
set1Bindings[2].count = 1;
|
||||
|
||||
DescriptorSetLayoutDesc setLayouts[2] = {};
|
||||
setLayouts[0].bindings = set0Bindings;
|
||||
setLayouts[0].bindingCount = 3;
|
||||
setLayouts[1].bindings = set1Bindings;
|
||||
setLayouts[1].bindingCount = 3;
|
||||
|
||||
RHIPipelineLayoutDesc desc = {};
|
||||
desc.setLayouts = setLayouts;
|
||||
desc.setLayoutCount = 2;
|
||||
|
||||
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||
ASSERT_NE(layout, nullptr);
|
||||
|
||||
auto* openGLLayout = static_cast<OpenGLPipelineLayout*>(layout);
|
||||
EXPECT_TRUE(openGLLayout->UsesSetLayouts());
|
||||
EXPECT_EQ(openGLLayout->GetSetLayoutCount(), 2u);
|
||||
EXPECT_TRUE(openGLLayout->HasConstantBufferBinding(0, 0));
|
||||
EXPECT_TRUE(openGLLayout->HasConstantBufferBinding(1, 0));
|
||||
EXPECT_EQ(openGLLayout->GetConstantBufferBindingPoint(0, 0), 0u);
|
||||
EXPECT_EQ(openGLLayout->GetConstantBufferBindingPoint(1, 0), 1u);
|
||||
EXPECT_EQ(openGLLayout->GetShaderResourceBindingPoint(0, 0), 0u);
|
||||
EXPECT_EQ(openGLLayout->GetShaderResourceBindingPoint(1, 0), 1u);
|
||||
EXPECT_EQ(openGLLayout->GetSamplerBindingPoint(0, 0), 0u);
|
||||
EXPECT_EQ(openGLLayout->GetSamplerBindingPoint(1, 0), 1u);
|
||||
|
||||
layout->Shutdown();
|
||||
delete layout;
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ tests/RHI/integration/
|
||||
5. 两个后端都必须与同一张 `GT.ppm` 做比对。
|
||||
6. 新测试如果暴露抽象层缺口,应先补 RHI,再补测试。
|
||||
7. 至少保留一个场景覆盖 `firstSet != 0` 的描述符绑定路径,当前由 `sphere` 负责验证。
|
||||
8. `sphere` 需要通过预留 `set0` 把实际 shader 绑定点推进到 `binding = 1`,避免出现“忽略 set 语义也能误通过”的假阳性。
|
||||
|
||||
### 6.3 命名
|
||||
|
||||
|
||||
Reference in New Issue
Block a user