diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/core.meta.slang | 3 | ||||
| -rw-r--r-- | source/slang/slang-ast-modifier.h | 10 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 42 | ||||
| -rw-r--r-- | source/slang/slang-compiler.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-compiler.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 10 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 5 |
10 files changed, 99 insertions, 3 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index e2fb8bbf2..481aba191 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -4214,3 +4214,6 @@ attribute_syntax [RequireFullQuads] : RequireFullQuadsAttribute; __generic<T> typealias NodePayloadPtr = Ptr<T, $( (uint64_t)AddressSpace::NodePayloadAMDX)>; +__attributeTarget(StructDecl) +attribute_syntax [raypayload] : RayPayloadAttribute; + diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h index 5f9ccb5bb..86c1b556c 100644 --- a/source/slang/slang-ast-modifier.h +++ b/source/slang/slang-ast-modifier.h @@ -1698,6 +1698,16 @@ class PayloadAttribute : public Attribute SLANG_AST_CLASS(PayloadAttribute) }; +/// A `[raypayload]` attribute indicates that a `struct` type will be used as +/// a ray payload for `TraceRay()` calls, and thus also as input/output +/// for shaders in the ray tracing pipeline that might be invoked for +/// such a ray. +/// +class RayPayloadAttribute : public Attribute +{ + SLANG_AST_CLASS(RayPayloadAttribute) +}; + /// A `[deprecated("message")]` attribute indicates the target is /// deprecated. /// A compiler warning including the message will be raised if the diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 4ab909118..21a16cae5 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -12496,6 +12496,12 @@ void SemanticsDeclAttributesVisitor::visitStructDecl(StructDecl* structDecl) } } + // Check if this is a ray payload struct and validate field access qualifiers + if (structDecl->findModifier<RayPayloadAttribute>()) + { + checkRayPayloadStructFields(structDecl); + } + int backingWidth = 0; [[maybe_unused]] int totalWidth = 0; struct BitFieldInfo diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index f7681ba45..8a1e79ce8 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -2835,6 +2835,8 @@ public: bool isCStyleType(Type* type, HashSet<Type*>& isVisit); void addVisibilityModifier(Decl* decl, DeclVisibility vis); + + void checkRayPayloadStructFields(StructDecl* structDecl); }; diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 741823a65..d94c77d6a 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -1413,9 +1413,20 @@ bool isModifierAllowedOnDecl(bool isGLSLInput, ASTNodeType modifierType, Decl* d case ASTNodeType::ConstRefModifier: case ASTNodeType::GLSLBufferModifier: case ASTNodeType::GLSLPatchModifier: + return (as<VarDeclBase>(decl) && isGlobalDecl(decl)) || as<ParamDecl>(decl) || + as<GLSLInterfaceBlockDecl>(decl); case ASTNodeType::RayPayloadAccessSemantic: case ASTNodeType::RayPayloadReadSemantic: case ASTNodeType::RayPayloadWriteSemantic: + // Allow on struct fields if the parent struct has the [raypayload] attribute + if (auto varDecl = as<VarDeclBase>(decl)) + { + if (auto structDecl = as<StructDecl>(varDecl->parentDecl)) + { + if (structDecl->findModifier<RayPayloadAttribute>()) + return true; + } + } return (as<VarDeclBase>(decl) && isGlobalDecl(decl)) || as<ParamDecl>(decl) || as<GLSLInterfaceBlockDecl>(decl); @@ -2179,5 +2190,36 @@ void SemanticsVisitor::checkModifiers(ModifiableSyntaxNode* syntaxNode) postProcessingOnModifiers(syntaxNode->modifiers); } +void SemanticsVisitor::checkRayPayloadStructFields(StructDecl* structDecl) +{ + // Only check structs with the [raypayload] attribute + if (!structDecl->findModifier<RayPayloadAttribute>()) + { + return; + } + + // Check each field in the struct + for (auto member : structDecl->members) + { + auto fieldVarDecl = as<VarDeclBase>(member); + if (!fieldVarDecl) + { + continue; + } + + bool hasReadModifier = fieldVarDecl->findModifier<RayPayloadReadSemantic>() != nullptr; + bool hasWriteModifier = fieldVarDecl->findModifier<RayPayloadWriteSemantic>() != nullptr; + + if (!hasReadModifier && !hasWriteModifier) + { + // Emit the diagnostic error + getSink()->diagnose( + fieldVarDecl, + Diagnostics::rayPayloadFieldMissingAccessQualifiers, + fieldVarDecl->getName()); + } + } +} + } // namespace Slang diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 3839e0722..55f3846af 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -1732,6 +1732,11 @@ SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(ComPtr<IArtifact>& options.libraries = SliceUtil::asSlice(libraries); options.libraryPaths = allocator.allocate(libraryPaths); + if (m_targetProfile.getFamily() == ProfileFamily::DX) + { + options.enablePAQ = m_targetProfile.getVersion() >= ProfileVersion::DX_6_7; + } + // Compile ComPtr<IArtifact> artifact; auto downstreamStartTime = std::chrono::high_resolution_clock::now(); diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 18192678a..8a9b8985a 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -2812,7 +2812,9 @@ public: }; CodeGenContext(Shared* shared) - : m_shared(shared), m_targetFormat(shared->targetProgram->getTargetReq()->getTarget()) + : m_shared(shared) + , m_targetFormat(shared->targetProgram->getTargetReq()->getTarget()) + , m_targetProfile(shared->targetProgram->getOptionSet().getProfile()) { } @@ -2909,6 +2911,7 @@ public: protected: CodeGenTarget m_targetFormat = CodeGenTarget::Unknown; + Profile m_targetProfile; ExtensionTracker* m_extensionTracker = nullptr; /// Will output assembly as well as the artifact if appropriate for the artifact type for diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index f2c7fecc1..21bf73d6e 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -2702,4 +2702,14 @@ DIAGNOSTIC( noBlocksOrIntrinsic, "no blocks found for function definition, is there a '$0' intrinsic missing?") +// +// Ray tracing +// + +DIAGNOSTIC( + 40000, + Error, + rayPayloadFieldMissingAccessQualifiers, + "field '$0' in ray payload struct must have either 'read' OR 'write' access qualifiers") + #undef DIAGNOSTIC diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 0f1ef3ee0..2d963866d 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -1667,8 +1667,18 @@ void HLSLSourceEmitter::emitPostKeywordTypeAttributesImpl(IRInst* inst) { m_writer->emit("[payload] "); } - // This can be re-enabled when we add PAQs: https://github.com/shader-slang/slang/issues/3448 - const bool enablePAQs = false; + + // Get the target profile to determine if PAQs are supported + bool enablePAQs = false; + auto profile = getTargetProgram()->getOptionSet().getProfile(); + if (profile.getFamily() == ProfileFamily::DX) + { + // PAQs are default in Shader Model 6.7 and above when called with `--profile lib_6_7` + + auto version = profile.getVersion(); + enablePAQs = version >= ProfileVersion::DX_6_7; + } + if (enablePAQs) { if (const auto payloadDecoration = inst->findDecoration<IRRayPayloadDecoration>()) diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index e6ec68660..260596dc3 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -9318,6 +9318,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> subBuilder->addDecoration(irAggType, kIROp_PayloadDecoration); } + if (const auto rayPayloadAttribute = decl->findModifier<RayPayloadAttribute>()) + { + subBuilder->addDecoration(irAggType, kIROp_RayPayloadDecoration); + } + subBuilder->setInsertInto(irAggType); // A `struct` that inherits from another `struct` must start |
