diff options
| author | Nathan V. Morrical <natemorrical@gmail.com> | 2021-06-04 17:18:14 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-04 16:18:14 -0700 |
| commit | 1617c2d4d7145435f34619d8d6706c5845b898c0 (patch) | |
| tree | 46187a6ac9cae538d20593eb10ab319acf21973f /source | |
| parent | 95a90d7fda3097d085cde1fea5213667277e729b (diff) | |
Enable tracing rays with OptiX backend (#1871)
* OptiX ray payload can now be read from and written to using the two payload register pointer method
* changing op to more descriptive name
* small tweak to allow for dumping out intermediate source for cuda targets
* initial trace ray call compiling
* hit attributes now work for float and int types, and vectors thereof
* Hitgroups using structs and arrays now work with optix
Co-authored-by: T. Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 6 | ||||
| -rw-r--r-- | source/slang/slang-emit-cuda.cpp | 23 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-legalize-varying-params.cpp | 94 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 8 |
5 files changed, 129 insertions, 5 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 3d7217b99..bb573c2b2 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -4220,18 +4220,23 @@ static const RAY_FLAG RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES = 0x200; // 10.1.2 - Ray Description Structure __target_intrinsic(hlsl, RayDesc) +__target_intrinsic(cuda, RayDesc) struct RayDesc { __target_intrinsic(hlsl, Origin) + __target_intrinsic(cuda, Origin) float3 Origin; __target_intrinsic(hlsl, TMin) + __target_intrinsic(cuda, TMin) float TMin; __target_intrinsic(hlsl, Direction) + __target_intrinsic(cuda, Direction) float3 Direction; __target_intrinsic(hlsl, TMax) + __target_intrinsic(cuda, TMax) float TMax; }; @@ -4303,6 +4308,7 @@ void CallShader(uint shaderIndex, inout Payload payload) // 10.3.2 __target_intrinsic(hlsl) +__target_intrinsic(cuda, "traceOptiXRay") void TraceRay<payload_t>( RaytracingAccelerationStructure AccelerationStructure, uint RayFlags, diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp index 4c430cfa6..0a375cb56 100644 --- a/source/slang/slang-emit-cuda.cpp +++ b/source/slang/slang-emit-cuda.cpp @@ -788,6 +788,29 @@ bool CUDASourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu m_writer->emit(")getOptiXRayPayloadPtr()"); return true; } + case kIROp_GetOptiXHitAttribute: + { + auto typeToFetch = inst->getOperand(0); + auto idxInst = as<IRIntLit>(inst->getOperand(1)); + IRIntegerValue idx = idxInst->getValue(); + if (typeToFetch->getOp() == kIROp_FloatType) { + m_writer->emit("__int_as_float(optixGetAttribute_"); + } + else + { + m_writer->emit("optixGetAttribute_"); + } + m_writer->emit(idx); + if (typeToFetch->getOp() == kIROp_FloatType) + { + m_writer->emit("())"); + } + else + { + m_writer->emit("()"); + } + return true; + } default: break; } diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 17ae652ae..847ce1d80 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -501,6 +501,9 @@ INST(GpuForeach, gpuForeach, 3, 0) // a pointer represented by two payload registers. INST(GetOptiXRayPayloadPtr, getOptiXRayPayloadPtr, 0, 0) +// Wrapper for OptiX intrinsics used to load a single hit attribute +INST(GetOptiXHitAttribute, getOptiXHitAttribute, 1, 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 f500b100f..8025bb088 100644 --- a/source/slang/slang-ir-legalize-varying-params.cpp +++ b/source/slang/slang-ir-legalize-varying-params.cpp @@ -1067,6 +1067,83 @@ struct CUDAEntryPointVaryingParamLegalizeContext : EntryPointVaryingParamLegaliz return LayoutResourceKind::None; } + IRInst* emitOptiXAttributeFetch(int& ioBaseAttributeIndex, IRType* typeToFetch, IRBuilder* builder) { + if (auto structType = as<IRStructType>(typeToFetch)) + { + List<IRInst*> fieldVals; + for (auto field : structType->getFields()) + { + auto fieldType = field->getFieldType(); + auto fieldVal = emitOptiXAttributeFetch(ioBaseAttributeIndex, fieldType, builder); + if (!fieldVal) + return nullptr; + + fieldVals.add(fieldVal); + } + return builder->emitMakeStruct(typeToFetch, fieldVals); + } + else if (auto arrayType = as<IRArrayTypeBase>(typeToFetch)) + { + auto elementCountInst = as<IRIntLit>(arrayType->getElementCount()); + IRIntegerValue elementCount = elementCountInst->getValue(); + auto elementType = arrayType->getElementType(); + List<IRInst*> elementVals; + for (IRIntegerValue ii = 0; ii < elementCount; ++ii) + { + auto elementVal = emitOptiXAttributeFetch(ioBaseAttributeIndex, elementType, builder); + if (!elementVal) + return nullptr; + elementVals.add(elementVal); + } + return builder->emitMakeArray(typeToFetch, elementVals.getCount(), elementVals.getBuffer()); + } + else if (auto matType = as<IRMatrixType>(typeToFetch)) + { + auto rowCountInst = as<IRIntLit>(matType->getRowCount()); + if (rowCountInst) + { + auto rowType = builder->getVectorType(matType->getElementType(), matType->getColumnCount()); + IRType* elementType = rowType; + IRIntegerValue elementCount = rowCountInst->getValue(); + List<IRInst*> elementVals; + for (IRIntegerValue ii = 0; ii < elementCount; ++ii) + { + auto elementVal = emitOptiXAttributeFetch(ioBaseAttributeIndex, elementType, builder); + if (!elementVal) + return nullptr; + elementVals.add(elementVal); + } + return builder->emitIntrinsicInst(typeToFetch, kIROp_MakeMatrix, elementVals.getCount(), elementVals.getBuffer()); + } + } + else if (auto vecType = as<IRVectorType>(typeToFetch)) + { + auto elementCountInst = as<IRIntLit>(vecType->getElementCount()); + IRIntegerValue elementCount = elementCountInst->getValue(); + IRType* elementType = vecType->getElementType(); + List<IRInst*> elementVals; + for (IRIntegerValue ii = 0; ii < elementCount; ++ii) + { + auto elementVal = emitOptiXAttributeFetch(ioBaseAttributeIndex, elementType, builder); + if (!elementVal) + return nullptr; + elementVals.add(elementVal); + } + return builder->emitMakeVector(typeToFetch, elementVals.getCount(), elementVals.getBuffer()); + } + else if (auto basicType = as<IRBasicType>(typeToFetch)) + { + IRIntegerValue idx = ioBaseAttributeIndex; + auto idxInst = builder->getIntValue(builder->getIntType(), idx); + ioBaseAttributeIndex++; + IRInst* args[] = { typeToFetch, idxInst }; + IRInst* getAttr = builder->emitIntrinsicInst(typeToFetch, kIROp_GetOptiXHitAttribute, 2, args); + return getAttr; + } + + return nullptr; + } + void beginModuleImpl() SLANG_OVERRIDE { // Because many of the varying parameters are defined @@ -1198,9 +1275,9 @@ struct CUDAEntryPointVaryingParamLegalizeContext : EntryPointVaryingParamLegaliz { 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); + 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. @@ -1214,6 +1291,17 @@ struct CUDAEntryPointVaryingParamLegalizeContext : EntryPointVaryingParamLegaliz return diagnoseUnsupportedUserVal(info); }*/ } + case LayoutResourceKind::HitAttributes: { + IRBuilder builder(m_sharedBuilder); + builder.setInsertBefore(m_firstOrdinaryInst); + int ioBaseAttributeIndex = 0; + IRInst* getHitAttributes = emitOptiXAttributeFetch(/*ioBaseAttributeIndex*/ ioBaseAttributeIndex, /* type to fetch */info.type, /*the builder in use*/ &builder); + if (ioBaseAttributeIndex > 8) { + m_sink->diagnose(m_param, Diagnostics::unexpected, "the supplied hit attribute exceeds the maximum hit attribute structure size (32 bytes)"); + return LegalizedVaryingVal(); + } + return LegalizedVaryingVal::makeValue(getHitAttributes); + } default: return diagnoseUnsupportedUserVal(info); } diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 42a93f3f0..2568547a4 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -719,7 +719,7 @@ HLSLRayTracingLayoutRulesImpl kHLSLHitAttributesParameterLayoutRulesImpl(LayoutR // CUDARayTracingLayoutRulesImpl kCUDARayPayloadParameterLayoutRulesImpl(LayoutResourceKind::RayPayload); //CUDARayTracingLayoutRulesImpl kCUDACallablePayloadParameterLayoutRulesImpl(LayoutResourceKind::CallablePayload); -//CUDARayTracingLayoutRulesImpl kCUDAHitAttributesParameterLayoutRulesImpl(LayoutResourceKind::HitAttributes); +CUDARayTracingLayoutRulesImpl kCUDAHitAttributesParameterLayoutRulesImpl(LayoutResourceKind::HitAttributes); struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl { @@ -947,6 +947,10 @@ LayoutRulesImpl kCUDARayPayloadParameterLayoutRulesImpl_ = { &kCUDALayoutRulesFamilyImpl, &kCUDARayPayloadParameterLayoutRulesImpl, &kCUDAObjectLayoutRulesImpl, }; +LayoutRulesImpl kCUDAHitAttributesParameterLayoutRulesImpl_ = { + &kCUDALayoutRulesFamilyImpl, &kCUDAHitAttributesParameterLayoutRulesImpl, &kCUDAObjectLayoutRulesImpl, +}; + // GLSL cases LayoutRulesImpl kStd140LayoutRulesImpl_ = { @@ -1303,7 +1307,7 @@ LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getCallablePayloadParameterRules() } LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getHitAttributesParameterRules() { - return nullptr; + return &kCUDAHitAttributesParameterLayoutRulesImpl_; } LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getShaderRecordConstantBufferRules() { |
