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;