resources: remove legacy shader authoring path
This commit is contained in:
@@ -251,151 +251,6 @@ TEST(ShaderLoader, LoadShaderManifestBuildsMultiPassBackendVariants) {
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadLegacyBackendSplitShaderAuthoringBuildsRuntimeContract) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_test";
|
||||
const fs::path stageRoot = shaderRoot / "stages";
|
||||
const fs::path shaderPath = shaderRoot / "multi_pass.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(stageRoot);
|
||||
|
||||
WriteTextFile(stageRoot / "forward_lit.vs.hlsl", "float4 MainVS() : SV_POSITION { return 0; } // AUTHORING_FORWARD_LIT_D3D12_VS\n");
|
||||
WriteTextFile(stageRoot / "forward_lit.ps.hlsl", "float4 MainPS() : SV_TARGET { return 1; } // AUTHORING_FORWARD_LIT_D3D12_PS\n");
|
||||
WriteTextFile(stageRoot / "forward_lit.vert.glsl", "#version 430\n// AUTHORING_FORWARD_LIT_GL_VS\nvoid main() {}\n");
|
||||
WriteTextFile(stageRoot / "forward_lit.frag.glsl", "#version 430\n// AUTHORING_FORWARD_LIT_GL_PS\nvoid main() {}\n");
|
||||
WriteTextFile(stageRoot / "forward_lit.vert.vk.glsl", "#version 450\n// AUTHORING_FORWARD_LIT_VK_VS\nvoid main() {}\n");
|
||||
WriteTextFile(stageRoot / "forward_lit.frag.vk.glsl", "#version 450\n// AUTHORING_FORWARD_LIT_VK_PS\nvoid main() {}\n");
|
||||
WriteTextFile(stageRoot / "depth_only.vs.hlsl", "float4 MainVS() : SV_POSITION { return 0; } // AUTHORING_DEPTH_ONLY_D3D12_VS\n");
|
||||
WriteTextFile(stageRoot / "depth_only.ps.hlsl", "float4 MainPS() : SV_TARGET { return 1; } // AUTHORING_DEPTH_ONLY_D3D12_PS\n");
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "AuthoringLit"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_BaseColor ("Base Color", Color) = (1,1,1,1) [Semantic(BaseColor)]
|
||||
_MainTex ("Base Map", 2D) = "white" [Semantic(BaseColorTexture)]
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "Queue" = "Geometry" }
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
Resources
|
||||
{
|
||||
PerObjectConstants (ConstantBuffer, 1, 0) [Semantic(PerObject)]
|
||||
LightingConstants (ConstantBuffer, 2, 0) [Semantic(Lighting)]
|
||||
MaterialConstants (ConstantBuffer, 3, 0) [Semantic(Material)]
|
||||
ShadowReceiverConstants (ConstantBuffer, 4, 0) [Semantic(ShadowReceiver)]
|
||||
BaseColorTexture (Texture2D, 5, 0) [Semantic(BaseColorTexture)]
|
||||
LinearClampSampler (Sampler, 6, 0) [Semantic(LinearClampSampler)]
|
||||
ShadowMapTexture (Texture2D, 7, 0) [Semantic(ShadowMapTexture)]
|
||||
ShadowMapSampler (Sampler, 8, 0) [Semantic(ShadowMapSampler)]
|
||||
}
|
||||
HLSLPROGRAM
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma backend D3D12 HLSL "stages/forward_lit.vs.hlsl" "stages/forward_lit.ps.hlsl" vs_5_0 ps_5_0
|
||||
#pragma backend OpenGL GLSL "stages/forward_lit.vert.glsl" "stages/forward_lit.frag.glsl"
|
||||
#pragma backend Vulkan GLSL "stages/forward_lit.vert.vk.glsl" "stages/forward_lit.frag.vk.glsl"
|
||||
ENDHLSL
|
||||
}
|
||||
Pass
|
||||
{
|
||||
Name "DepthOnly"
|
||||
Tags { "LightMode" = "DepthOnly" }
|
||||
HLSLPROGRAM
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma backend D3D12 HLSL "stages/depth_only.vs.hlsl" "stages/depth_only.ps.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(shaderPath.string().c_str());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
Shader* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
ASSERT_TRUE(shader->IsValid());
|
||||
EXPECT_EQ(shader->GetName(), "AuthoringLit");
|
||||
ASSERT_EQ(shader->GetProperties().Size(), 2u);
|
||||
ASSERT_EQ(shader->GetPassCount(), 2u);
|
||||
|
||||
const ShaderPropertyDesc* baseColorProperty = shader->FindProperty("_BaseColor");
|
||||
ASSERT_NE(baseColorProperty, nullptr);
|
||||
EXPECT_EQ(baseColorProperty->displayName, "Base Color");
|
||||
EXPECT_EQ(baseColorProperty->type, ShaderPropertyType::Color);
|
||||
EXPECT_EQ(baseColorProperty->defaultValue, "(1,1,1,1)");
|
||||
EXPECT_EQ(baseColorProperty->semantic, "BaseColor");
|
||||
|
||||
const ShaderPropertyDesc* baseMapProperty = shader->FindProperty("_MainTex");
|
||||
ASSERT_NE(baseMapProperty, nullptr);
|
||||
EXPECT_EQ(baseMapProperty->type, ShaderPropertyType::Texture2D);
|
||||
EXPECT_EQ(baseMapProperty->defaultValue, "white");
|
||||
EXPECT_EQ(baseMapProperty->semantic, "BaseColorTexture");
|
||||
|
||||
const ShaderPass* forwardLitPass = shader->FindPass("ForwardLit");
|
||||
ASSERT_NE(forwardLitPass, nullptr);
|
||||
ASSERT_EQ(forwardLitPass->tags.Size(), 2u);
|
||||
ASSERT_EQ(forwardLitPass->resources.Size(), 8u);
|
||||
EXPECT_EQ(forwardLitPass->tags[0].name, "Queue");
|
||||
EXPECT_EQ(forwardLitPass->tags[0].value, "Geometry");
|
||||
EXPECT_EQ(forwardLitPass->tags[1].name, "LightMode");
|
||||
EXPECT_EQ(forwardLitPass->tags[1].value, "ForwardBase");
|
||||
|
||||
const ShaderResourceBindingDesc* baseTextureBinding =
|
||||
shader->FindPassResourceBinding("ForwardLit", "BaseColorTexture");
|
||||
ASSERT_NE(baseTextureBinding, nullptr);
|
||||
EXPECT_EQ(baseTextureBinding->type, ShaderResourceType::Texture2D);
|
||||
EXPECT_EQ(baseTextureBinding->set, 5u);
|
||||
EXPECT_EQ(baseTextureBinding->binding, 0u);
|
||||
EXPECT_EQ(baseTextureBinding->semantic, "BaseColorTexture");
|
||||
|
||||
const ShaderStageVariant* d3d12Vertex =
|
||||
shader->FindVariant("ForwardLit", ShaderType::Vertex, ShaderBackend::D3D12);
|
||||
ASSERT_NE(d3d12Vertex, nullptr);
|
||||
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
|
||||
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
|
||||
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("AUTHORING_FORWARD_LIT_D3D12_VS"), std::string::npos);
|
||||
|
||||
const ShaderStageVariant* openglFragment =
|
||||
shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::OpenGL);
|
||||
ASSERT_NE(openglFragment, nullptr);
|
||||
EXPECT_EQ(openglFragment->entryPoint, "main");
|
||||
EXPECT_EQ(openglFragment->profile, "fs_4_30");
|
||||
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("AUTHORING_FORWARD_LIT_GL_PS"), std::string::npos);
|
||||
|
||||
const ShaderStageVariant* vulkanFragment =
|
||||
shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::Vulkan);
|
||||
ASSERT_NE(vulkanFragment, nullptr);
|
||||
EXPECT_EQ(vulkanFragment->entryPoint, "main");
|
||||
EXPECT_EQ(vulkanFragment->profile, "fs_4_50");
|
||||
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("AUTHORING_FORWARD_LIT_VK_PS"), std::string::npos);
|
||||
|
||||
const ShaderPass* depthOnlyPass = shader->FindPass("DepthOnly");
|
||||
ASSERT_NE(depthOnlyPass, nullptr);
|
||||
ASSERT_EQ(depthOnlyPass->tags.Size(), 2u);
|
||||
EXPECT_EQ(depthOnlyPass->tags[0].name, "Queue");
|
||||
EXPECT_EQ(depthOnlyPass->tags[0].value, "Geometry");
|
||||
EXPECT_EQ(depthOnlyPass->tags[1].name, "LightMode");
|
||||
EXPECT_EQ(depthOnlyPass->tags[1].value, "DepthOnly");
|
||||
EXPECT_NE(shader->FindVariant("DepthOnly", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
|
||||
EXPECT_NE(shader->FindVariant("DepthOnly", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
|
||||
|
||||
delete shader;
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadShaderManifestParsesVariantKeywordsAndKeywordAwareLookup) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -456,137 +311,12 @@ TEST(ShaderLoader, LoadShaderManifestParsesVariantKeywordsAndKeywordAwareLookup)
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadLegacyBackendSplitShaderAuthoringExpandsKeywordVariantsPerBackend) {
|
||||
TEST(ShaderLoader, LoadShaderAuthoringBuildsGenericHlslVariants) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_legacy_keyword_variants";
|
||||
const fs::path stageRoot = shaderRoot / "stages";
|
||||
const fs::path shaderPath = shaderRoot / "keyword_variants.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(stageRoot);
|
||||
|
||||
WriteTextFile(
|
||||
stageRoot / "keyword_test.vs.hlsl",
|
||||
"float4 MainVS() : SV_POSITION { return 0; } // LEGACY_KEYWORD_D3D12_VS\n");
|
||||
WriteTextFile(
|
||||
stageRoot / "keyword_test.ps.hlsl",
|
||||
"float4 MainPS() : SV_TARGET { return 1; } // LEGACY_KEYWORD_D3D12_PS\n");
|
||||
WriteTextFile(
|
||||
stageRoot / "keyword_test.vert.glsl",
|
||||
"#version 430\n// LEGACY_KEYWORD_GL_VS\nvoid main() {}\n");
|
||||
WriteTextFile(
|
||||
stageRoot / "keyword_test.frag.glsl",
|
||||
"#version 430\n// LEGACY_KEYWORD_GL_PS\nvoid main() {}\n");
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "LegacyKeywordVariants"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
HLSLPROGRAM
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma multi_compile _ XC_MAIN_LIGHT_SHADOWS
|
||||
#pragma multi_compile_local _ XC_ALPHA_TEST
|
||||
#pragma backend D3D12 HLSL "stages/keyword_test.vs.hlsl" "stages/keyword_test.ps.hlsl" vs_5_0 ps_5_0
|
||||
#pragma backend OpenGL GLSL "stages/keyword_test.vert.glsl" "stages/keyword_test.frag.glsl"
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(shaderPath.string().c_str());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
auto* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
ASSERT_TRUE(shader->IsValid());
|
||||
EXPECT_EQ(shader->GetName(), "LegacyKeywordVariants");
|
||||
|
||||
const ShaderPass* pass = shader->FindPass("ForwardLit");
|
||||
ASSERT_NE(pass, nullptr);
|
||||
ASSERT_EQ(pass->keywordDeclarations.Size(), 2u);
|
||||
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::MultiCompile);
|
||||
EXPECT_EQ(pass->keywordDeclarations[1].type, ShaderKeywordDeclarationType::MultiCompileLocal);
|
||||
EXPECT_TRUE(pass->keywordDeclarations[1].IsLocal());
|
||||
EXPECT_TRUE(shader->PassDeclaresKeyword("ForwardLit", "XC_MAIN_LIGHT_SHADOWS"));
|
||||
EXPECT_TRUE(shader->PassDeclaresKeyword("ForwardLit", "XC_ALPHA_TEST"));
|
||||
ASSERT_EQ(pass->variants.Size(), 16u);
|
||||
|
||||
const ShaderStageVariant* baseD3D12Fragment =
|
||||
shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::D3D12);
|
||||
ASSERT_NE(baseD3D12Fragment, nullptr);
|
||||
EXPECT_EQ(baseD3D12Fragment->requiredKeywords.enabledKeywords.Size(), 0u);
|
||||
EXPECT_NE(
|
||||
std::string(baseD3D12Fragment->sourceCode.CStr()).find("LEGACY_KEYWORD_D3D12_PS"),
|
||||
std::string::npos);
|
||||
EXPECT_EQ(
|
||||
std::string(baseD3D12Fragment->sourceCode.CStr()).find("#define XC_MAIN_LIGHT_SHADOWS 1"),
|
||||
std::string::npos);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_MAIN_LIGHT_SHADOWS");
|
||||
|
||||
const ShaderStageVariant* keywordD3D12Fragment =
|
||||
shader->FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::D3D12,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(keywordD3D12Fragment, nullptr);
|
||||
ASSERT_EQ(keywordD3D12Fragment->requiredKeywords.enabledKeywords.Size(), 2u);
|
||||
EXPECT_EQ(keywordD3D12Fragment->requiredKeywords.enabledKeywords[0], "XC_ALPHA_TEST");
|
||||
EXPECT_EQ(keywordD3D12Fragment->requiredKeywords.enabledKeywords[1], "XC_MAIN_LIGHT_SHADOWS");
|
||||
EXPECT_NE(
|
||||
std::string(keywordD3D12Fragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
|
||||
std::string::npos);
|
||||
EXPECT_NE(
|
||||
std::string(keywordD3D12Fragment->sourceCode.CStr()).find("#define XC_MAIN_LIGHT_SHADOWS 1"),
|
||||
std::string::npos);
|
||||
EXPECT_NE(
|
||||
std::string(keywordD3D12Fragment->sourceCode.CStr()).find("LEGACY_KEYWORD_D3D12_PS"),
|
||||
std::string::npos);
|
||||
|
||||
const ShaderStageVariant* keywordOpenGLFragment =
|
||||
shader->FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::OpenGL,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(keywordOpenGLFragment, nullptr);
|
||||
EXPECT_EQ(keywordOpenGLFragment->entryPoint, "main");
|
||||
EXPECT_EQ(keywordOpenGLFragment->profile, "fs_4_30");
|
||||
const std::string keywordOpenGLSource = keywordOpenGLFragment->sourceCode.CStr();
|
||||
EXPECT_NE(
|
||||
keywordOpenGLSource.find("#define XC_ALPHA_TEST 1"),
|
||||
std::string::npos);
|
||||
EXPECT_NE(keywordOpenGLSource.find("#version 430"), std::string::npos);
|
||||
EXPECT_LT(
|
||||
keywordOpenGLSource.find("#version 430"),
|
||||
keywordOpenGLSource.find("#define XC_ALPHA_TEST 1"));
|
||||
EXPECT_NE(
|
||||
keywordOpenGLSource.find("LEGACY_KEYWORD_GL_PS"),
|
||||
std::string::npos);
|
||||
|
||||
delete shader;
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVariants) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_single_source_test";
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_test";
|
||||
const fs::path includeRoot = shaderRoot / "shaderlib";
|
||||
const fs::path shaderPath = shaderRoot / "single_source.shader";
|
||||
const fs::path shaderPath = shaderRoot / "authoring.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(includeRoot);
|
||||
@@ -599,7 +329,7 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "SingleSourceLit"
|
||||
R"(Shader "AuthoringLit"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
@@ -648,7 +378,7 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
|
||||
Shader* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
ASSERT_TRUE(shader->IsValid());
|
||||
EXPECT_EQ(shader->GetName(), "SingleSourceLit");
|
||||
EXPECT_EQ(shader->GetName(), "AuthoringLit");
|
||||
ASSERT_EQ(shader->GetProperties().Size(), 1u);
|
||||
ASSERT_EQ(shader->GetPassCount(), 1u);
|
||||
|
||||
@@ -724,18 +454,18 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesPassStateAndFallback) {
|
||||
TEST(ShaderLoader, LoadShaderAuthoringParsesPassStateAndFallback) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_single_source_pass_state";
|
||||
const fs::path shaderPath = shaderRoot / "single_source_state.shader";
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_pass_state";
|
||||
const fs::path shaderPath = shaderRoot / "authoring_state.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(shaderRoot);
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "SingleSourceStateful"
|
||||
R"(Shader "AuthoringStateful"
|
||||
{
|
||||
Fallback "Legacy/Diffuse"
|
||||
SubShader
|
||||
@@ -786,19 +516,19 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesPassStateAndFa
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPreservesPassStateAndFallback) {
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromAuthoringPreservesPassStateAndFallback) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_shader_single_source_artifact_pass_state";
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_shader_authoring_artifact_pass_state";
|
||||
const fs::path shaderDir = projectRoot / "Assets" / "Shaders";
|
||||
const fs::path shaderPath = shaderDir / "single_source_state.shader";
|
||||
const fs::path shaderPath = shaderDir / "authoring_state.shader";
|
||||
|
||||
fs::remove_all(projectRoot);
|
||||
fs::create_directories(shaderDir);
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "ArtifactSingleSourceStateful"
|
||||
R"(Shader "ArtifactAuthoringStateful"
|
||||
{
|
||||
Fallback "Legacy/Cutout"
|
||||
SubShader
|
||||
@@ -825,7 +555,7 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPr
|
||||
database.Initialize(projectRoot.string().c_str());
|
||||
|
||||
AssetDatabase::ResolvedAsset resolvedAsset;
|
||||
ASSERT_TRUE(database.EnsureArtifact("Assets/Shaders/single_source_state.shader", ResourceType::Shader, resolvedAsset));
|
||||
ASSERT_TRUE(database.EnsureArtifact("Assets/Shaders/authoring_state.shader", ResourceType::Shader, resolvedAsset));
|
||||
ASSERT_TRUE(resolvedAsset.artifactReady);
|
||||
|
||||
ShaderLoader loader;
|
||||
@@ -852,18 +582,18 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPr
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesMultiCompileLocalKeywords) {
|
||||
TEST(ShaderLoader, LoadShaderAuthoringParsesMultiCompileLocalKeywords) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_single_source_multi_compile_local";
|
||||
const fs::path shaderPath = shaderRoot / "single_source_multi_compile_local.shader";
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_multi_compile_local";
|
||||
const fs::path shaderPath = shaderRoot / "authoring_multi_compile_local.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(shaderRoot);
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "SingleSourceLocalKeywords"
|
||||
R"(Shader "AuthoringLocalKeywords"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
@@ -914,18 +644,18 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesMultiCompileLo
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesFallbackAndFixedFunctionStateInheritance) {
|
||||
TEST(ShaderLoader, LoadShaderAuthoringParsesFallbackAndFixedFunctionStateInheritance) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_single_source_fixed_state";
|
||||
const fs::path shaderPath = shaderRoot / "single_source_fixed_state.shader";
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_fixed_state";
|
||||
const fs::path shaderPath = shaderRoot / "authoring_fixed_state.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(shaderRoot);
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "SingleSourceFixedState"
|
||||
R"(Shader "AuthoringFixedState"
|
||||
{
|
||||
Fallback "Legacy Shaders/Diffuse"
|
||||
SubShader
|
||||
@@ -990,10 +720,10 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesFallbackAndFix
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringRejectsBackendPragma) {
|
||||
TEST(ShaderLoader, LoadShaderAuthoringRejectsLegacyBackendPragma) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_single_source_reject_backend";
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_reject_backend";
|
||||
const fs::path shaderPath = shaderRoot / "invalid_backend.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
@@ -1035,10 +765,10 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringRejectsBackendPragma
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringRejectsResourcesBlock) {
|
||||
TEST(ShaderLoader, LoadShaderAuthoringRejectsLegacyResourcesBlock) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_single_source_reject_resources";
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_reject_resources";
|
||||
const fs::path shaderPath = shaderRoot / "invalid_resources.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
@@ -1228,19 +958,19 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactAndLoaderReadsItBack) {
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPreservesKeywords) {
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromAuthoringPreservesKeywords) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_shader_single_source_artifact_keywords";
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_shader_authoring_artifact_keywords";
|
||||
const fs::path shaderDir = projectRoot / "Assets" / "Shaders";
|
||||
const fs::path shaderPath = shaderDir / "single_source.shader";
|
||||
const fs::path shaderPath = shaderDir / "authoring.shader";
|
||||
|
||||
fs::remove_all(projectRoot);
|
||||
fs::create_directories(shaderDir);
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "ArtifactSingleSourceKeywords"
|
||||
R"(Shader "ArtifactAuthoringKeywords"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
@@ -1265,7 +995,7 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPr
|
||||
database.Initialize(projectRoot.string().c_str());
|
||||
|
||||
AssetDatabase::ResolvedAsset resolvedAsset;
|
||||
ASSERT_TRUE(database.EnsureArtifact("Assets/Shaders/single_source.shader", ResourceType::Shader, resolvedAsset));
|
||||
ASSERT_TRUE(database.EnsureArtifact("Assets/Shaders/authoring.shader", ResourceType::Shader, resolvedAsset));
|
||||
ASSERT_TRUE(resolvedAsset.artifactReady);
|
||||
EXPECT_TRUE(fs::exists(resolvedAsset.artifactMainPath.CStr()));
|
||||
|
||||
@@ -1310,133 +1040,48 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromSingleSourceAuthoringPr
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromLegacyBackendSplitAuthoringPreservesKeywords) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_shader_legacy_keyword_artifact";
|
||||
const fs::path shaderDir = projectRoot / "Assets" / "Shaders";
|
||||
const fs::path stageDir = shaderDir / "stages";
|
||||
const fs::path shaderPath = shaderDir / "legacy_keywords.shader";
|
||||
|
||||
fs::remove_all(projectRoot);
|
||||
fs::create_directories(stageDir);
|
||||
|
||||
WriteTextFile(stageDir / "legacy_keywords.vs.hlsl", "float4 MainVS() : SV_POSITION { return 0; }\n");
|
||||
WriteTextFile(
|
||||
stageDir / "legacy_keywords.ps.hlsl",
|
||||
"float4 MainPS() : SV_TARGET { return float4(1.0, 0.0, 0.0, 1.0); } // LEGACY_ARTIFACT_PS\n");
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "LegacyArtifactKeywords"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
HLSLPROGRAM
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma multi_compile _ XC_MAIN_LIGHT_SHADOWS
|
||||
#pragma multi_compile_local _ XC_ALPHA_TEST
|
||||
#pragma backend D3D12 HLSL "stages/legacy_keywords.vs.hlsl" "stages/legacy_keywords.ps.hlsl" vs_5_0 ps_5_0
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
AssetDatabase database;
|
||||
database.Initialize(projectRoot.string().c_str());
|
||||
|
||||
AssetDatabase::ResolvedAsset resolvedAsset;
|
||||
ASSERT_TRUE(database.EnsureArtifact("Assets/Shaders/legacy_keywords.shader", ResourceType::Shader, resolvedAsset));
|
||||
ASSERT_TRUE(resolvedAsset.artifactReady);
|
||||
EXPECT_TRUE(fs::exists(resolvedAsset.artifactMainPath.CStr()));
|
||||
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(resolvedAsset.artifactMainPath.CStr());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
auto* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
ASSERT_TRUE(shader->DeclaresKeyword("XC_MAIN_LIGHT_SHADOWS"));
|
||||
ASSERT_TRUE(shader->DeclaresKeyword("XC_ALPHA_TEST"));
|
||||
|
||||
const ShaderPass* pass = shader->FindPass("ForwardLit");
|
||||
ASSERT_NE(pass, nullptr);
|
||||
ASSERT_EQ(pass->keywordDeclarations.Size(), 2u);
|
||||
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::MultiCompile);
|
||||
EXPECT_EQ(pass->keywordDeclarations[1].type, ShaderKeywordDeclarationType::MultiCompileLocal);
|
||||
EXPECT_TRUE(pass->keywordDeclarations[1].IsLocal());
|
||||
ASSERT_EQ(pass->variants.Size(), 8u);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_MAIN_LIGHT_SHADOWS");
|
||||
|
||||
const ShaderStageVariant* keywordFragmentVariant =
|
||||
shader->FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::D3D12,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(keywordFragmentVariant, nullptr);
|
||||
ASSERT_EQ(keywordFragmentVariant->requiredKeywords.enabledKeywords.Size(), 2u);
|
||||
EXPECT_NE(
|
||||
std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_MAIN_LIGHT_SHADOWS 1"),
|
||||
std::string::npos);
|
||||
EXPECT_NE(
|
||||
std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
|
||||
std::string::npos);
|
||||
EXPECT_NE(
|
||||
std::string(keywordFragmentVariant->sourceCode.CStr()).find("LEGACY_ARTIFACT_PS"),
|
||||
std::string::npos);
|
||||
|
||||
delete shader;
|
||||
database.Shutdown();
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromUnityLikeAuthoringAndTracksStageDependencies) {
|
||||
TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromAuthoringAndTracksIncludeDependencies) {
|
||||
namespace fs = std::filesystem;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_shader_authoring_artifact_test";
|
||||
const fs::path shaderDir = projectRoot / "Assets" / "Shaders";
|
||||
const fs::path stageDir = shaderDir / "stages";
|
||||
const fs::path includeDir = shaderDir / "shaderlib";
|
||||
const fs::path shaderPath = shaderDir / "lit.shader";
|
||||
const fs::path fragmentPath = stageDir / "lit.frag.glsl";
|
||||
const fs::path includePath = includeDir / "shared.hlsl";
|
||||
|
||||
fs::remove_all(projectRoot);
|
||||
fs::create_directories(stageDir);
|
||||
fs::create_directories(includeDir);
|
||||
|
||||
WriteTextFile(stageDir / "lit.vert.glsl", "#version 430\n// AUTHORING_ARTIFACT_GL_VS\nvoid main() {}\n");
|
||||
WriteTextFile(fragmentPath, "#version 430\n// AUTHORING_ARTIFACT_GL_PS\nvoid main() {}\n");
|
||||
WriteTextFile(includePath, "// AUTHORING_ARTIFACT_SHARED_INCLUDE\n");
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "ArtifactAuthoringShader"
|
||||
{
|
||||
Properties
|
||||
HLSLINCLUDE
|
||||
#include "shaderlib/shared.hlsl"
|
||||
struct VSInput
|
||||
{
|
||||
_MainTex ("Main Tex", 2D) = "white" [Semantic(BaseColorTexture)]
|
||||
}
|
||||
float3 positionOS : POSITION;
|
||||
};
|
||||
ENDHLSL
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
Resources
|
||||
{
|
||||
BaseColorTexture (Texture2D, 3, 0) [Semantic(BaseColorTexture)]
|
||||
}
|
||||
HLSLPROGRAM
|
||||
#pragma vertex main
|
||||
#pragma fragment main
|
||||
#pragma backend OpenGL GLSL "stages/lit.vert.glsl" "stages/lit.frag.glsl"
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
float4 Vert(VSInput input) : SV_POSITION
|
||||
{
|
||||
return float4(input.positionOS, 1.0);
|
||||
}
|
||||
float4 Frag() : SV_TARGET
|
||||
{
|
||||
return float4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
@@ -1460,9 +1105,11 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromUnityLikeAuthoringAndTr
|
||||
ASSERT_NE(firstShader, nullptr);
|
||||
EXPECT_EQ(firstShader->GetName(), "ArtifactAuthoringShader");
|
||||
const ShaderStageVariant* firstFragment =
|
||||
firstShader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::OpenGL);
|
||||
firstShader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::D3D12);
|
||||
ASSERT_NE(firstFragment, nullptr);
|
||||
EXPECT_NE(std::string(firstFragment->sourceCode.CStr()).find("AUTHORING_ARTIFACT_GL_PS"), std::string::npos);
|
||||
EXPECT_NE(
|
||||
std::string(firstFragment->sourceCode.CStr()).find("#include \"shaderlib/shared.hlsl\""),
|
||||
std::string::npos);
|
||||
delete firstShader;
|
||||
|
||||
const String firstArtifactPath = firstResolve.artifactMainPath;
|
||||
@@ -1470,10 +1117,10 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromUnityLikeAuthoringAndTr
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
{
|
||||
std::ofstream fragmentFile(fragmentPath, std::ios::app);
|
||||
ASSERT_TRUE(fragmentFile.is_open());
|
||||
fragmentFile << "\n// force authoring dependency reimport\n";
|
||||
ASSERT_TRUE(static_cast<bool>(fragmentFile));
|
||||
std::ofstream includeFile(includePath, std::ios::app);
|
||||
ASSERT_TRUE(includeFile.is_open());
|
||||
includeFile << "\n// force authoring dependency reimport\n";
|
||||
ASSERT_TRUE(static_cast<bool>(includeFile));
|
||||
}
|
||||
|
||||
database.Initialize(projectRoot.string().c_str());
|
||||
@@ -1547,7 +1194,7 @@ TEST(ShaderLoader, AssetDatabaseReimportsShaderWhenStageDependencyChanges) {
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinForwardLitShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
@@ -1722,7 +1369,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsUnityStyleSingleSourceVarian
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinUnlitShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
@@ -1800,7 +1447,7 @@ TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinObjectIdShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
@@ -1865,7 +1512,7 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsUnityStyleSingleSourceVariants
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinDepthOnlyShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
@@ -1991,7 +1638,7 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsUnityStyleSingleSourceVariant
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinShadowCasterShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
@@ -2117,7 +1764,7 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsUnityStyleSingleSourceVari
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinFinalColorShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinFinalColorShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinFinalColorShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
@@ -2200,7 +1847,7 @@ TEST(ShaderLoader, LoadBuiltinFinalColorShaderBuildsUnityStyleSingleSourceVarian
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadBuiltinColorScalePostProcessShaderBuildsUnityStyleSingleSourceVariants) {
|
||||
TEST(ShaderLoader, LoadBuiltinColorScalePostProcessShaderBuildsAuthoringVariants) {
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(GetBuiltinColorScalePostProcessShaderPath());
|
||||
ASSERT_TRUE(result);
|
||||
|
||||
Reference in New Issue
Block a user