summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-modifier.cpp
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2024-08-28 15:06:23 -0400
committerGitHub <noreply@github.com>2024-08-28 12:06:23 -0700
commit65240d074b4ddec55e56962ebf8de46207bcf5fa (patch)
treefa887d3de8ab55c7498eae2d5bf61966818135a1 /source/slang/slang-check-modifier.cpp
parent638e5fb000d4e242a91e8b653da4a72daec0efda (diff)
Allow capabilities to be used with `[shader("...")]` (#4928)
* Allow capabilities to be used with `[shader("...")]` Fixes: #4917 Changes: 1. Allow using capabilities instead of `Stage`s with `EntryPointAttribute`. 2. When resolving capabilities for an entrypoint+profile (per entrypoint) in `resolveStageOfProfileWithEntryPoint` add our `EntryPointAttribute` and resolved capability 3. Added tests and some capabilities related clean-up * fix a warning made by a mistake in syntax * change fineStageByName to assume it is passed a stage without a '_' * test with and without prefix '_' * cleanup some profiles and reprisentation to work better with 'Stage' and 'Profile' This use case is why we need to clean all profile-usage into `CapabilityName`s directly. * change how we compare * only change profiles * let all capabilities be resolved by 'shader' profile for now * fix warning checks I accidently broke * meshshading_internal to _meshshading --------- Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source/slang/slang-check-modifier.cpp')
-rw-r--r--source/slang/slang-check-modifier.cpp42
1 files changed, 35 insertions, 7 deletions
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 705d0bb3b..d7f879c51 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -548,19 +548,47 @@ namespace Slang
{
SLANG_ASSERT(attr->args.getCount() == 1);
- String stageName;
- if (!checkLiteralStringVal(attr->args[0], &stageName))
+ String capNameString;
+ if (!checkLiteralStringVal(attr->args[0], &capNameString))
{
return false;
}
- auto stage = findStageByName(stageName);
- if (stage == Stage::Unknown)
+ CapabilityName capName = findCapabilityName(capNameString.getUnownedSlice());
+ if (capName != CapabilityName::Invalid)
{
- getSink()->diagnose(attr->args[0], Diagnostics::unknownStageName, stageName);
- }
+ if (isInternalCapabilityName(capName))
+ maybeDiagnose(getSink(), this->getOptionSet(), DiagnosticCategory::Capability, attr, Diagnostics::usingInternalCapabilityName, attr, capName);
+
+ // Ensure this capability only defines 1 stage per target, else diagnose an error.
+ // This is a fatal error, do not allow toggling this error off.
+ entryPointAttr->capabilitySet = CapabilitySet(capName);
+ HashSet<CapabilityAtom> stageToBeUsed;
+ for (auto& targetSet : entryPointAttr->capabilitySet.getCapabilityTargetSets())
+ {
+ for(auto& stageSet : targetSet.second.shaderStageSets)
+ stageToBeUsed.add(stageSet.first);
+ }
- entryPointAttr->stage = stage;
+ // TODO: Once profiles are removed in favor for `CapabilitySet`s we will beable to use more complex relationships,
+ // Until then we have an artificial limit that any capabilites used inside '[shader(...)]' must only specify 1 stage type
+ // uniformly across targets.
+ if (stageToBeUsed.getCount() > 1)
+ {
+ List<CapabilityAtom> atomsToPrint;
+ atomsToPrint.reserve(stageToBeUsed.getCount());
+ for (auto i : stageToBeUsed)
+ atomsToPrint.add(i);
+ getSink()->diagnose(attr, Diagnostics::capabilityHasMultipleStages, capNameString, atomsToPrint);
+ }
+ return entryPointAttr;
+ }
+ else
+ {
+ // always diagnose this error since nothing can compile with an invalid capability
+ getSink()->diagnose(attr, Diagnostics::unknownCapability, capNameString);
+ return false;
+ }
}
else if ((as<DomainAttribute>(attr)) ||
(as<MaxTessFactorAttribute>(attr)) ||