diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2024-08-28 15:06:23 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-28 12:06:23 -0700 |
| commit | 65240d074b4ddec55e56962ebf8de46207bcf5fa (patch) | |
| tree | fa887d3de8ab55c7498eae2d5bf61966818135a1 /source/slang/slang-check-modifier.cpp | |
| parent | 638e5fb000d4e242a91e8b653da4a72daec0efda (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.cpp | 42 |
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)) || |
