Sync editor rendering and UI workspace updates

This commit is contained in:
2026-04-09 02:59:36 +08:00
parent 23b23a56be
commit d46bf87970
107 changed files with 10918 additions and 430 deletions

View File

@@ -676,6 +676,78 @@ TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoaded
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuiltinVolumetricShaderUsesAuthoringContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinVolumetricShaderPath());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
Shader* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
const ShaderPass* pass = shader->FindPass("Volumetric");
ASSERT_NE(pass, nullptr);
EXPECT_EQ(pass->resources.Size(), 3u);
EXPECT_TRUE(pass->hasFixedFunctionState);
EXPECT_EQ(pass->fixedFunctionState.cullMode, MaterialCullMode::None);
EXPECT_FALSE(pass->fixedFunctionState.depthWriteEnable);
EXPECT_EQ(pass->fixedFunctionState.depthFunc, MaterialComparisonFunc::LessEqual);
EXPECT_TRUE(pass->fixedFunctionState.blendEnable);
const ShaderResourceBindingDesc* volumeData =
shader->FindPassResourceBinding("Volumetric", "VolumeData");
ASSERT_NE(volumeData, nullptr);
EXPECT_EQ(volumeData->type, ShaderResourceType::StructuredBuffer);
EXPECT_EQ(volumeData->set, 2u);
EXPECT_EQ(volumeData->binding, 0u);
EXPECT_EQ(
ResolveBuiltinPassResourceSemantic(*volumeData),
BuiltinPassResourceSemantic::VolumeField);
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuildsBuiltinPassResourceBindingPlanFromLoadedVolumetricShaderContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinVolumetricShaderPath());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
Shader* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
const ShaderPass* pass = shader->FindPass("Volumetric");
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.material.IsValid());
EXPECT_TRUE(plan.volumeField.IsValid());
EXPECT_EQ(plan.perObject.set, 0u);
EXPECT_EQ(plan.material.set, 1u);
EXPECT_EQ(plan.volumeField.set, 2u);
EXPECT_EQ(plan.volumeField.binding, 0u);
std::vector<BuiltinPassSetLayoutMetadata> setLayouts;
ASSERT_TRUE(TryBuildBuiltinPassSetLayouts(plan, setLayouts, &error)) << error.CStr();
ASSERT_EQ(setLayouts.size(), 3u);
EXPECT_TRUE(setLayouts[0].usesPerObject);
EXPECT_TRUE(setLayouts[1].usesMaterial);
EXPECT_TRUE(setLayouts[2].usesVolumeField);
ASSERT_EQ(setLayouts[2].bindings.size(), 1u);
EXPECT_EQ(
static_cast<DescriptorType>(setLayouts[2].bindings[0].type),
DescriptorType::SRV);
EXPECT_EQ(
setLayouts[2].bindings[0].resourceDimension,
ResourceViewDimension::StructuredBuffer);
delete shader;
}
TEST(BuiltinForwardPipeline_Test, BuiltinFinalColorShaderUsesAuthoringContract) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinFinalColorShaderPath());
@@ -867,6 +939,77 @@ TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringFinal
delete shader;
}
TEST(BuiltinForwardPipeline_Test, VulkanRuntimeCompileDescRewritesAuthoringVolumetricBindingsToDescriptorSpaces) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinVolumetricShaderPath());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
Shader* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
const ShaderPass* pass = shader->FindPass("Volumetric");
ASSERT_NE(pass, nullptr);
const ShaderStageVariant* d3d12Fragment = shader->FindVariant(
"Volumetric",
XCEngine::Resources::ShaderType::Fragment,
XCEngine::Resources::ShaderBackend::D3D12);
ASSERT_NE(d3d12Fragment, nullptr);
ShaderCompileDesc d3d12CompileDesc = {};
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
*pass,
XCEngine::Resources::ShaderBackend::D3D12,
*d3d12Fragment,
d3d12CompileDesc);
const std::string d3d12Source(
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
d3d12CompileDesc.source.size());
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"cbuffer PerObjectConstants",
"register(b0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"cbuffer MaterialConstants",
"register(b1)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
d3d12Source,
"StructuredBuffer<uint> VolumeData",
"register(t0)"));
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
"Volumetric",
XCEngine::Resources::ShaderType::Fragment,
XCEngine::Resources::ShaderBackend::Vulkan);
ASSERT_NE(vulkanFragment, nullptr);
ShaderCompileDesc vulkanCompileDesc = {};
::XCEngine::Rendering::Detail::ApplyShaderStageVariant(
*pass,
XCEngine::Resources::ShaderBackend::Vulkan,
*vulkanFragment,
vulkanCompileDesc);
const std::string vulkanSource(
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
vulkanCompileDesc.source.size());
EXPECT_TRUE(SourceContainsRegisterBinding(
vulkanSource,
"cbuffer PerObjectConstants",
"register(b0, space0)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
vulkanSource,
"cbuffer MaterialConstants",
"register(b0, space1)"));
EXPECT_TRUE(SourceContainsRegisterBinding(
vulkanSource,
"StructuredBuffer<uint> VolumeData",
"register(t0, space2)"));
delete shader;
}
TEST(BuiltinForwardPipeline_Test, OpenGLRuntimeTranspilesFinalColorVariantToCombinedSourceSampler) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinFinalColorShaderPath());