From 65240d074b4ddec55e56962ebf8de46207bcf5fa Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:06:23 -0400 Subject: 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 --- source/slang/slang-check-shader.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source/slang/slang-check-shader.cpp') diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp index 99205e522..3a1e4c7f6 100644 --- a/source/slang/slang-check-shader.cpp +++ b/source/slang/slang-check-shader.cpp @@ -557,7 +557,7 @@ namespace Slang for (auto target : linkage->targets) { auto targetCaps = target->getTargetCaps(); - auto stageCapabilitySet = CapabilitySet(entryPoint->getProfile().getCapabilityName()); + auto stageCapabilitySet = entryPoint->getProfile().getCapabilityName(); targetCaps.join(stageCapabilitySet); if (targetCaps.isIncompatibleWith(entryPointFuncDecl->inferredCapabilityRequirements)) { @@ -613,20 +613,23 @@ namespace Slang if (auto entryPointAttr = entryPointFuncDecl->findModifier()) { auto entryPointProfileStage = entryPointProfile.getStage(); - // Ensure every target is specifying the same stage as an entry` point + auto entryPointStage = getStageFromAtom(entryPointAttr->capabilitySet.getTargetStage()); + + // 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 (profileStage != Stage::Unknown && profileStage != entryPointStage) + maybeDiagnose(sink, optionSet, DiagnosticCategory::Capability, entryPointAttr, Diagnostics::entryPointAndProfileAreIncompatible, entryPointFuncDecl, entryPointStage, 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); + entryPointProfile = Profile(entryPointStage); + else if (entryPointProfileStage != Stage::Unknown && entryPointProfileStage != entryPointStage) + maybeDiagnose(sink, optionSet, DiagnosticCategory::Capability, entryPointFuncDecl, Diagnostics::specifiedStageDoesntMatchAttribute, entryPointFuncDecl->getName(), entryPointProfileStage, entryPointStage); + entryPointProfile.additionalCapabilities.add(entryPointAttr->capabilitySet); return true; } return false; -- cgit v1.2.3