summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorNathan V. Morrical <natemorrical@gmail.com>2021-05-25 11:06:54 -0600
committerGitHub <noreply@github.com>2021-05-25 10:06:54 -0700
commitfbf00dd54d787c6e22b0f1785a64dfb2fb1e300a (patch)
treedd7e6f32eea789e3288dc8a937e92f256ea0b8e9 /source/slang
parent34a1ff5226a526cc17c5baecd63637f69c324fc7 (diff)
OptiX ray payload read/write support in raytracing pipeline shaders (#1853)
* OptiX ray payload can now be read from and written to using the two payload register pointer method * changing op to more descriptive name * fixup: comment change to re-trigger CI Co-authored-by: T. Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-emit-cuda.cpp7
-rw-r--r--source/slang/slang-ir-inst-defs.h4
-rw-r--r--source/slang/slang-ir-legalize-varying-params.cpp55
-rw-r--r--source/slang/slang-type-layout.cpp21
4 files changed, 78 insertions, 9 deletions
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index 09ea7ef9e..4c430cfa6 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -781,6 +781,13 @@ bool CUDASourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
m_writer->emit(")");
return true;
}
+ case kIROp_GetOptiXRayPayloadPtr:
+ {
+ m_writer->emit("(");
+ emitType(inst->getDataType());
+ m_writer->emit(")getOptiXRayPayloadPtr()");
+ return true;
+ }
default: break;
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index f73dbd006..17ae652ae 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -497,6 +497,10 @@ INST(GroupMemoryBarrierWithGroupSync, GroupMemoryBarrierWithGroupSync, 0, 0)
// GPU_FOREACH loop of the form
INST(GpuForeach, gpuForeach, 3, 0)
+// Wrapper for OptiX intrinsics used to load and store ray payload data using
+// a pointer represented by two payload registers.
+INST(GetOptiXRayPayloadPtr, getOptiXRayPayloadPtr, 0, 0)
+
/* Decoration */
INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
diff --git a/source/slang/slang-ir-legalize-varying-params.cpp b/source/slang/slang-ir-legalize-varying-params.cpp
index c802513e8..f500b100f 100644
--- a/source/slang/slang-ir-legalize-varying-params.cpp
+++ b/source/slang/slang-ir-legalize-varying-params.cpp
@@ -895,11 +895,7 @@ protected:
virtual LegalizedVaryingVal createLegalUserVaryingValImpl(VaryingParamInfo const& info)
{
- SLANG_UNUSED(info);
-
- m_sink->diagnose(m_param, Diagnostics::unimplemented, "this target doesn't support user-defined varying parameters");
-
- return LegalizedVaryingVal();
+ return diagnoseUnsupportedUserVal(info);
}
virtual LegalizedVaryingVal createLegalSystemVaryingValImpl(VaryingParamInfo const& info)
@@ -915,7 +911,16 @@ protected:
{
SLANG_UNUSED(info);
- m_sink->diagnose(m_param, Diagnostics::unimplemented, "this target doesn't support this system-defined varying parameters");
+ m_sink->diagnose(m_param, Diagnostics::unimplemented, "this target doesn't support this system-defined varying parameter");
+
+ return LegalizedVaryingVal();
+ }
+
+ LegalizedVaryingVal diagnoseUnsupportedUserVal(VaryingParamInfo const& info)
+ {
+ SLANG_UNUSED(info);
+
+ m_sink->diagnose(m_param, Diagnostics::unimplemented, "this target doesn't support this user-defined varying parameter");
return LegalizedVaryingVal();
}
@@ -1054,6 +1059,14 @@ struct CUDAEntryPointVaryingParamLegalizeContext : EntryPointVaryingParamLegaliz
//
IRType* uint3Type = nullptr;
+ // Scans through and returns the first typeLayout attribute of non-zero size.
+ static LayoutResourceKind getLayoutResourceKind(IRTypeLayout* typeLayout) {
+ for (auto attr : typeLayout->getSizeAttrs()) {
+ if (attr->getSize() != 0) return attr->getResourceKind();
+ }
+ return LayoutResourceKind::None;
+ }
+
void beginModuleImpl() SLANG_OVERRIDE
{
// Because many of the varying parameters are defined
@@ -1114,7 +1127,6 @@ struct CUDAEntryPointVaryingParamLegalizeContext : EntryPointVaryingParamLegaliz
IRInst* groupThreadIndex = nullptr;
IRInst* dispatchThreadID = nullptr;
-
void beginEntryPointImpl() SLANG_OVERRIDE
{
IRBuilder builder(m_sharedBuilder);
@@ -1174,11 +1186,38 @@ struct CUDAEntryPointVaryingParamLegalizeContext : EntryPointVaryingParamLegaliz
case SystemValueSemanticName::GroupThreadID: return LegalizedVaryingVal::makeValue(threadIdxGlobalParam);
case SystemValueSemanticName::GroupThreadIndex: return LegalizedVaryingVal::makeValue(groupThreadIndex);
case SystemValueSemanticName::DispatchThreadID: return LegalizedVaryingVal::makeValue(dispatchThreadID);
-
default:
return diagnoseUnsupportedSystemVal(info);
}
}
+
+ LegalizedVaryingVal createLegalUserVaryingValImpl(VaryingParamInfo const& info) SLANG_OVERRIDE
+ {
+ auto layoutResourceKind = getLayoutResourceKind(info.typeLayout);
+ switch (layoutResourceKind)
+ {
+ case LayoutResourceKind::RayPayload: {
+ IRBuilder builder(m_sharedBuilder);
+ builder.setInsertBefore(m_firstOrdinaryInst);
+ IRPtrType* ptrType = builder.getPtrType(info.type);
+ IRInst* getRayPayload = builder.emitIntrinsicInst(ptrType, kIROp_GetOptiXRayPayloadPtr, 0, nullptr);
+ return LegalizedVaryingVal::makeAddress(getRayPayload);
+ // Todo: compute how many registers are required for the current payload.
+ // If more than 32, use the above logic.
+ // Otherwise, either use the optix_get_payload or optix_set_payload
+ // intrinsics depending on input/output
+ /*if (info.kind == LayoutResourceKind::VaryingInput) {
+ }
+ else if (info.kind == LayoutResourceKind::VaryingOutput) {
+ }
+ else {
+ return diagnoseUnsupportedUserVal(info);
+ }*/
+ }
+ default:
+ return diagnoseUnsupportedUserVal(info);
+ }
+ }
};
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index f21722bd7..f2869886e 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -686,6 +686,12 @@ struct HLSLRayTracingLayoutRulesImpl : DefaultVaryingLayoutRulesImpl
: DefaultVaryingLayoutRulesImpl(kind)
{}
};
+struct CUDARayTracingLayoutRulesImpl : DefaultVaryingLayoutRulesImpl
+{
+ CUDARayTracingLayoutRulesImpl(LayoutResourceKind kind)
+ : DefaultVaryingLayoutRulesImpl(kind)
+ {}
+};
DefaultLayoutRulesImpl kDefaultLayoutRulesImpl;
Std140LayoutRulesImpl kStd140LayoutRulesImpl;
@@ -707,7 +713,13 @@ HLSLRayTracingLayoutRulesImpl kHLSLRayPayloadParameterLayoutRulesImpl(LayoutReso
HLSLRayTracingLayoutRulesImpl kHLSLCallablePayloadParameterLayoutRulesImpl(LayoutResourceKind::CallablePayload);
HLSLRayTracingLayoutRulesImpl kHLSLHitAttributesParameterLayoutRulesImpl(LayoutResourceKind::HitAttributes);
+// Just copying what was done above for now, but for CUDA...
+//CUDAVaryingLayoutRulesImpl kCUDAVaryingInputLayoutRulesImpl(LayoutResourceKind::VertexInput);
+//CUDAVaryingLayoutRulesImpl kCUDAVaryingOutputLayoutRulesImpl(LayoutResourceKind::FragmentOutput);
//
+CUDARayTracingLayoutRulesImpl kCUDARayPayloadParameterLayoutRulesImpl(LayoutResourceKind::RayPayload);
+//CUDARayTracingLayoutRulesImpl kCUDACallablePayloadParameterLayoutRulesImpl(LayoutResourceKind::CallablePayload);
+//CUDARayTracingLayoutRulesImpl kCUDAHitAttributesParameterLayoutRulesImpl(LayoutResourceKind::HitAttributes);
struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
@@ -929,6 +941,12 @@ LayoutRulesImpl kCUDAAnyValueLayoutRulesImpl_ = {
&kCUDAObjectLayoutRulesImpl,
};
+// We want a custom layout for ray payloads to handle the logic of
+// copying payload registers vs reading / writing to and from memory
+LayoutRulesImpl kCUDARayPayloadParameterLayoutRulesImpl_ = {
+ &kCUDALayoutRulesFamilyImpl, &kCUDARayPayloadParameterLayoutRulesImpl, &kCUDAObjectLayoutRulesImpl,
+};
+
// GLSL cases
LayoutRulesImpl kStd140LayoutRulesImpl_ = {
@@ -1276,7 +1294,8 @@ LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getParameterBlockRules()
}
LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getRayPayloadParameterRules()
{
- return nullptr;
+ // Mimicking HLSL
+ return &kCUDARayPayloadParameterLayoutRulesImpl_;
}
LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getCallablePayloadParameterRules()
{