summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-shader.cpp
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2024-07-18 11:03:30 -0400
committerGitHub <noreply@github.com>2024-07-18 11:03:30 -0400
commit6f1371a7870a7c371a77cfdee1daa5c32f0c5377 (patch)
tree70fa0962fa5f34ea4646a531c3969bbf7eb8d74b /source/slang/slang-check-shader.cpp
parent494efd7254f28ec46aff84bb1c06fe582a743c1a (diff)
Adjust how `slang` and `slangc` uses a `profile` to manage the stage of an entry-point (#4670)
* Fixes #4656 Changes: 1. Setting a profile via slangc no-longer sets an entry-point target-stage, this is to allow slangc to follow how the SLANG-API works (else `main` is assumed to be the default entry-point) 2. If the stage specified by a profile is not equal to the stage specified by a entry-point, we throw a capability error. 3. Resolving the stage of an entry point was changed to function (mostly) equally for when 0 entry-points are specified versus to when there are 1 or more. 4. changed capabilitySet Iterator so it is invalid if backing data is nullptr (although this should never happen, it would stop crashes in the worst case). * remove the breaking change since it likely is going to be a lot more than just a simple change due to the implicit `main` and stage through `profile` code. * print out profile name with errors * use target's profile for printing * change logic to print warning in a different method (account for more cases) * set unknown stages
Diffstat (limited to 'source/slang/slang-check-shader.cpp')
-rw-r--r--source/slang/slang-check-shader.cpp50
1 files changed, 30 insertions, 20 deletions
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index 14495dd6e..3d086b189 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -577,6 +577,30 @@ namespace Slang
}
}
+ bool resolveStageOfProfileWithEntryPoint(Profile& entryPointProfile, CompilerOptionSet& optionSet, const List<RefPtr<TargetRequest>>& targets, FuncDecl* entryPointFuncDecl, DiagnosticSink* sink)
+ {
+ if (auto entryPointAttr = entryPointFuncDecl->findModifier<EntryPointAttribute>())
+ {
+ auto entryPointProfileStage = entryPointProfile.getStage();
+ // Ensure every target is specifying the same stage as an entry` point
+ // if a profile+stage was set, else user will not be aware that their
+ // code is requiring `fragment` on a `vertex` shader
+ for (auto target : targets)
+ {
+ auto targetProfile = target->getOptionSet().getProfile();
+ auto profileStage = targetProfile.getStage();
+ if (profileStage != Stage::Unknown && profileStage != entryPointAttr->stage)
+ maybeDiagnose(sink, optionSet, DiagnosticCategory::Capability, entryPointAttr, Diagnostics::entryPointAndProfileAreIncompatible, entryPointFuncDecl, entryPointAttr->stage, targetProfile.getName());
+ }
+ if (entryPointProfileStage == Stage::Unknown)
+ entryPointProfile.setStage(entryPointAttr->stage);
+ else if (entryPointProfileStage != Stage::Unknown && entryPointProfileStage != entryPointAttr->stage)
+ maybeDiagnose(sink, optionSet, DiagnosticCategory::Capability, entryPointFuncDecl, Diagnostics::specifiedStageDoesntMatchAttribute, entryPointFuncDecl->getName(), entryPointProfileStage, entryPointAttr->stage);
+ return true;
+ }
+ return false;
+ }
+
// Given an entry point specified via API or command line options,
// attempt to find a matching AST declaration that implements the specified
// entry point. If such a function is found, then validate that it actually
@@ -618,27 +642,13 @@ namespace Slang
//
// If the entry point specifies a stage via a `[shader("...")]` attribute,
// then we might be able to infer a stage for the entry point request if
- // it didn't have one, *or* issue a diagnostic if there is a mismatch.
- //
+ // it didn't have one, *or* issue a diagnostic if there is a mismatch with the profile.
+
auto entryPointProfile = entryPointReq->getProfile();
- if( auto entryPointAttribute = entryPointFuncDecl->findModifier<EntryPointAttribute>() )
- {
- auto entryPointStage = entryPointProfile.getStage();
- if( entryPointStage == Stage::Unknown )
- {
- entryPointProfile.setStage(entryPointAttribute->stage);
- }
- else if( entryPointAttribute->stage != entryPointStage )
- {
- sink->diagnose(entryPointFuncDecl, Diagnostics::specifiedStageDoesntMatchAttribute, entryPointName, entryPointStage, entryPointAttribute->stage);
- }
- }
- else
- {
- // TODO: Should we attach a `[shader(...)]` attribute to an
- // entry point that didn't have one, so that we can have
- // a more uniform representation in the AST?
- }
+ resolveStageOfProfileWithEntryPoint(entryPointProfile, linkage->m_optionSet, linkage->targets, entryPointFuncDecl, sink);
+ // TODO: Should we attach a `[shader(...)]` attribute to an
+ // entry point that didn't have one, so that we can have
+ // a more uniform representation in the AST?
RefPtr<EntryPoint> entryPoint = EntryPoint::create(
linkage,