summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/core.meta.slang3
-rw-r--r--source/slang/slang-ast-modifier.h10
-rw-r--r--source/slang/slang-check-decl.cpp6
-rw-r--r--source/slang/slang-check-impl.h2
-rw-r--r--source/slang/slang-check-modifier.cpp42
-rw-r--r--source/slang/slang-compiler.cpp5
-rw-r--r--source/slang/slang-compiler.h5
-rw-r--r--source/slang/slang-diagnostic-defs.h10
-rw-r--r--source/slang/slang-emit-hlsl.cpp14
-rw-r--r--source/slang/slang-lower-to-ir.cpp5
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