rendering: add keyword-aware shader variant selection
This commit is contained in:
@@ -382,6 +382,66 @@ TEST(ShaderLoader, LoadLegacyBackendSplitShaderAuthoringBuildsRuntimeContract) {
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadShaderManifestParsesVariantKeywordsAndKeywordAwareLookup) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_manifest_variant_keywords";
|
||||
const fs::path manifestPath = shaderRoot / "variant_keywords.shader";
|
||||
|
||||
fs::remove_all(shaderRoot);
|
||||
fs::create_directories(shaderRoot);
|
||||
|
||||
{
|
||||
std::ofstream manifest(manifestPath);
|
||||
ASSERT_TRUE(manifest.is_open());
|
||||
manifest << "{\n";
|
||||
manifest << " \"name\": \"VariantKeywordShader\",\n";
|
||||
manifest << " \"passes\": [\n";
|
||||
manifest << " {\n";
|
||||
manifest << " \"name\": \"ForwardLit\",\n";
|
||||
manifest << " \"variants\": [\n";
|
||||
manifest << " { \"stage\": \"Vertex\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"sourceCode\": \"#version 430\\nvoid main() {}\\n\" },\n";
|
||||
manifest << " { \"stage\": \"Fragment\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"sourceCode\": \"#version 430\\n// BASE_FRAGMENT\\nvoid main() {}\\n\" },\n";
|
||||
manifest << " { \"stage\": \"Fragment\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"keywords\": [\"XC_ALPHA_TEST\", \"_\", \"XC_FOG\", \"XC_ALPHA_TEST\"], \"sourceCode\": \"#version 430\\n// KEYWORD_FRAGMENT\\nvoid main() {}\\n\" }\n";
|
||||
manifest << " ]\n";
|
||||
manifest << " }\n";
|
||||
manifest << " ]\n";
|
||||
manifest << "}\n";
|
||||
}
|
||||
|
||||
ShaderLoader loader;
|
||||
LoadResult result = loader.Load(manifestPath.string().c_str());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
Shader* shader = static_cast<Shader*>(result.resource);
|
||||
ASSERT_NE(shader, nullptr);
|
||||
|
||||
const ShaderStageVariant* baseFragment =
|
||||
shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::OpenGL);
|
||||
ASSERT_NE(baseFragment, nullptr);
|
||||
EXPECT_NE(std::string(baseFragment->sourceCode.CStr()).find("BASE_FRAGMENT"), std::string::npos);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_FOG");
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
|
||||
const ShaderStageVariant* keywordFragment =
|
||||
shader->FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::OpenGL,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(keywordFragment, nullptr);
|
||||
EXPECT_NE(std::string(keywordFragment->sourceCode.CStr()).find("KEYWORD_FRAGMENT"), std::string::npos);
|
||||
ASSERT_EQ(keywordFragment->requiredKeywords.enabledKeywords.Size(), 2u);
|
||||
EXPECT_EQ(keywordFragment->requiredKeywords.enabledKeywords[0], "XC_ALPHA_TEST");
|
||||
EXPECT_EQ(keywordFragment->requiredKeywords.enabledKeywords[1], "XC_FOG");
|
||||
|
||||
delete shader;
|
||||
fs::remove_all(shaderRoot);
|
||||
}
|
||||
|
||||
TEST(ShaderLoader, LoadUnityStyleSingleSourceShaderAuthoringBuildsGenericHlslVariants) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -680,7 +740,8 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactAndLoaderReadsItBack) {
|
||||
manifest << " ],\n";
|
||||
manifest << " \"variants\": [\n";
|
||||
manifest << " { \"stage\": \"Vertex\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"source\": \"lit.vert.glsl\" },\n";
|
||||
manifest << " { \"stage\": \"Fragment\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"source\": \"lit.frag.glsl\" }\n";
|
||||
manifest << " { \"stage\": \"Fragment\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"source\": \"lit.frag.glsl\" },\n";
|
||||
manifest << " { \"stage\": \"Fragment\", \"backend\": \"OpenGL\", \"language\": \"GLSL\", \"keywords\": [\"XC_ALPHA_TEST\", \"XC_FOG\"], \"sourceCode\": \"#version 430\\n// ARTIFACT_GL_PS_KEYWORD\\nvoid main() {}\\n\" }\n";
|
||||
manifest << " ]\n";
|
||||
manifest << " }\n";
|
||||
manifest << " ]\n";
|
||||
@@ -711,7 +772,7 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactAndLoaderReadsItBack) {
|
||||
|
||||
const ShaderPass* pass = shader->FindPass("ForwardLit");
|
||||
ASSERT_NE(pass, nullptr);
|
||||
ASSERT_EQ(pass->variants.Size(), 2u);
|
||||
ASSERT_EQ(pass->variants.Size(), 3u);
|
||||
ASSERT_EQ(pass->resources.Size(), 1u);
|
||||
|
||||
const ShaderStageVariant* fragmentVariant =
|
||||
@@ -719,6 +780,22 @@ TEST(ShaderLoader, AssetDatabaseCreatesShaderArtifactAndLoaderReadsItBack) {
|
||||
ASSERT_NE(fragmentVariant, nullptr);
|
||||
EXPECT_NE(std::string(fragmentVariant->sourceCode.CStr()).find("ARTIFACT_GL_PS"), std::string::npos);
|
||||
|
||||
ShaderKeywordSet enabledKeywords = {};
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_FOG");
|
||||
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
|
||||
|
||||
const ShaderStageVariant* keywordVariant =
|
||||
shader->FindVariant(
|
||||
"ForwardLit",
|
||||
ShaderType::Fragment,
|
||||
ShaderBackend::OpenGL,
|
||||
enabledKeywords);
|
||||
ASSERT_NE(keywordVariant, nullptr);
|
||||
EXPECT_NE(std::string(keywordVariant->sourceCode.CStr()).find("ARTIFACT_GL_PS_KEYWORD"), std::string::npos);
|
||||
ASSERT_EQ(keywordVariant->requiredKeywords.enabledKeywords.Size(), 2u);
|
||||
EXPECT_EQ(keywordVariant->requiredKeywords.enabledKeywords[0], "XC_ALPHA_TEST");
|
||||
EXPECT_EQ(keywordVariant->requiredKeywords.enabledKeywords[1], "XC_FOG");
|
||||
|
||||
delete shader;
|
||||
database.Shutdown();
|
||||
fs::remove_all(projectRoot);
|
||||
|
||||
Reference in New Issue
Block a user