diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2024-07-18 11:03:30 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-18 11:03:30 -0400 |
| commit | 6f1371a7870a7c371a77cfdee1daa5c32f0c5377 (patch) | |
| tree | 70fa0962fa5f34ea4646a531c3969bbf7eb8d74b /source/slang/slang-check-shader.cpp | |
| parent | 494efd7254f28ec46aff84bb1c06fe582a743c1a (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.cpp | 50 |
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, |
