summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/visual-studio/slang/slang.vcxproj2
-rw-r--r--build/visual-studio/slang/slang.vcxproj.filters6
-rw-r--r--source/slang/hlsl.meta.slang88
-rw-r--r--source/slang/slang-emit.cpp5
-rw-r--r--source/slang/slang-ir-hlsl-legalize.cpp93
-rw-r--r--source/slang/slang-ir-hlsl-legalize.h17
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--tests/nv-extensions/nv-ray-tracing-motion-blur.slang18
-rw-r--r--tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl127
-rw-r--r--tests/vkray/raygen-trace-ray-param-non-struct.slang94
-rw-r--r--tests/vkray/raygen-trace-ray-param-struct.slang76
-rw-r--r--tests/vkray/raygen.slang16
12 files changed, 405 insertions, 139 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj
index aca22890b..183f83abc 100644
--- a/build/visual-studio/slang/slang.vcxproj
+++ b/build/visual-studio/slang/slang.vcxproj
@@ -401,6 +401,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClInclude Include="..\..\..\source\slang\slang-ir-generics-lowering-context.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-glsl-legalize.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-glsl-liveness.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-hlsl-legalize.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-init-local-var.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-inline.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-insert-debug-value-store.h" />
@@ -628,6 +629,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
<ClCompile Include="..\..\..\source\slang\slang-ir-generics-lowering-context.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-glsl-legalize.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-glsl-liveness.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-hlsl-legalize.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-init-local-var.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-inline.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-insert-debug-value-store.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters
index 7b6b7de2c..5d5743c16 100644
--- a/build/visual-studio/slang/slang.vcxproj.filters
+++ b/build/visual-studio/slang/slang.vcxproj.filters
@@ -291,6 +291,9 @@
<ClInclude Include="..\..\..\source\slang\slang-ir-glsl-liveness.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-hlsl-legalize.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-init-local-var.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -968,6 +971,9 @@
<ClCompile Include="..\..\..\source\slang\slang-ir-glsl-liveness.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-hlsl-legalize.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-init-local-var.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index cd6de61b5..fa2a7ccb1 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -9572,6 +9572,26 @@ void CallShader(uint shaderIndex, inout Payload payload)
// 10.3.2
+// Some functions only accept a "struct type" parameter. The
+// following function addresses this issue by transforming non-struct
+// parameters into a struct.
+// side effect typed use locations (`inout`,`out`, etc.) are managed.
+__generic<T>
+__intrinsic_op($(kIROp_ForceVarIntoStructTemporarily))
+Ref<T> __forceVarIntoStructTemporarily(inout T maybeStruct);
+
+__target_intrinsic(hlsl, "TraceRay")
+[require(hlsl, raytracing)]
+__generic<payload_t>
+void __traceRayHLSL(
+ RaytracingAccelerationStructure AccelerationStructure,
+ uint RayFlags,
+ uint InstanceInclusionMask,
+ uint RayContributionToHitGroupIndex,
+ uint MultiplierForGeometryContributionToHitGroupIndex,
+ uint MissShaderIndex,
+ RayDesc Ray,
+ inout payload_t Payload);
__target_intrinsic(_GL_EXT_ray_tracing, "traceRayEXT")
[require(glsl, raytracing)]
@@ -9599,6 +9619,7 @@ __generic<Payload>
__intrinsic_op($(kIROp_GetVulkanRayTracingPayloadLocation))
int __rayPayloadLocation(__ref Payload payload);
+[ForceInline]
[require(glsl, raytracing)]
[require(spirv, raytracing)]
[require(hlsl, raytracing)]
@@ -9615,7 +9636,17 @@ void TraceRay(
{
__target_switch
{
- case hlsl: __intrinsic_asm "TraceRay";
+ case hlsl:
+ __traceRayHLSL(
+ AccelerationStructure,
+ RayFlags,
+ InstanceInclusionMask,
+ RayContributionToHitGroupIndex,
+ MultiplierForGeometryContributionToHitGroupIndex,
+ MissShaderIndex,
+ Ray,
+ __forceVarIntoStructTemporarily(Payload));
+ return;
case cuda: __intrinsic_asm "traceOptiXRay";
case glsl:
{
@@ -9673,6 +9704,20 @@ void TraceRay(
//
// https://github.com/KhronosGroup/GLSL/blob/master/extensions/nv/GLSL_NV_ray_tracing_motion_blur.txt
+__target_intrinsic(hlsl, "TraceMotionRay")
+[require(hlsl, raytracing_motionblur)]
+__generic<payload_t>
+void __traceMotionRayHLSL(
+ RaytracingAccelerationStructure AccelerationStructure,
+ uint RayFlags,
+ uint InstanceInclusionMask,
+ uint RayContributionToHitGroupIndex,
+ uint MultiplierForGeometryContributionToHitGroupIndex,
+ uint MissShaderIndex,
+ RayDesc Ray,
+ float CurrentTime,
+ inout payload_t Payload);
+
__glsl_extension(GL_NV_ray_tracing_motion_blur)
__target_intrinsic(glsl, "traceRayMotionNV")
[require(glsl, raytracing_motionblur)]
@@ -9690,6 +9735,7 @@ void __traceMotionRay(
float CurrentTime,
int PayloadLocation);
+[ForceInline]
[require(glsl, raytracing_motionblur)]
[require(spirv, raytracing_motionblur)]
[require(hlsl, raytracing_motionblur)]
@@ -9707,7 +9753,18 @@ void TraceMotionRay(
{
__target_switch
{
- case hlsl: __intrinsic_asm "TraceMotionRay";
+ case hlsl:
+ __traceMotionRayHLSL(
+ AccelerationStructure,
+ RayFlags,
+ InstanceInclusionMask,
+ RayContributionToHitGroupIndex,
+ MultiplierForGeometryContributionToHitGroupIndex,
+ MissShaderIndex,
+ Ray,
+ CurrentTime,
+ __forceVarIntoStructTemporarily(Payload));
+ return;
case glsl:
{
[__vulkanRayPayload]
@@ -11555,7 +11612,7 @@ struct HitObject
MultiplierForGeometryContributionToHitGroupIndex,
MissShaderIndex,
Ray,
- Payload,
+ __forceVarIntoStructTemporarily(Payload),
hitObj);
return hitObj;
}
@@ -11641,7 +11698,16 @@ struct HitObject
__target_switch
{
case hlsl:
- __intrinsic_asm "TraceMotionRay";
+ __traceMotionRayHLSL(
+ AccelerationStructure,
+ RayFlags,
+ InstanceInclusionMask,
+ RayContributionToHitGroupIndex,
+ MultiplierForGeometryContributionToHitGroupIndex,
+ MissShaderIndex,
+ Ray,
+ CurrentTime,
+ __forceVarIntoStructTemporarily(Payload));
case glsl:
{
[__vulkanRayPayload]
@@ -12143,6 +12209,14 @@ struct HitObject
}
}
+ __target_intrinsic(hlsl, "NvInvokeHitObject")
+ [require(hlsl, ser)]
+ __generic<payload_t>
+ static void __InvokeHLSL(
+ RaytracingAccelerationStructure AccelerationStructure,
+ HitObject HitOrMiss,
+ inout payload_t Payload);
+
/// Invokes closesthit or miss shading for the specified hit object. In case of a NOP HitObject, no
/// shader is invoked.
[__requiresNVAPI]
@@ -12157,7 +12231,11 @@ struct HitObject
{
__target_switch
{
- case hlsl: __intrinsic_asm "NvInvokeHitObject";
+ case hlsl:
+ __InvokeHLSL(
+ AccelerationStructure,
+ HitOrMiss,
+ __forceVarIntoStructTemporarily(Payload));
case glsl:
{
[__vulkanRayPayload]
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 70dddb4f6..f724b1941 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -28,6 +28,7 @@
#include "slang-ir-explicit-global-init.h"
#include "slang-ir-fuse-satcoop.h"
#include "slang-ir-glsl-legalize.h"
+#include "slang-ir-hlsl-legalize.h"
#include "slang-ir-insts.h"
#include "slang-ir-inline.h"
#include "slang-ir-legalize-array-return-type.h"
@@ -839,6 +840,10 @@ Result linkAndOptimizeIR(
break;
}
+ // Legalize non struct parameters that are expected to be structs for HLSL.
+ if(isD3DTarget(targetRequest))
+ legalizeNonStructParameterToStructForHLSL(irModule);
+
// Legalize `ImageSubscript` and constant buffer loads for GLSL.
switch (target)
{
diff --git a/source/slang/slang-ir-hlsl-legalize.cpp b/source/slang/slang-ir-hlsl-legalize.cpp
new file mode 100644
index 000000000..ccd480d8c
--- /dev/null
+++ b/source/slang/slang-ir-hlsl-legalize.cpp
@@ -0,0 +1,93 @@
+// slang-ir-hlsl-legalize.cpp
+#include "slang-ir-hlsl-legalize.h"
+
+#include <functional>
+
+#include "slang-ir.h"
+#include "slang-ir-insts.h"
+#include "slang-ir-inst-pass-base.h"
+#include "slang-ir-specialize-function-call.h"
+#include "slang-ir-util.h"
+
+namespace Slang
+{
+
+void searchChildrenForForceVarIntoStructTemporarily(IRModule* module, IRInst* inst)
+{
+ for(auto child : inst->getChildren())
+ {
+ switch(child->getOp())
+ {
+ case kIROp_Block:
+ {
+ searchChildrenForForceVarIntoStructTemporarily(module, child);
+ break;
+ }
+ case kIROp_Call:
+ {
+ auto call = as<IRCall>(child);
+ for(UInt i = 0; i < call->getArgCount(); i++)
+ {
+ auto arg = call->getArg(i);
+ if(arg->getOp() != kIROp_ForceVarIntoStructTemporarily)
+ continue;
+ auto forceStructArg = arg->getOperand(0);
+ auto forceStructBaseType = as<IRType>(forceStructArg->getDataType()->getOperand(0));
+ if(forceStructBaseType->getOp() == kIROp_StructType)
+ {
+ call->setArg(i, arg->getOperand(0));
+ continue;
+ }
+
+ // When `__forceVarIntoStructTemporarily` is called with a non-struct type parameter,
+ // we create a temporary struct and copy the parameter into the struct.
+ // This struct is then subsituted for the return of `__forceVarIntoStructTemporarily`.
+ // Optionally, if `__forceVarIntoStructTemporarily` is a parameter to a side effect type
+ // (`ref`, `out`, `inout`) we copy the struct back into our original non-struct parameter.
+ IRBuilder builder(call);
+
+ builder.setInsertBefore(call->getCallee());
+ auto structType = builder.createStructType();
+ StringBuilder structName;
+ builder.addNameHintDecoration(structType, UnownedStringSlice("ForceVarIntoStructTemporarily_t"));
+
+ auto elementBufferKey = builder.createStructKey();
+ builder.addNameHintDecoration(elementBufferKey, UnownedStringSlice("data"));
+ auto _dataField = builder.createStructField(structType, elementBufferKey, forceStructBaseType);
+
+ builder.setInsertBefore(call);
+ auto structVar = builder.emitVar(structType);
+ builder.addNameHintDecoration(structVar, UnownedStringSlice("forceVarIntoStructTemporarily"));
+ builder.emitStore(
+ builder.emitFieldAddress(builder.getPtrType(_dataField->getFieldType()), structVar, _dataField->getKey()),
+ builder.emitLoad(forceStructArg));
+
+ arg->replaceUsesWith(structVar);
+ arg->removeAndDeallocate();
+
+ auto argType = call->getCallee()->getDataType()->getOperand(i+1);
+ if (!isPtrLikeOrHandleType(argType))
+ continue;
+
+ builder.setInsertAfter(call);
+ builder.emitStore(
+ forceStructArg,
+ builder.emitFieldAddress(builder.getPtrType(_dataField->getFieldType()), structVar, _dataField->getKey()));
+ }
+ break;
+ }
+ }
+ }
+}
+
+void legalizeNonStructParameterToStructForHLSL(IRModule* module)
+{
+ for(auto globalInst : module->getGlobalInsts())
+ {
+ if (globalInst->getOp() != kIROp_Func)
+ continue;
+ searchChildrenForForceVarIntoStructTemporarily(module, globalInst);
+ }
+}
+
+} // namespace Slang
diff --git a/source/slang/slang-ir-hlsl-legalize.h b/source/slang/slang-ir-hlsl-legalize.h
new file mode 100644
index 000000000..3970dc364
--- /dev/null
+++ b/source/slang/slang-ir-hlsl-legalize.h
@@ -0,0 +1,17 @@
+// slang-ir-hlsl-legalize.h
+#pragma once
+#include"../core/slang-list.h"
+#include "slang-compiler.h"
+
+namespace Slang
+{
+
+class DiagnosticSink;
+class Session;
+
+struct IRFunc;
+struct IRModule;
+
+void legalizeNonStructParameterToStructForHLSL(IRModule* module);
+
+} \ No newline at end of file
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index e51f6dc95..25f331708 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -664,6 +664,8 @@ INST(GetVulkanRayTracingPayloadLocation, GetVulkanRayTracingPayloadLocation, 1,
INST(GetLegalizedSPIRVGlobalParamAddr, kIROp_GetLegalizedSPIRVGlobalParamAddr, 1, 0)
+INST(ForceVarIntoStructTemporarily, ForceVarIntoStructTemporarily, 1, 0)
+
INST(MakeArrayList, makeArrayList, 0, 0)
INST(MakeTensorView, makeTensorView, 0, 0)
INST(AllocateTorchTensor, allocTorchTensor, 0, 0)
diff --git a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang
index 753101d7e..f07bc6977 100644
--- a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang
+++ b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang
@@ -1,4 +1,6 @@
-//TEST:CROSS_COMPILE: -profile glsl_460+GL_EXT_ray_tracing -stage raygeneration -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK_SPV): -emit-spirv-directly -stage raygeneration -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK_HLSL): -stage raygeneration -entry main -target hlsl
+//TEST:SIMPLE(filecheck=CHECK_GLSL): -stage raygeneration -entry main -target glsl
#define TRACING_EPSILON 1e-6
@@ -45,8 +47,8 @@ void main()
(float(launchID.y) + 0.5f) / float(launchSize.y)
);
- float3 P = samplerPosition.Sample(sampler, inUV).rgb;
- float3 N = samplerNormal.Sample(sampler, inUV).rgb * 2.0 - 1.0;
+ float3 P = samplerPosition.SampleLevel(sampler, inUV, 0).rgb;
+ float3 N = samplerNormal.SampleLevel(sampler, inUV, 0).rgb * 2.0 - 1.0;
float3 lightPos = ubo.light.position.xyz;
float3 lightDelta = lightPos - P;
@@ -116,3 +118,13 @@ void main()
outputImage[launchID] = float4(color, 1.0);
}
+
+// CHECK_SPV: %{{.*}} = OpVariable %_ptr_RayPayload{{(NV)?}}_ReflectionRay{{.*}} RayPayload
+// CHECK_SPV: OpTraceRayMotionNV
+// CHECK_SPV: OpTraceRayKHR
+
+// CHECK_HLSL: TraceMotionRay
+// CHECK_HLSL: TraceRay
+
+// CHECK_GLSL: traceRayMotionNV(
+// CHECK_GLSL: traceRayEXT( \ No newline at end of file
diff --git a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl b/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
deleted file mode 100644
index 744ee2f44..000000000
--- a/tests/nv-extensions/nv-ray-tracing-motion-blur.slang.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-#version 460
-#extension GL_EXT_ray_tracing : require
-#extension GL_NV_ray_tracing_motion_blur : require
-layout(row_major) uniform;
-layout(row_major) buffer;
-layout(binding = 0)
-uniform texture2D samplerPosition_0;
-
-layout(binding = 2)
-uniform sampler sampler_0;
-
-layout(binding = 1)
-uniform texture2D samplerNormal_0;
-
-struct Light_0
-{
- vec4 position_0;
- vec4 color_0;
-};
-
-struct Uniforms_0
-{
- Light_0 light_0;
- vec4 viewPos_0;
- mat4x4 view_0;
- mat4x4 model_0;
-};
-
-layout(binding = 3)
-layout(std140) uniform _S1
-{
- Light_0 light_0;
- vec4 viewPos_0;
- mat4x4 view_0;
- mat4x4 model_0;
-}ubo_0;
-layout(binding = 5)
-uniform accelerationStructureEXT as_0;
-
-layout(rgba32f)
-layout(binding = 4)
-uniform image2D outputImage_0;
-
-struct ReflectionRay_0
-{
- float color_1;
-};
-
-layout(location = 0)
-rayPayloadEXT
-ReflectionRay_0 p_0;
-
-struct ShadowRay_0
-{
- float hitDistance_0;
-};
-
-layout(location = 1)
-rayPayloadEXT
-ShadowRay_0 p_1;
-
-struct RayDesc_0
-{
- vec3 Origin_0;
- float TMin_0;
- vec3 Direction_0;
- float TMax_0;
-};
-
-void TraceMotionRay_0(accelerationStructureEXT AccelerationStructure_0, uint RayFlags_0, uint InstanceInclusionMask_0, uint RayContributionToHitGroupIndex_0, uint MultiplierForGeometryContributionToHitGroupIndex_0, uint MissShaderIndex_0, RayDesc_0 Ray_0, float CurrentTime_0, inout ShadowRay_0 Payload_0)
-{
- p_1 = Payload_0;
- traceRayMotionNV(AccelerationStructure_0, RayFlags_0, InstanceInclusionMask_0, RayContributionToHitGroupIndex_0, MultiplierForGeometryContributionToHitGroupIndex_0, MissShaderIndex_0, Ray_0.Origin_0, Ray_0.TMin_0, Ray_0.Direction_0, Ray_0.TMax_0, CurrentTime_0, (1));
- Payload_0 = p_1;
- return;
-}
-
-float saturate_0(float x_0)
-{
- return clamp(x_0, 0.0, 1.0);
-}
-
-void TraceRay_0(accelerationStructureEXT AccelerationStructure_1, uint RayFlags_1, uint InstanceInclusionMask_1, uint RayContributionToHitGroupIndex_1, uint MultiplierForGeometryContributionToHitGroupIndex_1, uint MissShaderIndex_1, RayDesc_0 Ray_1, inout ReflectionRay_0 Payload_1)
-{
- p_0 = Payload_1;
- traceRayEXT(AccelerationStructure_1, RayFlags_1, InstanceInclusionMask_1, RayContributionToHitGroupIndex_1, MultiplierForGeometryContributionToHitGroupIndex_1, MissShaderIndex_1, Ray_1.Origin_0, Ray_1.TMin_0, Ray_1.Direction_0, Ray_1.TMax_0, (0));
- Payload_1 = p_0;
- return;
-}
-
-void main()
-{
- uvec3 _S2 = ((gl_LaunchIDEXT));
- ivec2 launchID_0 = ivec2(_S2.xy);
- uvec3 _S3 = ((gl_LaunchSizeEXT));
- ivec2 launchSize_0 = ivec2(_S3.xy);
- vec2 inUV_0 = vec2((float(launchID_0.x) + 0.5) / float(launchSize_0.x), (float(launchID_0.y) + 0.5) / float(launchSize_0.y));
- vec3 P_0 = (texture(sampler2D(samplerPosition_0,sampler_0), (inUV_0))).xyz;
- vec3 N_0 = (texture(sampler2D(samplerNormal_0,sampler_0), (inUV_0))).xyz * 2.0 - 1.0;
- vec3 lightDelta_0 = ubo_0.light_0.position_0.xyz - P_0;
- float lightDist_0 = length(lightDelta_0);
- vec3 L_0 = normalize(lightDelta_0);
- float _S4 = 1.0 / (lightDist_0 * lightDist_0);
- RayDesc_0 ray_0;
- ray_0.Origin_0 = P_0;
- ray_0.TMin_0 = 0.00000099999999747524;
- ray_0.Direction_0 = lightDelta_0;
- ray_0.TMax_0 = lightDist_0;
- ShadowRay_0 shadowRay_0;
- shadowRay_0.hitDistance_0 = 0.0;
- TraceMotionRay_0(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, 1.0, shadowRay_0);
- float atten_0;
- if(shadowRay_0.hitDistance_0 < lightDist_0)
- {
- atten_0 = 0.0;
- }
- else
- {
- atten_0 = _S4;
- }
- vec3 color_2 = ubo_0.light_0.color_0.xyz * saturate_0(dot(N_0, L_0)) * atten_0;
- ReflectionRay_0 reflectionRay_0;
- TraceRay_0(as_0, 1U, 255U, 0U, 0U, 2U, ray_0, reflectionRay_0);
- imageStore((outputImage_0), ivec2((uvec2(launchID_0))), vec4(color_2 + reflectionRay_0.color_1, 1.0));
- return;
-}
-
diff --git a/tests/vkray/raygen-trace-ray-param-non-struct.slang b/tests/vkray/raygen-trace-ray-param-non-struct.slang
new file mode 100644
index 000000000..c4451d941
--- /dev/null
+++ b/tests/vkray/raygen-trace-ray-param-non-struct.slang
@@ -0,0 +1,94 @@
+//TEST:SIMPLE(filecheck=CHECK): -target hlsl -stage raygeneration -entry main
+
+RaytracingAccelerationStructure as;
+
+RWStructuredBuffer<float> outputBuffer1;
+
+// addComplexity ensures the code does not optimize any `someInData1`
+void addComplexity1(inout float someInData1)
+{
+ someInData1 = outputBuffer1[1];
+}
+void addComplexity2(float dataIn)
+{
+ outputBuffer1[2] = dataIn;
+}
+
+void main()
+{
+ RayDesc ray;
+ ray.Origin = float3(0);
+ ray.TMin = 1e-6;
+ ray.Direction = float3(0,0,1);
+ ray.TMax = 100.0f;
+
+ // CHECK: ForceVarIntoStructTemporarily_t{{_[0-9]}} forceVarIntoStructTemporarily{{_[0-9]}};
+ float someInData1 = 5.0f;
+ addComplexity1(someInData1);
+
+ // CHECK: forceVarIntoStructTemporarily{{_[0-9]}}.data{{_[0-9]}} = {{.*}}
+ // CHECK: TraceRay(
+ // CHECK: {{.*}} = forceVarIntoStructTemporarily{{.*}}.data{{.*}};
+ TraceRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1;
+
+ // CHECK: forceVarIntoStructTemporarily{{_[0-9]}}.data{{_[0-9]}} = {{.*}}
+ // CHECK: TraceMotionRay(
+ // CHECK: {{.*}} = forceVarIntoStructTemporarily{{.*}}.data{{.*}};
+ TraceMotionRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ 0.0f,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1;
+
+ // CHECK: forceVarIntoStructTemporarily{{_[0-9]}}.data{{_[0-9]}} = {{.*}}
+ // CHECK: NvTraceRayHitObject(
+ // CHECK: {{.*}} = forceVarIntoStructTemporarily{{.*}}.data{{.*}};
+ HitObject::TraceRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1;
+
+ // CHECK: forceVarIntoStructTemporarily{{_[0-9]}}.data{{_[0-9]}} = {{.*}}
+ // CHECK: TraceMotionRay(
+ // CHECK: {{.*}} = forceVarIntoStructTemporarily{{.*}}.data{{.*}};
+ HitObject::TraceMotionRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ 0.0f,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1;
+
+ // CHECK: forceVarIntoStructTemporarily{{_[0-9]}}.data{{_[0-9]}} = {{.*}}
+ // CHECK: NvInvokeHitObject(
+ // CHECK: {{.*}} = forceVarIntoStructTemporarily{{.*}}.data{{.*}};
+ HitObject hitObject_HitOrMiss;
+ HitObject::Invoke(
+ as,
+ hitObject_HitOrMiss,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1;
+
+ addComplexity2(someInData1);
+} \ No newline at end of file
diff --git a/tests/vkray/raygen-trace-ray-param-struct.slang b/tests/vkray/raygen-trace-ray-param-struct.slang
new file mode 100644
index 000000000..d9a6d134a
--- /dev/null
+++ b/tests/vkray/raygen-trace-ray-param-struct.slang
@@ -0,0 +1,76 @@
+//TEST:SIMPLE(filecheck=CHECK): -target hlsl -stage raygeneration -entry main
+
+RaytracingAccelerationStructure as;
+
+struct testStruct
+{
+ int data;
+}
+
+RWStructuredBuffer<int> outputBuffer1;
+
+void main()
+{
+ RayDesc ray;
+ ray.Origin = float3(0);
+ ray.TMin = 1e-6;
+ ray.Direction = float3(0,0,1);
+ ray.TMax = 100.0f;
+
+ testStruct someInData1;
+ someInData1.data = 5;
+
+ // CHECK: TraceRay(
+ TraceRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1.data;
+
+ // CHECK: TraceMotionRay(
+ TraceMotionRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ 0.0f,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1.data;
+
+ // CHECK: NvTraceRayHitObject(
+ HitObject::TraceRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1.data;
+
+ // CHECK: TraceMotionRay(
+ HitObject::TraceMotionRay(as,
+ 1,
+ 0xff,
+ 0,
+ 0,
+ 2,
+ ray,
+ 0.0f,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1.data;
+
+ // CHECK: NvInvokeHitObject(
+ HitObject hitObject_HitOrMiss;
+ HitObject::Invoke(
+ as,
+ hitObject_HitOrMiss,
+ someInData1);
+ outputBuffer1[0] = outputBuffer1[0]+someInData1.data;
+} \ No newline at end of file
diff --git a/tests/vkray/raygen.slang b/tests/vkray/raygen.slang
index 18ac74d4b..d63b3a668 100644
--- a/tests/vkray/raygen.slang
+++ b/tests/vkray/raygen.slang
@@ -1,5 +1,6 @@
-//TEST:CROSS_COMPILE: -profile glsl_460+GL_EXT_ray_tracing -stage raygeneration -entry main -target spirv-assembly
-//TEST:SIMPLE(filecheck=CHECK): -emit-spirv-directly -stage raygeneration -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK_SPV): -emit-spirv-directly -stage raygeneration -entry main -target spirv-assembly
+//TEST:SIMPLE(filecheck=CHECK_HLSL): -stage raygeneration -entry main -target hlsl
+//TEST:SIMPLE(filecheck=CHECK_GLSL): -stage raygeneration -entry main -target glsl
#define TRACING_EPSILON 1e-6
@@ -116,5 +117,12 @@ void main()
outputImage[int2(gl_LaunchIDNV.xy)] = float4(color, 1.0);
}
-// CHECK: %{{.*}} = OpVariable %_ptr_RayPayload{{(NV)?}}_ReflectionRay{{.*}} RayPayload
-// CHECK: OpTraceRayKHR
+// CHECK_SPV: %{{.*}} = OpVariable %_ptr_RayPayload{{(NV)?}}_ReflectionRay{{.*}} RayPayload
+// CHECK_SPV: OpTraceRayKHR
+// CHECK_SPV: OpTraceRayKHR
+
+// CHECK_HLSL: TraceRay
+// CHECK_HLSL: TraceRay
+
+// CHECK_GLSL: traceRayEXT(
+// CHECK_GLSL: traceRayEXT( \ No newline at end of file