Add GPU sorting for gaussian splat rendering
This commit is contained in:
@@ -1163,6 +1163,59 @@ TEST(BuiltinForwardPipeline_Test, BuiltinGaussianSplatUtilitiesShaderUsesCompute
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(BuiltinForwardPipeline_Test, BuiltinGaussianSplatBitonicSortShaderUsesComputeAuthoringContract) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinGaussianSplatUtilitiesShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
Shader* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
|
||||
const ShaderPass* pass = shader->FindPass("GaussianSplatBitonicSort");
|
||||
ASSERT_NE(pass, nullptr);
|
||||
EXPECT_EQ(pass->resources.Size(), 3u);
|
||||
|
||||
const ShaderResourceBindingDesc* perObject =
|
||||
shader->FindPassResourceBinding("GaussianSplatBitonicSort", "PerObjectConstants");
|
||||
ASSERT_NE(perObject, nullptr);
|
||||
EXPECT_EQ(perObject->type, ShaderResourceType::ConstantBuffer);
|
||||
EXPECT_EQ(perObject->set, 0u);
|
||||
EXPECT_EQ(perObject->binding, 0u);
|
||||
EXPECT_EQ(
|
||||
ResolveBuiltinPassResourceSemantic(*perObject),
|
||||
BuiltinPassResourceSemantic::PerObject);
|
||||
|
||||
const ShaderResourceBindingDesc* sortDistances =
|
||||
shader->FindPassResourceBinding("GaussianSplatBitonicSort", "GaussianSplatSortDistances");
|
||||
ASSERT_NE(sortDistances, nullptr);
|
||||
EXPECT_EQ(sortDistances->type, ShaderResourceType::RWStructuredBuffer);
|
||||
EXPECT_EQ(sortDistances->set, 4u);
|
||||
EXPECT_EQ(sortDistances->binding, 0u);
|
||||
EXPECT_EQ(
|
||||
ResolveBuiltinPassResourceSemantic(*sortDistances),
|
||||
BuiltinPassResourceSemantic::GaussianSplatSortDistanceBuffer);
|
||||
|
||||
const ShaderResourceBindingDesc* orderBuffer =
|
||||
shader->FindPassResourceBinding("GaussianSplatBitonicSort", "GaussianSplatOrderBuffer");
|
||||
ASSERT_NE(orderBuffer, nullptr);
|
||||
EXPECT_EQ(orderBuffer->type, ShaderResourceType::RWStructuredBuffer);
|
||||
EXPECT_EQ(orderBuffer->set, 4u);
|
||||
EXPECT_EQ(orderBuffer->binding, 1u);
|
||||
EXPECT_EQ(
|
||||
ResolveBuiltinPassResourceSemantic(*orderBuffer),
|
||||
BuiltinPassResourceSemantic::GaussianSplatOrderBuffer);
|
||||
|
||||
const ShaderStageVariant* computeVariant = shader->FindVariant(
|
||||
"GaussianSplatBitonicSort",
|
||||
XCEngine::Resources::ShaderType::Compute,
|
||||
XCEngine::Resources::ShaderBackend::D3D12);
|
||||
ASSERT_NE(computeVariant, nullptr);
|
||||
EXPECT_EQ(computeVariant->entryPoint, "GaussianSplatBitonicSortCS");
|
||||
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedGaussianSplatUtilitiesShaderContract) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinGaussianSplatUtilitiesShaderPath());
|
||||
@@ -1253,6 +1306,52 @@ TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoaded
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedGaussianSplatBitonicSortContract) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinGaussianSplatUtilitiesShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
Shader* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
|
||||
const ShaderPass* pass = shader->FindPass("GaussianSplatBitonicSort");
|
||||
ASSERT_NE(pass, nullptr);
|
||||
|
||||
BuiltinPassResourceBindingPlan plan = {};
|
||||
String error;
|
||||
EXPECT_TRUE(TryBuildBuiltinPassResourceBindingPlan(*pass, plan, &error)) << error.CStr();
|
||||
ASSERT_EQ(plan.bindings.Size(), 3u);
|
||||
EXPECT_TRUE(plan.perObject.IsValid());
|
||||
EXPECT_TRUE(plan.gaussianSplatSortDistanceBuffer.IsValid());
|
||||
EXPECT_TRUE(plan.gaussianSplatOrderBuffer.IsValid());
|
||||
EXPECT_FALSE(plan.gaussianSplatViewDataBuffer.IsValid());
|
||||
EXPECT_EQ(plan.perObject.set, 0u);
|
||||
EXPECT_EQ(plan.gaussianSplatSortDistanceBuffer.set, 4u);
|
||||
EXPECT_EQ(plan.gaussianSplatSortDistanceBuffer.binding, 0u);
|
||||
EXPECT_EQ(plan.gaussianSplatOrderBuffer.set, 4u);
|
||||
EXPECT_EQ(plan.gaussianSplatOrderBuffer.binding, 1u);
|
||||
EXPECT_EQ(plan.firstDescriptorSet, 0u);
|
||||
EXPECT_EQ(plan.descriptorSetCount, 5u);
|
||||
|
||||
std::vector<BuiltinPassSetLayoutMetadata> setLayouts;
|
||||
ASSERT_TRUE(TryBuildBuiltinPassSetLayouts(plan, setLayouts, &error)) << error.CStr();
|
||||
ASSERT_EQ(setLayouts.size(), 5u);
|
||||
EXPECT_TRUE(setLayouts[0].usesPerObject);
|
||||
EXPECT_TRUE(setLayouts[4].usesGaussianSplatSortDistanceBuffer);
|
||||
EXPECT_TRUE(setLayouts[4].usesGaussianSplatOrderBuffer);
|
||||
EXPECT_FALSE(setLayouts[4].usesGaussianSplatViewDataBuffer);
|
||||
ASSERT_EQ(setLayouts[4].bindings.size(), 2u);
|
||||
EXPECT_EQ(
|
||||
static_cast<DescriptorType>(setLayouts[4].bindings[0].type),
|
||||
DescriptorType::UAV);
|
||||
EXPECT_EQ(
|
||||
static_cast<DescriptorType>(setLayouts[4].bindings[1].type),
|
||||
DescriptorType::UAV);
|
||||
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(BuiltinForwardPipeline_Test, OpenGLPipelineLayoutUsesUnifiedStorageBufferBindingsForGaussianSplatUtilities) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinGaussianSplatUtilitiesShaderPath());
|
||||
|
||||
Reference in New Issue
Block a user