resources: support multi_compile_local shader keywords
This commit is contained in:
@@ -13,7 +13,8 @@ namespace Resources {
|
||||
enum class ShaderKeywordDeclarationType : Core::uint8 {
|
||||
MultiCompile = 0,
|
||||
ShaderFeature,
|
||||
ShaderFeatureLocal
|
||||
ShaderFeatureLocal,
|
||||
MultiCompileLocal = 3
|
||||
};
|
||||
|
||||
struct ShaderKeywordDeclaration {
|
||||
@@ -21,7 +22,8 @@ struct ShaderKeywordDeclaration {
|
||||
Containers::Array<Containers::String> options;
|
||||
|
||||
bool IsLocal() const {
|
||||
return type == ShaderKeywordDeclarationType::ShaderFeatureLocal;
|
||||
return type == ShaderKeywordDeclarationType::ShaderFeatureLocal ||
|
||||
type == ShaderKeywordDeclarationType::MultiCompileLocal;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -928,6 +928,7 @@ bool IsUnityStyleAuthoringPragmaDirective(const std::string& line) {
|
||||
pragmaTokens[1] == "fragment" ||
|
||||
pragmaTokens[1] == "target" ||
|
||||
pragmaTokens[1] == "multi_compile" ||
|
||||
pragmaTokens[1] == "multi_compile_local" ||
|
||||
pragmaTokens[1] == "shader_feature" ||
|
||||
pragmaTokens[1] == "shader_feature_local" ||
|
||||
pragmaTokens[1] == "backend";
|
||||
@@ -1037,6 +1038,8 @@ bool TryParseShaderKeywordDeclarationPragma(
|
||||
|
||||
if (pragmaTokens[1] == "multi_compile") {
|
||||
outDeclaration.type = ShaderKeywordDeclarationType::MultiCompile;
|
||||
} else if (pragmaTokens[1] == "multi_compile_local") {
|
||||
outDeclaration.type = ShaderKeywordDeclarationType::MultiCompileLocal;
|
||||
} else if (pragmaTokens[1] == "shader_feature") {
|
||||
outDeclaration.type = ShaderKeywordDeclarationType::ShaderFeature;
|
||||
} else if (pragmaTokens[1] == "shader_feature_local") {
|
||||
@@ -1550,6 +1553,7 @@ bool ParseLegacyBackendSplitShaderAuthoring(
|
||||
}
|
||||
if (pragmaTokens.size() >= 2u &&
|
||||
(pragmaTokens[1] == "multi_compile" ||
|
||||
pragmaTokens[1] == "multi_compile_local" ||
|
||||
pragmaTokens[1] == "shader_feature" ||
|
||||
pragmaTokens[1] == "shader_feature_local")) {
|
||||
ShaderKeywordDeclaration declaration = {};
|
||||
@@ -1842,6 +1846,7 @@ bool ParseUnityStyleSingleSourceShaderAuthoring(
|
||||
}
|
||||
if (pragmaTokens.size() >= 2u &&
|
||||
(pragmaTokens[1] == "multi_compile" ||
|
||||
pragmaTokens[1] == "multi_compile_local" ||
|
||||
pragmaTokens[1] == "shader_feature" ||
|
||||
pragmaTokens[1] == "shader_feature_local")) {
|
||||
ShaderKeywordDeclaration declaration = {};
|
||||
|
||||
@@ -478,7 +478,7 @@ TEST(ShaderLoader, LoadLegacyBackendSplitShaderAuthoringExpandsKeywordVariantsPe
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma multi_compile _ XC_MAIN_LIGHT_SHADOWS
|
||||
#pragma shader_feature_local _ XC_ALPHA_TEST
|
||||
#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
|
||||
@@ -501,7 +501,8 @@ TEST(ShaderLoader, LoadLegacyBackendSplitShaderAuthoringExpandsKeywordVariantsPe
|
||||
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::ShaderFeatureLocal);
|
||||
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);
|
||||
@@ -702,6 +703,68 @@ TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVar
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringParsesMultiCompileLocalKeywords) {
|
||||
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";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(shaderRoot);
|
||||
|
||||
WriteTextFile(
|
||||
shaderPath,
|
||||
R"(Shader "SingleSourceLocalKeywords"
|
||||
{
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
Name "ForwardLit"
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vert
|
||||
#pragma fragment Frag
|
||||
#pragma multi_compile_local _ XC_LOCAL_FOG
|
||||
float4 Vert() : SV_POSITION { return 0; }
|
||||
float4 Frag() : SV_TARGET { return 1; }
|
||||
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);
|
||||
|
||||
const ShaderPass* pass = shader->FindPass("ForwardLit");
|
||||
ASSERT_NE(pass, nullptr);
|
||||
ASSERT_EQ(pass->keywordDeclarations.Size(), 1u);
|
||||
EXPECT_EQ(pass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::MultiCompileLocal);
|
||||
EXPECT_TRUE(pass->keywordDeclarations[0].IsLocal());
|
||||
ASSERT_EQ(pass->variants.Size(), 4u);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_LOCAL_FOG");
|
||||
const ShaderStageVariant* keywordFragmentVariant =
|
||||
shader->FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::D3D12,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(keywordFragmentVariant, nullptr);
|
||||
EXPECT_NE(
|
||||
std::string(keywordFragmentVariant->sourceCode.CStr()).find("#define XC_LOCAL_FOG 1"),
|
||||
std::string::npos);
|
||||
|
||||
delete shader;
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringRejectsBackendPragma) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -1051,7 +1114,7 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromLegacyBackendSplitAutho
|
||||
#pragma vertex MainVS
|
||||
#pragma fragment MainPS
|
||||
#pragma multi_compile _ XC_MAIN_LIGHT_SHADOWS
|
||||
#pragma shader_feature_local _ XC_ALPHA_TEST
|
||||
#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
|
||||
}
|
||||
@@ -1080,6 +1143,9 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactFromLegacyBackendSplitAutho
|
||||
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 = {};
|
||||
|
||||
Reference in New Issue
Block a user