Support compute-only shader authoring variants

This commit is contained in:
2026-04-11 00:24:55 +08:00
parent 107b320aa7
commit be5dabd820
5 changed files with 226 additions and 46 deletions

View File

@@ -298,6 +298,10 @@ bool ParseShaderAuthoring(
currentPass->fragmentEntryPoint = pragmaTokens[2].c_str();
continue;
}
if (pragmaTokens.size() >= 3u && pragmaTokens[1] == "compute") {
currentPass->computeEntryPoint = pragmaTokens[2].c_str();
continue;
}
if (pragmaTokens.size() >= 3u && pragmaTokens[1] == "target") {
currentPass->targetProfile = pragmaTokens[2].c_str();
continue;
@@ -591,10 +595,19 @@ bool ParseShaderAuthoring(
if (pass.programSource.Empty()) {
return fail("a Pass is missing an HLSLPROGRAM block", 0);
}
if (pass.vertexEntryPoint.Empty()) {
const bool hasCompute = !pass.computeEntryPoint.Empty();
const bool hasVertex = !pass.vertexEntryPoint.Empty();
const bool hasFragment = !pass.fragmentEntryPoint.Empty();
if (hasCompute && (hasVertex || hasFragment)) {
return fail("a Pass must not mix #pragma compute with graphics stage pragmas", 0);
}
if (hasCompute) {
continue;
}
if (!hasVertex) {
return fail("a Pass is missing a #pragma vertex directive", 0);
}
if (pass.fragmentEntryPoint.Empty()) {
if (!hasFragment) {
return fail("a Pass is missing a #pragma fragment directive", 0);
}
}

View File

@@ -87,6 +87,7 @@ bool IsShaderAuthoringPragmaDirective(const std::string& line) {
return pragmaTokens[1] == "vertex" ||
pragmaTokens[1] == "fragment" ||
pragmaTokens[1] == "compute" ||
pragmaTokens[1] == "target" ||
pragmaTokens[1] == "multi_compile" ||
pragmaTokens[1] == "multi_compile_local" ||

View File

@@ -362,6 +362,25 @@ ShaderPass BuildConcretePass(
const Containers::String variantSource =
BuildKeywordVariantSource(strippedCombinedSource, keywordSet);
if (!pass.computeEntryPoint.Empty()) {
ShaderStageVariant computeVariant = {};
computeVariant.stage = ShaderType::Compute;
computeVariant.backend = ShaderBackend::Generic;
computeVariant.language = ShaderLanguage::HLSL;
computeVariant.requiredKeywords = keywordSet;
computeVariant.entryPoint =
!pass.computeEntryPoint.Empty()
? pass.computeEntryPoint
: GetDefaultEntryPoint(ShaderLanguage::HLSL, ShaderType::Compute);
computeVariant.profile = GetDefaultProfile(
ShaderLanguage::HLSL,
ShaderBackend::Generic,
ShaderType::Compute);
computeVariant.sourceCode = variantSource;
shaderPass.variants.PushBack(computeVariant);
continue;
}
ShaderStageVariant vertexVariant = {};
vertexVariant.stage = ShaderType::Vertex;
vertexVariant.backend = ShaderBackend::Generic;
@@ -535,12 +554,12 @@ Containers::String GetDefaultProfile(
ShaderType stage) {
if (language == ShaderLanguage::HLSL) {
switch (stage) {
case ShaderType::Vertex: return "vs_5_0";
case ShaderType::Fragment: return "ps_5_0";
case ShaderType::Geometry: return "gs_5_0";
case ShaderType::Compute: return "cs_5_0";
case ShaderType::Hull: return "hs_5_0";
case ShaderType::Domain: return "ds_5_0";
case ShaderType::Vertex: return "vs_5_1";
case ShaderType::Fragment: return "ps_5_1";
case ShaderType::Geometry: return "gs_5_1";
case ShaderType::Compute: return "cs_5_1";
case ShaderType::Hull: return "hs_5_1";
case ShaderType::Domain: return "ds_5_1";
default: return Containers::String();
}
}

View File

@@ -26,6 +26,7 @@ struct ShaderPassIR {
Containers::Array<ShaderKeywordDeclaration> keywordDeclarations;
Containers::String vertexEntryPoint;
Containers::String fragmentEntryPoint;
Containers::String computeEntryPoint;
Containers::String sharedProgramSource;
Containers::String programSource;
Containers::String targetProfile;

View File

@@ -6,7 +6,7 @@
#include <XCEngine/Resources/Shader/ShaderLoader.h>
#include <XCEngine/Core/Asset/ResourceTypes.h>
#include <XCEngine/Core/Containers/Array.h>
#include "Rendering/Detail/ShaderVariantUtils.h"
#include "Rendering/Internal/ShaderVariantUtils.h"
#include <chrono>
#include <cstring>
@@ -237,18 +237,18 @@ TEST(ShaderLoader, LoadShaderAuthoringBuildsMultiPassGenericVariants) {
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_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("FORWARD_LIT_GENERIC_VS"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::OpenGL);
ASSERT_NE(openglFragment, nullptr);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("FORWARD_LIT_GENERIC_PS"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant("ForwardLit", ShaderType::Fragment, ShaderBackend::Vulkan);
ASSERT_NE(vulkanFragment, nullptr);
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("FORWARD_LIT_GENERIC_PS"), std::string::npos);
const ShaderPass* depthOnlyPass = shader->FindPass("DepthOnly");
@@ -457,7 +457,7 @@ TEST(ShaderLoader, LoadShaderAuthoringBuildsGenericHlslVariants) {
EXPECT_EQ(vertexVariant->backend, ShaderBackend::Generic);
EXPECT_EQ(vertexVariant->language, ShaderLanguage::HLSL);
EXPECT_EQ(vertexVariant->entryPoint, "Vert");
EXPECT_EQ(vertexVariant->profile, "vs_5_0");
EXPECT_EQ(vertexVariant->profile, "vs_5_1");
EXPECT_NE(std::string(vertexVariant->sourceCode.CStr()).find("#include \"shaderlib/shared.hlsl\""), std::string::npos);
EXPECT_NE(std::string(vertexVariant->sourceCode.CStr()).find("XC_SINGLE_SOURCE_FRAG_BODY"), std::string::npos);
EXPECT_EQ(vertexVariant->requiredKeywords.enabledKeywords.Size(), 0u);
@@ -469,7 +469,7 @@ TEST(ShaderLoader, LoadShaderAuthoringBuildsGenericHlslVariants) {
EXPECT_EQ(fragmentVariant->backend, ShaderBackend::Generic);
EXPECT_EQ(fragmentVariant->language, ShaderLanguage::HLSL);
EXPECT_EQ(fragmentVariant->entryPoint, "Frag");
EXPECT_EQ(fragmentVariant->profile, "ps_5_0");
EXPECT_EQ(fragmentVariant->profile, "ps_5_1");
ShaderKeywordSet enabledKeywords = {};
enabledKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
@@ -500,6 +500,151 @@ TEST(ShaderLoader, LoadShaderAuthoringBuildsGenericHlslVariants) {
fs::remove_all(shaderRoot);
}
TEST(ShaderLoader, LoadShaderAuthoringBuildsComputeOnlyPassVariant) {
namespace fs = std::filesystem;
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_compute_only";
const fs::path shaderPath = shaderRoot / "compute_only.shader";
fs::remove_all(shaderRoot);
fs::create_directories(shaderRoot);
WriteTextFile(
shaderPath,
R"(Shader "ComputeOnlyShader"
{
SubShader
{
Pass
{
Name "SortKeys"
HLSLPROGRAM
#pragma target 4.5
#pragma compute SortKeysCS
StructuredBuffer<float4> InputData;
RWStructuredBuffer<uint> OutputOrder;
[numthreads(64, 1, 1)]
void SortKeysCS(uint3 dispatchThreadId : SV_DispatchThreadID)
{
OutputOrder[dispatchThreadId.x] = (uint)InputData[dispatchThreadId.x].x; // COMPUTE_ONLY_BODY
}
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());
const ShaderPass* pass = shader->FindPass("SortKeys");
ASSERT_NE(pass, nullptr);
EXPECT_EQ(pass->resources.Size(), 2u);
const ShaderResourceBindingDesc* inputData =
shader->FindPassResourceBinding("SortKeys", "InputData");
ASSERT_NE(inputData, nullptr);
EXPECT_EQ(inputData->type, ShaderResourceType::StructuredBuffer);
EXPECT_EQ(inputData->set, 2u);
EXPECT_EQ(inputData->binding, 0u);
const ShaderResourceBindingDesc* outputOrder =
shader->FindPassResourceBinding("SortKeys", "OutputOrder");
ASSERT_NE(outputOrder, nullptr);
EXPECT_EQ(outputOrder->type, ShaderResourceType::RWStructuredBuffer);
EXPECT_EQ(outputOrder->set, 4u);
EXPECT_EQ(outputOrder->binding, 0u);
EXPECT_EQ(shader->FindVariant("SortKeys", ShaderType::Vertex, ShaderBackend::D3D12), nullptr);
EXPECT_EQ(shader->FindVariant("SortKeys", ShaderType::Fragment, ShaderBackend::D3D12), nullptr);
const ShaderStageVariant* computeVariant =
shader->FindVariant("SortKeys", ShaderType::Compute, ShaderBackend::D3D12);
ASSERT_NE(computeVariant, nullptr);
EXPECT_EQ(computeVariant->backend, ShaderBackend::Generic);
EXPECT_EQ(computeVariant->language, ShaderLanguage::HLSL);
EXPECT_EQ(computeVariant->entryPoint, "SortKeysCS");
EXPECT_EQ(computeVariant->profile, "cs_5_1");
EXPECT_NE(
std::string(computeVariant->sourceCode.CStr()).find("COMPUTE_ONLY_BODY"),
std::string::npos);
XCEngine::RHI::ShaderCompileDesc d3d12CompileDesc = {};
::XCEngine::Rendering::Internal::ApplyShaderStageVariant(
*pass,
ShaderBackend::D3D12,
*computeVariant,
d3d12CompileDesc);
const std::string d3d12Source(
reinterpret_cast<const char*>(d3d12CompileDesc.source.data()),
d3d12CompileDesc.source.size());
EXPECT_NE(d3d12Source.find("StructuredBuffer<float4> InputData: register(t0);"), std::string::npos);
EXPECT_NE(d3d12Source.find("RWStructuredBuffer<uint> OutputOrder: register(u0);"), std::string::npos);
XCEngine::RHI::ShaderCompileDesc vulkanCompileDesc = {};
::XCEngine::Rendering::Internal::ApplyShaderStageVariant(
*pass,
ShaderBackend::Vulkan,
*computeVariant,
vulkanCompileDesc);
const std::string vulkanSource(
reinterpret_cast<const char*>(vulkanCompileDesc.source.data()),
vulkanCompileDesc.source.size());
EXPECT_NE(vulkanSource.find("StructuredBuffer<float4> InputData: register(t0, space2);"), std::string::npos);
EXPECT_NE(vulkanSource.find("RWStructuredBuffer<uint> OutputOrder: register(u0, space4);"), std::string::npos);
delete shader;
fs::remove_all(shaderRoot);
}
TEST(ShaderLoader, LoadShaderAuthoringRejectsPassMixingComputeAndGraphicsPragmas) {
namespace fs = std::filesystem;
const fs::path shaderRoot = fs::temp_directory_path() / "xc_shader_authoring_mixed_compute_graphics";
const fs::path shaderPath = shaderRoot / "mixed_compute_graphics.shader";
fs::remove_all(shaderRoot);
fs::create_directories(shaderRoot);
WriteTextFile(
shaderPath,
R"(Shader "MixedComputeGraphicsShader"
{
SubShader
{
Pass
{
Name "InvalidPass"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma compute ComputeMain
float4 Vert() : SV_POSITION { return 0; }
float4 Frag() : SV_TARGET { return 1.0; }
[numthreads(1, 1, 1)]
void ComputeMain(uint3 dispatchThreadId : SV_DispatchThreadID) {}
ENDHLSL
}
}
}
)");
ShaderLoader loader;
LoadResult result = loader.Load(shaderPath.string().c_str());
EXPECT_FALSE(result);
EXPECT_NE(
std::string(result.errorMessage.CStr()).find("must not mix #pragma compute with graphics stage pragmas"),
std::string::npos);
fs::remove_all(shaderRoot);
}
TEST(ShaderLoader, LoadShaderAuthoringCollectsUnityStyleBufferResources) {
namespace fs = std::filesystem;
@@ -645,7 +790,7 @@ TEST(ShaderLoader, RuntimeShaderSourceRewritesUnityStyleBufferRegisters) {
shader->FindVariant("Volume", ShaderType::Fragment, ShaderBackend::D3D12);
ASSERT_NE(fragmentVariant, nullptr);
const std::string d3d12Source =
::XCEngine::Rendering::Detail::BuildRuntimeShaderSource(
::XCEngine::Rendering::Internal::BuildRuntimeShaderSource(
*pass,
ShaderBackend::D3D12,
*fragmentVariant);
@@ -666,7 +811,7 @@ TEST(ShaderLoader, RuntimeShaderSourceRewritesUnityStyleBufferRegisters) {
shader->FindVariant("Volume", ShaderType::Fragment, ShaderBackend::Vulkan);
ASSERT_NE(vulkanFragment, nullptr);
const std::string vulkanSource =
::XCEngine::Rendering::Detail::BuildRuntimeShaderSource(
::XCEngine::Rendering::Internal::BuildRuntimeShaderSource(
*pass,
ShaderBackend::Vulkan,
*vulkanFragment);
@@ -2271,7 +2416,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("cbuffer LightingConstants"), std::string::npos);
const ShaderStageVariant* d3d12Fragment = shader->FindVariant(
@@ -2282,7 +2427,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Fragment->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Fragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Fragment->entryPoint, "MainPS");
EXPECT_EQ(d3d12Fragment->profile, "ps_5_0");
EXPECT_EQ(d3d12Fragment->profile, "ps_5_1");
EXPECT_NE(std::string(d3d12Fragment->sourceCode.CStr()).find("gAdditionalLights"), std::string::npos);
EXPECT_NE(std::string(d3d12Fragment->sourceCode.CStr()).find("gLightingParams"), std::string::npos);
EXPECT_EQ(std::string(d3d12Fragment->sourceCode.CStr()).find("#define XC_MAIN_LIGHT_SHADOWS 1"), std::string::npos);
@@ -2329,7 +2474,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
EXPECT_EQ(alphaShadowOpenGLFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(alphaShadowOpenGLFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(alphaShadowOpenGLFragment->entryPoint, "MainPS");
EXPECT_EQ(alphaShadowOpenGLFragment->profile, "ps_5_0");
EXPECT_EQ(alphaShadowOpenGLFragment->profile, "ps_5_1");
const std::string alphaShadowOpenGLSource = alphaShadowOpenGLFragment->sourceCode.CStr();
EXPECT_NE(alphaShadowOpenGLSource.find("#define XC_ALPHA_TEST 1"), std::string::npos);
EXPECT_NE(alphaShadowOpenGLSource.find("clip(baseColor.a - gAlphaCutoffParams.x);"), std::string::npos);
@@ -2343,7 +2488,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
EXPECT_EQ(alphaShadowVulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(alphaShadowVulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(alphaShadowVulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(alphaShadowVulkanFragment->profile, "ps_5_0");
EXPECT_EQ(alphaShadowVulkanFragment->profile, "ps_5_1");
const std::string alphaShadowVulkanSource = alphaShadowVulkanFragment->sourceCode.CStr();
EXPECT_NE(alphaShadowVulkanSource.find("#define XC_ALPHA_TEST 1"), std::string::npos);
EXPECT_NE(alphaShadowVulkanSource.find("ShadowMapTexture.Sample"), std::string::npos);
@@ -2356,7 +2501,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("gAdditionalLights"), std::string::npos);
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("gLightingParams"), std::string::npos);
@@ -2368,7 +2513,7 @@ TEST(ShaderLoader, LoadBuiltinForwardLitShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gAdditionalLights"), std::string::npos);
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gLightingParams"), std::string::npos);
@@ -2425,7 +2570,7 @@ TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("gProjectionMatrix"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
@@ -2436,7 +2581,7 @@ TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsAuthoringVariants) {
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("BaseColorTexture.Sample"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
@@ -2447,7 +2592,7 @@ TEST(ShaderLoader, LoadBuiltinUnlitShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gBaseColorFactor"), std::string::npos);
delete shader;
@@ -2490,7 +2635,7 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("gObjectIdColor"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
@@ -2501,7 +2646,7 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsAuthoringVariants) {
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("return gObjectIdColor;"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
@@ -2512,7 +2657,7 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gModelMatrix"), std::string::npos);
delete shader;
@@ -2603,7 +2748,7 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("gProjectionMatrix"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
@@ -2614,7 +2759,7 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("BaseColorTexture.Sample"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
@@ -2625,7 +2770,7 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gAlphaCutoffParams"), std::string::npos);
ShaderKeywordSet alphaKeywords = {};
@@ -2640,7 +2785,7 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
EXPECT_EQ(alphaD3D12Fragment->backend, ShaderBackend::Generic);
EXPECT_EQ(alphaD3D12Fragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(alphaD3D12Fragment->entryPoint, "MainPS");
EXPECT_EQ(alphaD3D12Fragment->profile, "ps_5_0");
EXPECT_EQ(alphaD3D12Fragment->profile, "ps_5_1");
EXPECT_NE(
std::string(alphaD3D12Fragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
@@ -2657,7 +2802,7 @@ TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
EXPECT_EQ(alphaOpenGLFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(alphaOpenGLFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(alphaOpenGLFragment->entryPoint, "MainPS");
EXPECT_EQ(alphaOpenGLFragment->profile, "ps_5_0");
EXPECT_EQ(alphaOpenGLFragment->profile, "ps_5_1");
const std::string alphaOpenGLSource = alphaOpenGLFragment->sourceCode.CStr();
EXPECT_NE(alphaOpenGLSource.find("#define XC_ALPHA_TEST 1"), std::string::npos);
EXPECT_NE(alphaOpenGLSource.find("clip(baseColor.a - gAlphaCutoffParams.x);"), std::string::npos);
@@ -2729,7 +2874,7 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("gProjectionMatrix"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
@@ -2740,7 +2885,7 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsAuthoringVariants) {
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("return input.position.z;"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
@@ -2751,7 +2896,7 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gAlphaCutoffParams"), std::string::npos);
ShaderKeywordSet alphaKeywords = {};
@@ -2766,7 +2911,7 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsAuthoringVariants) {
EXPECT_EQ(alphaD3D12Fragment->backend, ShaderBackend::Generic);
EXPECT_EQ(alphaD3D12Fragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(alphaD3D12Fragment->entryPoint, "MainPS");
EXPECT_EQ(alphaD3D12Fragment->profile, "ps_5_0");
EXPECT_EQ(alphaD3D12Fragment->profile, "ps_5_1");
EXPECT_NE(
std::string(alphaD3D12Fragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
@@ -2783,7 +2928,7 @@ TEST(ShaderLoader, LoadBuiltinShadowCasterShaderBuildsAuthoringVariants) {
EXPECT_EQ(alphaOpenGLFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(alphaOpenGLFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(alphaOpenGLFragment->entryPoint, "MainPS");
EXPECT_EQ(alphaOpenGLFragment->profile, "ps_5_0");
EXPECT_EQ(alphaOpenGLFragment->profile, "ps_5_1");
const std::string alphaOpenGLSource = alphaOpenGLFragment->sourceCode.CStr();
EXPECT_NE(alphaOpenGLSource.find("#define XC_ALPHA_TEST 1"), std::string::npos);
EXPECT_NE(alphaOpenGLSource.find("clip(baseColor.a - gAlphaCutoffParams.x);"), std::string::npos);
@@ -2845,7 +2990,7 @@ TEST(ShaderLoader, LoadBuiltinFinalColorShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("UNITY_UV_STARTS_AT_TOP"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
@@ -2856,7 +3001,7 @@ TEST(ShaderLoader, LoadBuiltinFinalColorShaderBuildsAuthoringVariants) {
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("SourceColorTexture.Sample"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
@@ -2867,7 +3012,7 @@ TEST(ShaderLoader, LoadBuiltinFinalColorShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("ApplyToneMapping"), std::string::npos);
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gFinalColorParams"), std::string::npos);
@@ -2916,7 +3061,7 @@ TEST(ShaderLoader, LoadBuiltinColorScalePostProcessShaderBuildsAuthoringVariants
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(std::string(d3d12Vertex->sourceCode.CStr()).find("UNITY_UV_STARTS_AT_TOP"), std::string::npos);
const ShaderStageVariant* openglFragment = shader->FindVariant(
@@ -2927,7 +3072,7 @@ TEST(ShaderLoader, LoadBuiltinColorScalePostProcessShaderBuildsAuthoringVariants
EXPECT_EQ(openglFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(openglFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(openglFragment->entryPoint, "MainPS");
EXPECT_EQ(openglFragment->profile, "ps_5_0");
EXPECT_EQ(openglFragment->profile, "ps_5_1");
EXPECT_NE(std::string(openglFragment->sourceCode.CStr()).find("SourceColorTexture.Sample"), std::string::npos);
const ShaderStageVariant* vulkanFragment = shader->FindVariant(
@@ -2938,7 +3083,7 @@ TEST(ShaderLoader, LoadBuiltinColorScalePostProcessShaderBuildsAuthoringVariants
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("gColorScale"), std::string::npos);
EXPECT_NE(std::string(vulkanFragment->sourceCode.CStr()).find("SourceColorTexture.Sample"), std::string::npos);
@@ -2983,7 +3128,7 @@ TEST(ShaderLoader, LoadBuiltinObjectIdOutlineShaderBuildsAuthoringVariants) {
EXPECT_EQ(d3d12Vertex->backend, ShaderBackend::Generic);
EXPECT_EQ(d3d12Vertex->language, ShaderLanguage::HLSL);
EXPECT_EQ(d3d12Vertex->entryPoint, "MainVS");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_0");
EXPECT_EQ(d3d12Vertex->profile, "vs_5_1");
EXPECT_NE(
std::string(d3d12Vertex->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_VS"),
std::string::npos);
@@ -3005,7 +3150,7 @@ TEST(ShaderLoader, LoadBuiltinObjectIdOutlineShaderBuildsAuthoringVariants) {
EXPECT_EQ(vulkanFragment->backend, ShaderBackend::Generic);
EXPECT_EQ(vulkanFragment->language, ShaderLanguage::HLSL);
EXPECT_EQ(vulkanFragment->entryPoint, "MainPS");
EXPECT_EQ(vulkanFragment->profile, "ps_5_0");
EXPECT_EQ(vulkanFragment->profile, "ps_5_1");
EXPECT_NE(
std::string(vulkanFragment->sourceCode.CStr()).find("XC_BUILTIN_OBJECT_ID_OUTLINE_D3D12_PS"),
std::string::npos);
@@ -3099,3 +3244,4 @@ TEST(ShaderLoader, ResourceManagerLoadsBuiltinShadersOutsideProjectWorkingDirect
}
} // namespace