diff options
| -rw-r--r-- | source/slang/hlsl.meta.slang | 197 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 44 | ||||
| -rw-r--r-- | source/slang/slang.natvis | 26 | ||||
| -rw-r--r-- | tests/pipeline/ray-tracing/trace-ray-inline.slang | 172 | ||||
| -rw-r--r-- | tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl | 219 | ||||
| -rw-r--r-- | tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl | 238 |
6 files changed, 873 insertions, 23 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 77b371662..761016866 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -4678,6 +4678,9 @@ static const CANDIDATE_TYPE CANDIDATE_PROCEDURAL_PRIMITIVE = 1; // back to the user code at interesting events along the ray. // __target_intrinsic(hlsl, RayQuery) +__target_intrinsic(glsl, rayQueryEXT) +__glsl_extension(GL_EXT_ray_query) +__glsl_version(460) struct RayQuery <let rayFlags : RAY_FLAG = RAY_FLAG_NONE> { // Initialize the query object in a "fresh" state. @@ -4697,7 +4700,42 @@ struct RayQuery <let rayFlags : RAY_FLAG = RAY_FLAG_NONE> // `RayQuery` to get the effective ray flags, which // must obey any API-imposed restrictions. // - void TraceRayInline(RaytracingAccelerationStructure accelerationStructure, RAY_FLAG rayFlags, uint instanceInclusionMask, RayDesc ray); + __target_intrinsic(hlsl) + void TraceRayInline( + RaytracingAccelerationStructure accelerationStructure, + RAY_FLAG rayFlags, + uint instanceInclusionMask, + RayDesc ray); + + __target_intrinsic(glsl, "rayQueryInitializeEXT($0, $1, $2, $3, $4, $5, $6, $7)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) + void __rayQueryInitializeEXT( + RaytracingAccelerationStructure accelerationStructure, + RAY_FLAG rayFlags, + uint instanceInclusionMask, + float3 origin, + float tMin, + float3 direction, + float tMax); + + [__unsafeForceInlineEarly] + __specialized_for_target(glsl) + void TraceRayInline( + RaytracingAccelerationStructure accelerationStructure, + RAY_FLAG rayFlags, + uint instanceInclusionMask, + RayDesc ray) + { + __rayQueryInitializeEXT( + accelerationStructure, + rayFlags, + instanceInclusionMask, + ray.Origin, + ray.TMin, + ray.Direction, + ray.TMax); + } // Resume the ray query coroutine. // @@ -4713,6 +4751,9 @@ struct RayQuery <let rayFlags : RAY_FLAG = RAY_FLAG_NONE> // functions to appropriately handle the closest hit (it any) // that was found. // + __target_intrinsic(glsl, rayQueryProceedEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) bool Proceed(); // Causes the ray query to terminate. @@ -4721,6 +4762,9 @@ struct RayQuery <let rayFlags : RAY_FLAG = RAY_FLAG_NONE> // traversal has terminated, so that subsequent // `Proceed()` calls will return `false`. // + __target_intrinsic(glsl, rayQueryTerminateEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) void Abort(); // Get the type of candidate hit being considered. @@ -4732,73 +4776,210 @@ struct RayQuery <let rayFlags : RAY_FLAG = RAY_FLAG_NONE> // the kind of candidate hit that must be resolved by // user code. // + __target_intrinsic(glsl, "rayQueryGetIntersectionTypeEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) CANDIDATE_TYPE CandidateType(); // Access properties of a candidate hit. - // + + __target_intrinsic(glsl, "transpose(rayQueryGetIntersectionObjectToWorldEXT($0, false))") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3x4 CandidateObjectToWorld3x4(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionObjectToWorldEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float4x3 CandidateObjectToWorld4x3(); + + __target_intrinsic(glsl, "transpose(rayQueryGetIntersectionWorldToObjectEXT($0, false))") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3x4 CandidateWorldToObject3x4(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionWorldToObjectEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float4x3 CandidateWorldToObject4x3(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionInstanceCustomIndexEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CandidateInstanceIndex(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionInstanceIdEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CandidateInstanceID(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionGeometryIndexEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CandidateGeometryIndex(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionPrimitiveIndexEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CandidatePrimitiveIndex(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CandidateInstanceContributionToHitGroupIndex(); // Access properties of the ray being traced // in the object space of a candidate hit. - // + + __target_intrinsic(glsl, "rayQueryGetIntersectionObjectRayOriginEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3 CandidateObjectRayOrigin(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionObjectRayDirectionEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3 CandidateObjectRayDirection(); // Access properties of a candidate procedural primitive hit. - // + + __target_intrinsic(glsl, "rayQueryGetIntersectionCandidateAABBOpaqueEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) bool CandidateProceduralPrimitiveNonOpaque(); - // Access properties of a candidate no-opaque triangle hit. - // + // Access properties of a candidate non-opaque triangle hit. + + __target_intrinsic(glsl, "rayQueryGetIntersectionFrontFaceEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) bool CandidateTriangleFrontFace(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionBarycentricsEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float2 CandidateTriangleBarycentrics(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionTEXT($0, false)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float CandidateTriangleRayT(); // Commit the current non-opaque triangle hit. + __target_intrinsic(glsl, rayQueryConfirmIntersectionEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) void CommitNonOpaqueTriangleHit(); // Commit the current procedural primitive hit, with hit time `t`. + __target_intrinsic(glsl, rayQueryGenerateIntersectionEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) void CommitProceduralPrimitiveHit(float t); // Get the status of the committed (closest) hit, if any. + __target_intrinsic(glsl, "rayQueryGetIntersectionTypeEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) COMMITTED_STATUS CommittedStatus(); // Access properties of the committed hit. // + __target_intrinsic(glsl, "transpose(rayQueryGetIntersectionObjectToWorldEXT($0, true))") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3x4 CommittedObjectToWorld3x4(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionObjectToWorldEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float4x3 CommittedObjectToWorld4x3(); + + __target_intrinsic(glsl, "transpose(rayQueryGetIntersectionWorldToObjectEXT($0, true))") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3x4 CommittedWorldToObject3x4(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionWorldToObjectEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float4x3 CommittedWorldToObject4x3(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionTEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float CommittedRayT(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionInstanceCustomIndexEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CommittedInstanceIndex(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionInstanceIdEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CommittedInstanceID(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionGeometryIndexEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CommittedGeometryIndex(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionPrimitiveIndexEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CommittedPrimitiveIndex(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint CommittedInstanceContributionToHitGroupIndex(); // Access properties of the ray being traced // in the object space of a committed hit. - // + + __target_intrinsic(glsl, "rayQueryGetIntersectionObjectRayOriginEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3 CommittedObjectRayOrigin(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionObjectRayDirectionEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3 CommittedObjectRayDirection(); // Access properties of a committed triangle hit. - // + + __target_intrinsic(glsl, "rayQueryGetIntersectionFrontFaceEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) bool CommittedTriangleFrontFace(); + + __target_intrinsic(glsl, "rayQueryGetIntersectionBarycentricsEXT($0, true)") + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float2 CommittedTriangleBarycentrics(); // Access properties of the ray being traced. + + __target_intrinsic(glsl, rayQueryGetRayFlagsEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) uint RayFlags(); + + __target_intrinsic(glsl, rayQueryGetWorldRayOriginEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3 WorldRayOrigin(); + + __target_intrinsic(glsl, rayQueryGetWorldRayDirectionEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float3 WorldRayDirection(); + + __target_intrinsic(glsl, rayQueryGetRayTMinEXT) + __glsl_extension(GL_EXT_ray_query) + __glsl_version(460) float RayTMin(); } diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 7b784de8d..fb4417119 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -95,6 +95,7 @@ void GLSLSourceEmitter::_requireGLSLVersion(int version) CASE(430); CASE(440); CASE(450); + CASE(460); #undef CASE } @@ -1801,14 +1802,46 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) { case kIROp_RaytracingAccelerationStructureType: { - _requireRayTracing(); - + // Note: We have the problem here that we want to do `_requireRayTracing()`, + // but just based on the use of a ray-tracing acceleration structure we + // cannot know which extension the user means to use. The current options are: + // + // * GL_NV_ray_tracing + // * GL_EXT_ray_tracing + // * GL_EXT_ray_query + // + // The first two options there are basically equivalent extensions with + // different GLSL syntax. We end up requiring the user to opt in to + // `GL_NV_ray_tracing` using target capabilities, and will always default + // to `GL_EXT_ray_tracing` otherwise. + // if( getTargetCaps().implies(CapabilityAtom::GL_NV_ray_tracing) ) { + // If the user has explicitly opted in to `GL_NV_ray_tracing`, + // then we don't need to explicitly request the extentsion again. + // We know that the acceleration structure type will translate + // to the one from that extension: + // m_writer->emit("accelerationStructureNV"); } else { + // If the user does *not* opt into a specific extension, then we + // have the problem that either `GL_EXT_ray_tracing` or `GL_EXT_ray-query` + // could provide the `accelerationSturctureEXT` type, but there + // can be drivers that provide only one and not the other. + // + // Because we can't pick one upon just seeing the type, we need to + // emit the type here but *not* call `_requireRayTracing()` or + // anything like it, because we don't yet know the specific extension + // we should ask for. + // + // TODO: We might eventually want to have this step set a flag that + // will cause a compilation error if nothing else in the code requires + // a specific concrete ray-tracing extension. Ideally all of these + // details could be subusmed under the capability system sooner or + // later. + // m_writer->emit("accelerationStructureEXT"); } break; @@ -1827,6 +1860,13 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) return; } + auto decorated = getResolvedInstForDecorations(type); + if(auto targetIntrinsicDecor = findBestTargetIntrinsicDecoration(decorated)) + { + m_writer->emit(targetIntrinsicDecor->getDefinition()); + return; + } + SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled type"); } diff --git a/source/slang/slang.natvis b/source/slang/slang.natvis index 63ee313da..cb272f974 100644 --- a/source/slang/slang.natvis +++ b/source/slang/slang.natvis @@ -72,9 +72,9 @@ </Expand> </Type> <Type Name="Slang::IRInst"> - <DisplayString>{{{op}}}</DisplayString> + <DisplayString>{{{m_op}}}</DisplayString> <Expand> - <Item Name="[op]">op</Item> + <Item Name="[op]">m_op</Item> <Item Name="[type]">typeUse.usedValue</Item> <CustomListItems MaxItemsPerView="3"> <Variable Name="child" InitialValue="m_decorationsAndChildren.first"/> @@ -82,20 +82,20 @@ <If Condition="child == 0"> <Break/> </If> - <If Condition="child->op == Slang::kIROp_NameHintDecoration"> + <If Condition="child->m_op == Slang::kIROp_NameHintDecoration"> <Item Name="[name]">((Slang::IRStringLit*)(((Slang::IRUse*)(child + 1))->usedValue))->value.stringVal.chars,[((Slang::IRStringLit*)(((Slang::IRUse*)(child + 1))->usedValue))->value.stringVal.numChars]s8</Item> </If> - <If Condition="child->op == Slang::kIROp_ExportDecoration"> + <If Condition="child->m_op == Slang::kIROp_ExportDecoration"> <Item Name="[exportName]">((Slang::IRStringLit*)(((Slang::IRUse*)(child + 1))->usedValue))->value.stringVal.chars,[((Slang::IRStringLit*)(((Slang::IRUse*)(child + 1))->usedValue))->value.stringVal.numChars]s8</Item> </If> - <If Condition="child->op == Slang::kIROp_ImportDecoration"> + <If Condition="child->m_op == Slang::kIROp_ImportDecoration"> <Item Name="[importName]">((Slang::IRStringLit*)(((Slang::IRUse*)(child + 1))->usedValue))->value.stringVal.chars,[((Slang::IRStringLit*)(((Slang::IRUse*)(child + 1))->usedValue))->value.stringVal.numChars]s8</Item> </If> <Exec>child = child->next</Exec> </Loop> </CustomListItems> - <Item Name="[value]" Condition="op == Slang::kIROp_StringLit">((IRStringLit*)this)->value.stringVal.chars,[((IRStringLit*)this)->value.stringVal.numChars]s8</Item> - <Item Name="[value]" Condition="op == Slang::kIROp_IntLit">((IRIntLit*)this)->value.intVal</Item> + <Item Name="[value]" Condition="m_op == Slang::kIROp_StringLit">((IRStringLit*)this)->value.stringVal.chars,[((IRStringLit*)this)->value.stringVal.numChars]s8</Item> + <Item Name="[value]" Condition="m_op == Slang::kIROp_IntLit">((IRIntLit*)this)->value.intVal</Item> <!-- <Synthetic Name="[operands]"> <DisplayString>{{count = {operandCount}}}</DisplayString> @@ -120,14 +120,14 @@ <Exec>child = pOperandInst->m_decorationsAndChildren.first</Exec> <Exec>nameDecoration = 0</Exec> <Loop Condition="child != 0"> - <If Condition="child->op == Slang::kIROp_NameHintDecoration"> + <If Condition="child->m_op == Slang::kIROp_NameHintDecoration"> <Exec>nameDecoration = child</Exec> <Break/> </If> - <If Condition="child->op == Slang::kIROp_ExportDecoration && (nameDecoration == 0 || nameDecoration->op != Slang::kIROp_NameHintDecoration)"> + <If Condition="child->m_op == Slang::kIROp_ExportDecoration && (nameDecoration == 0 || nameDecoration->m_op != Slang::kIROp_NameHintDecoration)"> <Exec>nameDecoration = child</Exec> </If> - <If Condition="child->op == Slang::kIROp_ImportDecoration && (nameDecoration == 0 || nameDecoration->op != Slang::kIROp_NameHintDecoration)"> + <If Condition="child->m_op == Slang::kIROp_ImportDecoration && (nameDecoration == 0 || nameDecoration->m_op != Slang::kIROp_NameHintDecoration)"> <Exec>nameDecoration = child</Exec> </If> <Exec>child = child->next</Exec> @@ -149,14 +149,14 @@ <Exec>child = pItem->m_decorationsAndChildren.first </Exec> <Exec>nameDecoration = 0</Exec> <Loop Condition="child != 0"> - <If Condition="child->op == Slang::kIROp_NameHintDecoration"> + <If Condition="child->m_op == Slang::kIROp_NameHintDecoration"> <Exec>nameDecoration = child</Exec> <Break/> </If> - <If Condition="child->op == Slang::kIROp_ExportDecoration && (nameDecoration == 0 || nameDecoration->op != Slang::kIROp_NameHintDecoration)"> + <If Condition="child->m_op == Slang::kIROp_ExportDecoration && (nameDecoration == 0 || nameDecoration->m_op != Slang::kIROp_NameHintDecoration)"> <Exec>nameDecoration = child</Exec> </If> - <If Condition="child->op == Slang::kIROp_ImportDecoration && (nameDecoration == 0 || nameDecoration->op != Slang::kIROp_NameHintDecoration)"> + <If Condition="child->m_op == Slang::kIROp_ImportDecoration && (nameDecoration == 0 || nameDecoration->m_op != Slang::kIROp_NameHintDecoration)"> <Exec>nameDecoration = child</Exec> </If> <Exec>child = child->next</Exec> diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang b/tests/pipeline/ray-tracing/trace-ray-inline.slang new file mode 100644 index 000000000..30c32ee4f --- /dev/null +++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang @@ -0,0 +1,172 @@ +// trace-ray-inline.slang + +//TEST:CROSS_COMPILE:-target dxil-asm -stage compute -profile sm_6_5 -entry main +//TEST:CROSS_COMPILE:-target spirv-asm -stage compute -profile sm_6_5 -entry main + +// The goal of this shader is to use all the main pieces +// of functionality in DXR 1.1's `TraceRayInline` feature, +// to ensure that they survive translation to HLSL. + +// In order to trace rays, we need an acceleration structure. +// +RaytracingAccelerationStructure myAccelerationStructure; + +// We also need to decide what to do with hits/misses. +// The `TraceRayInline` approach eschews separate shader +// stages for RT, and instead expects users to write +// those operations as subroutines instead. +// +// We will mimic the style and naming of DXR 1.0 here +// to try and make the parallels clear. +// +// We start with a ray "payload" type that will be +// used for input/output on hit and miss shaders +// + +struct MyRayPayload +{ + int value; +}; + +// The first and simplest shader is the miss shader. +// +void myMiss(inout MyRayPayload payload) +{ + payload.value = 0; +} + +// Next, up is a closest hit shader for opaque triangles. +// +void myTriangleClosestHit(inout MyRayPayload payload) +{ + payload.value = 1; +} + +// In order to support alpha testing, we need an any-hit +// shader for triangles. +// +// In this case, the return value is used to specify +// whether the hit should be accepted (true) or ignored (false). +// +bool myTriangleAnyHit(inout MyRayPayload payload) +{ + return true; +} + +// Procedural primitives are different than triangles +// in that they need user-defined hit attributes. +// +struct MyProceduralHitAttrs { int value; } + +// Otherwise, the closest- and any-hit shaders +// for procedural primitives are similar to those +// for triangles. +// +void myProceduralClosestHit(inout MyRayPayload payload, MyProceduralHitAttrs attrs) +{ + payload.value = attrs.value; +} +bool myProceduralAnyHit(inout MyRayPayload payload) +{ + return true; +} + +// The new piece of the puzzle for procedural primitives +// is the intersection shader, which should be able to +// report zero or more intersections. +// +// For now we will only deal with the single-intersection +// case. +// +bool myProceduralIntersection(inout float tHit, inout MyProceduralHitAttrs hitAttrs) +{ + return true; +} + +// In order to kick of tracing we need the properties of a ray +// query to trace, so we will pipe those in via a constant buffer. +// +cbuffer C +{ + float3 origin; + float tMin; + float3 direction; + float tMax; + uint rayFlags; + uint instanceMask; + uint shouldStopAtFirstHit; +} + +// The actual tracing is handled by a compute shader, +// which here takes on the role of a ray generation shader. +// +void main(uint3 tid : SV_DispatchThreadID) +{ + uint index = tid.x; + + RayQuery<RAY_FLAG_NONE> query; + MyProceduralHitAttrs committedProceduralAttrs; + + MyRayPayload payload = { -1 }; + RayDesc ray = { origin, tMin, direction, tMax }; + query.TraceRayInline( + myAccelerationStructure, + rayFlags, + instanceMask, + ray); + + + for(;;) + { + if(!query.Proceed()) break; + + switch(query.CandidateType()) + { + case CANDIDATE_PROCEDURAL_PRIMITIVE: + { + MyProceduralHitAttrs candidateProceduralAttrs = { 0 }; + float tHit = 0.0f; + if(myProceduralIntersection(tHit, candidateProceduralAttrs)) + { + if(myProceduralAnyHit(payload)) + { + query.CommitProceduralPrimitiveHit(tHit); + committedProceduralAttrs = candidateProceduralAttrs; + if(shouldStopAtFirstHit) + query.Abort(); + } + } + } + break; + + case CANDIDATE_NON_OPAQUE_TRIANGLE: + { + if(myTriangleAnyHit(payload)) + { + query.CommitNonOpaqueTriangleHit(); + if(shouldStopAtFirstHit) + query.Abort(); + } + } + break; + + } + + + } + + switch(query.CommittedStatus()) + { + case COMMITTED_TRIANGLE_HIT: + myTriangleClosestHit(payload); + break; + + case COMMITTED_PROCEDURAL_PRIMITIVE_HIT: + myProceduralClosestHit(payload, committedProceduralAttrs); + break; + + case COMMITTED_NOTHING: + myMiss(payload); + break; + } +}
\ No newline at end of file diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl new file mode 100644 index 000000000..883742020 --- /dev/null +++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl @@ -0,0 +1,219 @@ +// trace-ray-inline.slang.glsl +//TEST_IGNORE_FILE: + +#version 460 +#extension GL_EXT_ray_query : require + +struct SLANG_ParameterGroup_C_0 +{ + vec3 origin_0; + float tMin_0; + vec3 direction_0; + float tMax_0; + uint rayFlags_0; + uint instanceMask_0; + uint shouldStopAtFirstHit_0; +}; + +layout(binding = 1) +layout(std140) uniform _S1 +{ + SLANG_ParameterGroup_C_0 _data; +} C_0; + +struct RayDesc_0 +{ + vec3 Origin_0; + float TMin_0; + vec3 Direction_0; + float TMax_0; +}; + +void RayQuery_TraceRayInline_0(rayQueryEXT this_0, accelerationStructureEXT accelerationStructure_0, uint rayFlags_1, uint instanceInclusionMask_0, RayDesc_0 ray_0) +{ + rayQueryInitializeEXT((this_0), (accelerationStructure_0), (rayFlags_1), (instanceInclusionMask_0), (ray_0.Origin_0), (ray_0.TMin_0), (ray_0.Direction_0), (ray_0.TMax_0)); + return; +} + +layout(binding = 0) +uniform accelerationStructureEXT myAccelerationStructure_0; + +struct MyProceduralHitAttrs_0 +{ + int value_0; +}; + +bool myProceduralIntersection_0(inout float tHit_0, inout MyProceduralHitAttrs_0 hitAttrs_0) +{ + return true; +} + +struct MyRayPayload_0 +{ + int value_1; +}; + +bool myProceduralAnyHit_0(inout MyRayPayload_0 payload_0) +{ + return true; +} + +bool myTriangleAnyHit_0(inout MyRayPayload_0 payload_1) +{ + return true; +} + +void myTriangleClosestHit_0(inout MyRayPayload_0 payload_2) +{ + payload_2.value_1 = 1; + return; +} + +void myProceduralClosestHit_0(inout MyRayPayload_0 payload_3, MyProceduralHitAttrs_0 attrs_0) +{ + payload_3.value_1 = attrs_0.value_0; + return; +} + +void myMiss_0(inout MyRayPayload_0 payload_4) +{ + payload_4.value_1 = 0; + return; +} + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void main() +{ + MyRayPayload_0 payload_5; + MyProceduralHitAttrs_0 committedProceduralAttrs_0; + MyProceduralHitAttrs_0 committedProceduralAttrs_1; + MyRayPayload_0 payload_6; + MyProceduralHitAttrs_0 committedProceduralAttrs_2; + MyRayPayload_0 payload_7; + MyProceduralHitAttrs_0 committedProceduralAttrs_3; + rayQueryEXT query_0; + MyRayPayload_0 _S2 = { -1 }; + RayDesc_0 ray_1 = { C_0._data.origin_0, C_0._data.tMin_0, C_0._data.direction_0, C_0._data.tMax_0 }; + RayQuery_TraceRayInline_0(query_0, myAccelerationStructure_0, C_0._data.rayFlags_0, C_0._data.instanceMask_0, ray_1); + MyProceduralHitAttrs_0 _S3; + payload_5 = _S2; + committedProceduralAttrs_0 = _S3; + for(;;) + { + bool _S4 = rayQueryProceedEXT(query_0); + if(!_S4) + { + break; + } + uint _S5 = (rayQueryGetIntersectionTypeEXT((query_0), false)); + switch(_S5) + { + case uint(1): + { + MyProceduralHitAttrs_0 candidateProceduralAttrs_0 = { 0 }; + float _S6; + _S6 = 0.00000000000000000000; + MyProceduralHitAttrs_0 _S7; + _S7 = candidateProceduralAttrs_0; + bool _S8 = myProceduralIntersection_0(_S6, _S7); + float tHit_1 = _S6; + MyProceduralHitAttrs_0 candidateProceduralAttrs_1 = _S7; + if(_S8) + { + MyRayPayload_0 _S9; + _S9 = payload_5; + bool _S10 = myProceduralAnyHit_0(_S9); + MyRayPayload_0 _S11 = _S9; + if(_S10) + { + rayQueryGenerateIntersectionEXT(query_0, tHit_1); + if(bool(C_0._data.shouldStopAtFirstHit_0)) + { + rayQueryTerminateEXT(query_0); + } + else + { + } + committedProceduralAttrs_1 = candidateProceduralAttrs_1; + } + else + { + committedProceduralAttrs_1 = committedProceduralAttrs_0; + } + payload_6 = _S11; + committedProceduralAttrs_2 = committedProceduralAttrs_1; + } + else + { + payload_6 = payload_5; + committedProceduralAttrs_2 = committedProceduralAttrs_0; + } + payload_7 = payload_6; + committedProceduralAttrs_3 = committedProceduralAttrs_2; + break; + } + case uint(0): + { + MyRayPayload_0 _S12; + _S12 = payload_5; + bool _S13 = myTriangleAnyHit_0(_S12); + MyRayPayload_0 _S14 = _S12; + if(_S13) + { + rayQueryConfirmIntersectionEXT(query_0); + if(bool(C_0._data.shouldStopAtFirstHit_0)) + { + rayQueryTerminateEXT(query_0); + } + else + { + } + } + else + { + } + payload_7 = _S14; + committedProceduralAttrs_3 = committedProceduralAttrs_0; + break; + } + default: + { + payload_7 = payload_5; + committedProceduralAttrs_3 = committedProceduralAttrs_0; + break; + } + } + payload_5 = payload_7; + committedProceduralAttrs_0 = committedProceduralAttrs_3; + } + uint _S15 = (rayQueryGetIntersectionTypeEXT((query_0), true)); + switch(_S15) + { + case uint(1): + { + MyRayPayload_0 _S16; + _S16 = payload_5; + myTriangleClosestHit_0(_S16); + break; + } + case uint(2): + { + MyRayPayload_0 _S17; + _S17 = payload_5; + myProceduralClosestHit_0(_S17, committedProceduralAttrs_0); + break; + } + case uint(0): + { + MyRayPayload_0 _S18; + _S18 = payload_5; + myMiss_0(_S18); + break; + } + default: + { + break; + } + } + return; +} diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl b/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl new file mode 100644 index 000000000..cdea1668a --- /dev/null +++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl @@ -0,0 +1,238 @@ +// trace-ray-inline.slang.hlsl +//TEST_IGNORE_FILE: + +struct SLANG_ParameterGroup_C_0 +{ + vector<float,3> origin_0; + float tMin_0; + vector<float,3> direction_0; + float tMax_0; + uint rayFlags_0; + uint instanceMask_0; + uint shouldStopAtFirstHit_0; +}; + +cbuffer C_0 : register(b0) +{ + SLANG_ParameterGroup_C_0 C_0; +} + +RaytracingAccelerationStructure myAccelerationStructure_0 : register(t0); + +struct MyProceduralHitAttrs_0 +{ + int value_0; +}; + +bool myProceduralIntersection_0(inout float tHit_0, inout MyProceduralHitAttrs_0 hitAttrs_0) +{ + return true; +} + +struct MyRayPayload_0 +{ + int value_1; +}; + +bool myProceduralAnyHit_0(inout MyRayPayload_0 payload_0) +{ + return true; +} + +bool myTriangleAnyHit_0(inout MyRayPayload_0 payload_1) +{ + return true; +} + +void myTriangleClosestHit_0(inout MyRayPayload_0 payload_2) +{ + payload_2.value_1 = int(1); + return; +} + +void myProceduralClosestHit_0(inout MyRayPayload_0 payload_3, MyProceduralHitAttrs_0 attrs_0) +{ + payload_3.value_1 = attrs_0.value_0; + return; +} + +void myMiss_0(inout MyRayPayload_0 payload_4) +{ + payload_4.value_1 = int(0); + return; +} + + +[shader("compute")] +[numthreads(1, 1, 1)] +void main(vector<uint,3> tid_0 : SV_DISPATCHTHREADID) +{ + MyRayPayload_0 payload_5; + MyProceduralHitAttrs_0 committedProceduralAttrs_0; + MyProceduralHitAttrs_0 committedProceduralAttrs_1; + MyRayPayload_0 payload_6; + MyProceduralHitAttrs_0 committedProceduralAttrs_2; + MyRayPayload_0 payload_7; + MyProceduralHitAttrs_0 committedProceduralAttrs_3; + + RayQuery<int(0) > query_0; + + MyRayPayload_0 _S1 = { int(-1) }; + RayDesc ray_0 = { C_0.origin_0, C_0.tMin_0, C_0.direction_0, C_0.tMax_0 }; + query_0.TraceRayInline(myAccelerationStructure_0, C_0.rayFlags_0, C_0.instanceMask_0, ray_0); + + MyProceduralHitAttrs_0 _S2; + + payload_5 = _S1; + committedProceduralAttrs_0 = _S2; + for(;;) + { + bool _S3 = query_0.Proceed(); + + if(!_S3) + { + break; + } + uint _S4 = query_0.CandidateType(); + + switch(_S4) + { + case (uint) int(1): + { + MyProceduralHitAttrs_0 candidateProceduralAttrs_0 = { int(0) }; + + float _S5; + + _S5 = 0.00000000000000000000; + + MyProceduralHitAttrs_0 _S6; + + _S6 = candidateProceduralAttrs_0; + + bool _S7 = myProceduralIntersection_0(_S5, _S6); + + float tHit_1 = _S5; + + MyProceduralHitAttrs_0 candidateProceduralAttrs_1 = _S6; + + if(_S7) + { + MyRayPayload_0 _S8; + + _S8 = payload_5; + + bool _S9 = myProceduralAnyHit_0(_S8); + + MyRayPayload_0 _S10 = _S8; + + if(_S9) + { + query_0.CommitProceduralPrimitiveHit(tHit_1); + + if((bool) C_0.shouldStopAtFirstHit_0) + { + + query_0.Abort(); + } + else + { + } + + committedProceduralAttrs_1 = candidateProceduralAttrs_1; + } + else + { + committedProceduralAttrs_1 = committedProceduralAttrs_0; + } + + payload_6 = _S10; + committedProceduralAttrs_2 = committedProceduralAttrs_1; + } + else + { + payload_6 = payload_5; + committedProceduralAttrs_2 = committedProceduralAttrs_0; + } + + payload_7 = payload_6; + committedProceduralAttrs_3 = committedProceduralAttrs_2; + break; + } + case (uint) int(0): + { + MyRayPayload_0 _S11; + _S11 = payload_5; + + bool _S12 = myTriangleAnyHit_0(_S11); + MyRayPayload_0 _S13 = _S11; + + if(_S12) + { + query_0.CommitNonOpaqueTriangleHit(); + if((bool) C_0.shouldStopAtFirstHit_0) + { + query_0.Abort(); + } + else + { + } + } + else + { + } + + payload_7 = _S13; + committedProceduralAttrs_3 = committedProceduralAttrs_0; + break; + } + default: + { + payload_7 = payload_5; + committedProceduralAttrs_3 = committedProceduralAttrs_0; + break; + } + } + + payload_5 = payload_7; + committedProceduralAttrs_0 = committedProceduralAttrs_3; + } + + uint _S14 = query_0.CommittedStatus(); + + switch(_S14) + { + case (uint) int(1): + { + MyRayPayload_0 _S15; + + _S15 = payload_5; + + myTriangleClosestHit_0(_S15); + break; + } + case (uint) int(2): + { + + MyRayPayload_0 _S16; + _S16 = payload_5; + + myProceduralClosestHit_0(_S16, committedProceduralAttrs_0); + break; + } + case (uint) int(0): + { + MyRayPayload_0 _S17; + + _S17 = payload_5; + + myMiss_0(_S17); + break; + } + default: + { + break; + } + } + + return; +} |
