summaryrefslogtreecommitdiff
path: root/tests/pipeline
diff options
context:
space:
mode:
authorTheresa Foley <10618364+tangent-vector@users.noreply.github.com>2023-06-13 14:40:02 -0700
committerGitHub <noreply@github.com>2023-06-13 17:40:02 -0400
commitf161686e8e260a4b0e6e0a773cf1cf16069f41bf (patch)
tree1daf16da7f0826eb26cf352b0fab9aa1c61b4327 /tests/pipeline
parentb255ef068b77a45fdd0b595a555386928a61d56e (diff)
Fixes for Shader Execution Reordering on VK (#2929)
* Fixes for Shader Execution Reordering on VK There are some mismatches between the way that hit objects are handled between the current NVAPI/HLSL and proposed GLSL extensions for shader execution reordering. These mismatches create complications for generating valid GLSL/SPIR-V code from input Slang. Many of the problems that apply to `HitObject` also apply to the existing `RayQuery<>` type used for "inline" ray tracing. In the case of `RayQuery<>` we have that for *both* HLSL and GLSL/SPIR-V: * A `RayQuery` (or `rayQueryEXT`) is an opaque handle to underlying mutable storage * The storage that backs a `RayQuery` is allocated as part of the "defualt constructor" for a local variable declared with type `RayQuery`. * The `RayQuery` API provides numerous operations that mutate the storage referred to by the opaque handle. The key difference between HLSL and GLSL/SPIR-V for the case of a `RayQuery` amounts to: * In HLSL, local variables of type `RayQuery` can be assigned to, and assignment has by-reference semantics. It is possible to create multiple aliased handles to the same underlying storage. * In GLSL/SPIR-V, local variables of type `rayQueryEXT` cannot be assigned to, returned from functions, etc. It is impossible to create multiple aliased handles to the same underlying storage. The case for `HitObject`s is signicantly *more* messy, because: * In NVAPI/HLSL a `HitObject` is effectively a "value type" in that it only exposes constructors, and there is no way to mutate the state of a `HitObject` other than by assignment to a variable of that type. It makes no semantic difference whether a `HitObject` directly stores the value(s), or if it is a handle, since there is no way to introduce aliasing of mutable state. Assignment of `HitObject`s semantically creates a copy. * In GLSL/SPIR-V, a `hitObjectNV` is, like a `rayQueryEXT`, a handle to underlying mutable state. These handles cannot be assigned, returned from functions, etc. There is no way to make a copy of a hit object. This change includes several changes to how *both* `RayQuery<>` and `HitObject` are implemented, with the intention of getting more cases to work correctly when compiling for GLSL/SPIR-V, and to set up a more clear mental model for the semantics we want to give to these types in Slang, and how those semantics can/should map to our targets. An overview of important changes: * Marked a few operations on `RayQuery` as `[mutating]` that realistically should have already been that way. * Marked the `HitObject` type as being non-copyable (an attribute we do not currently enforce), and marked the various GLSL operations that construct a hit object as having an `out` parameter of the `HitObject` type (even if they are nominally specified in GLSL as not writing to the correspondign parameter). * Added a distinct IR opcode (`allocateOpaqueHandle`) to represent the implicit allocation that happens when declaring a variable of type `HitObject` or `RayQuery`, and made the "implicit constructor" for those types map to the new op. This operation took a lot of tweaking to get emitting in a reasonable way, and I'm still not 100% sure that all of the emission-related logic for it is strictly required (or correct). * Added new IR instructions for `HitObject` and `RayQuery` types, and made the stdlib types map to those IR instructions. * Treat `HitObject` and `RayQuery` as resource types for the purpose of our existing pass that specializes calls to functions that have outputs of resource type * Added a new test case that includes a function that returns a `HitObject` as its result. * Many test cases saw slight changes in their output (especially around the relative ordering of declarations of `HitObject`s and `RayQuery`s with other instructions) * Remove debugging logic
Diffstat (limited to 'tests/pipeline')
-rw-r--r--tests/pipeline/ray-tracing/trace-ray-inline.slang4
-rw-r--r--tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl138
-rw-r--r--tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl118
3 files changed, 21 insertions, 239 deletions
diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang b/tests/pipeline/ray-tracing/trace-ray-inline.slang
index e952bb802..23ec90885 100644
--- a/tests/pipeline/ray-tracing/trace-ray-inline.slang
+++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang
@@ -1,7 +1,7 @@
// 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 glsl_460+spirv_1_4 -entry main
+//TEST:CROSS_COMPILE:-target dxil-asm -stage compute -profile sm_6_5 -entry main -line-directive-mode none
+//TEST:CROSS_COMPILE:-target spirv-asm -stage compute -profile glsl_460+spirv_1_4 -entry main -line-directive-mode none
// The goal of this shader is to use all the main pieces
// of functionality in DXR 1.1's `TraceRayInline` feature,
diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
index 56926e956..e1a54a30a 100644
--- a/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
+++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang.glsl
@@ -3,8 +3,6 @@
#extension GL_EXT_ray_query : require
layout(row_major) uniform;
layout(row_major) buffer;
-
-#line 91 "tests/pipeline/ray-tracing/trace-ray-inline.slang"
struct SLANG_ParameterGroup_C_0
{
vec3 origin_0;
@@ -16,8 +14,6 @@ struct SLANG_ParameterGroup_C_0
uint shouldStopAtFirstHit_0;
};
-
-#line 91
layout(binding = 2)
layout(std140) uniform _S1
{
@@ -29,267 +25,159 @@ layout(std140) uniform _S1
uint instanceMask_0;
uint shouldStopAtFirstHit_0;
}C_0;
-
-#line 12
layout(binding = 0)
uniform accelerationStructureEXT myAccelerationStructure_0;
-
-#line 86
layout(std430, binding = 1) buffer _S2 {
int _data[];
} resultBuffer_0;
-
-#line 59
struct MyProceduralHitAttrs_0
{
int value_0;
};
-
-#line 81
bool myProceduralIntersection_0(inout float tHit_0, inout MyProceduralHitAttrs_0 hitAttrs_0)
{
return true;
}
-
-#line 26
struct MyRayPayload_0
{
int value_1;
};
-
-#line 69
bool myProceduralAnyHit_0(inout MyRayPayload_0 payload_0)
{
return true;
}
-
-#line 51
bool myTriangleAnyHit_0(inout MyRayPayload_0 payload_1)
{
return true;
}
-
-#line 40
void myTriangleClosestHit_0(inout MyRayPayload_0 payload_2)
{
payload_2.value_1 = 1;
return;
}
-
-#line 65
void myProceduralClosestHit_0(inout MyRayPayload_0 payload_3, MyProceduralHitAttrs_0 attrs_0)
{
payload_3.value_1 = attrs_0.value_0;
return;
}
-
-#line 33
void myMiss_0(inout MyRayPayload_0 payload_4)
{
payload_4.value_1 = 0;
return;
}
-
-#line 105
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main()
{
-
-#line 107
uint index_0 = gl_GlobalInvocationID.x;
-
-#line 112
+ rayQueryEXT query_0;
MyRayPayload_0 payload_5;
-
-#line 112
payload_5.value_1 = -1;
-
-#line 109
- rayQueryEXT query_0;
-
-#line 114
rayQueryInitializeEXT((query_0), (myAccelerationStructure_0), (C_0.rayFlags_0 | 512), (C_0.instanceMask_0), (C_0.origin_0), (C_0.tMin_0), (C_0.direction_0), (C_0.tMax_0));
-
-#line 114
MyProceduralHitAttrs_0 committedProceduralAttrs_0;
-
-#line 114
for(;;)
{
-
-#line 123
bool _S3 = rayQueryProceedEXT(query_0);
-
-#line 123
if(!_S3)
{
-
-#line 123
break;
}
-
-#line 123
+ uint _S4 = (rayQueryGetIntersectionTypeEXT((query_0), false));
MyProceduralHitAttrs_0 committedProceduralAttrs_1;
-
- switch((rayQueryGetIntersectionTypeEXT((query_0), false)))
+ switch(_S4)
{
case 1U:
{
MyProceduralHitAttrs_0 candidateProceduralAttrs_0;
-
-#line 129
candidateProceduralAttrs_0.value_0 = 0;
float tHit_1 = 0.0;
- bool _S4 = myProceduralIntersection_0(tHit_1, candidateProceduralAttrs_0);
-
-#line 131
- if(_S4)
+ bool _S5 = myProceduralIntersection_0(tHit_1, candidateProceduralAttrs_0);
+ if(_S5)
{
- bool _S5 = myProceduralAnyHit_0(payload_5);
-
-#line 133
- if(_S5)
+ bool _S6 = myProceduralAnyHit_0(payload_5);
+ if(_S6)
{
rayQueryGenerateIntersectionEXT(query_0, tHit_1);
- MyProceduralHitAttrs_0 _S6 = candidateProceduralAttrs_0;
+ MyProceduralHitAttrs_0 _S7 = candidateProceduralAttrs_0;
if(C_0.shouldStopAtFirstHit_0 != 0U)
{
-
-#line 138
rayQueryTerminateEXT(query_0);
-
-#line 137
}
else
{
-
-#line 137
}
-
-#line 137
- committedProceduralAttrs_1 = _S6;
-
-#line 137
+ committedProceduralAttrs_1 = _S7;
}
else
{
-
-#line 137
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 137
}
-
-#line 137
}
else
{
-
-#line 137
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 137
}
-
-#line 137
break;
}
case 0U:
{
-
-#line 146
- bool _S7 = myTriangleAnyHit_0(payload_5);
-
-#line 146
- if(_S7)
+ bool _S8 = myTriangleAnyHit_0(payload_5);
+ if(_S8)
{
rayQueryConfirmIntersectionEXT(query_0);
if(C_0.shouldStopAtFirstHit_0 != 0U)
{
-
-#line 150
rayQueryTerminateEXT(query_0);
-
-#line 149
}
else
{
-
-#line 149
}
-
-#line 146
}
else
{
-
-#line 146
}
-
-#line 146
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 146
break;
}
default:
{
-
-#line 146
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 146
break;
}
}
-
-#line 121
committedProceduralAttrs_0 = committedProceduralAttrs_1;
-
-#line 121
}
-
-#line 160
- switch((rayQueryGetIntersectionTypeEXT((query_0), true)))
+ uint _S9 = (rayQueryGetIntersectionTypeEXT((query_0), true));
+ switch(_S9)
{
case 1U:
{
-
-#line 163
myTriangleClosestHit_0(payload_5);
break;
}
case 2U:
{
-
-#line 167
myProceduralClosestHit_0(payload_5, committedProceduralAttrs_0);
break;
}
case 0U:
{
-
-#line 171
myMiss_0(payload_5);
break;
}
default:
{
-
-#line 172
break;
}
}
((resultBuffer_0)._data[(index_0)]) = payload_5.value_1;
return;
}
-
diff --git a/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl b/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl
index e96cbb8f4..bf10cc2e1 100644
--- a/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl
+++ b/tests/pipeline/ray-tracing/trace-ray-inline.slang.hlsl
@@ -1,11 +1,5 @@
#pragma pack_matrix(column_major)
-#ifdef SLANG_HLSL_ENABLE_NVAPI
-#include "nvHLSLExtns.h"
-#endif
-#pragma warning(disable: 3557)
-
-#line 91 "tests/pipeline/ray-tracing/trace-ray-inline.slang"
struct SLANG_ParameterGroup_C_0
{
float3 origin_0;
@@ -17,272 +11,172 @@ struct SLANG_ParameterGroup_C_0
uint shouldStopAtFirstHit_0;
};
-
-#line 91
cbuffer C_0 : register(b0)
{
SLANG_ParameterGroup_C_0 C_0;
}
-#line 12
RaytracingAccelerationStructure myAccelerationStructure_0 : register(t0);
-
-#line 86
RWStructuredBuffer<int > resultBuffer_0 : register(u0);
-
-#line 59
struct MyProceduralHitAttrs_0
{
int value_0;
};
-
-#line 81
bool myProceduralIntersection_0(inout float tHit_0, inout MyProceduralHitAttrs_0 hitAttrs_0)
{
return true;
}
-
-#line 26
struct MyRayPayload_0
{
int value_1;
};
-
-#line 69
bool myProceduralAnyHit_0(inout MyRayPayload_0 payload_0)
{
return true;
}
-
-#line 51
bool myTriangleAnyHit_0(inout MyRayPayload_0 payload_1)
{
return true;
}
-
-#line 40
void myTriangleClosestHit_0(inout MyRayPayload_0 payload_2)
{
payload_2.value_1 = int(1);
return;
}
-
-#line 65
void myProceduralClosestHit_0(inout MyRayPayload_0 payload_3, MyProceduralHitAttrs_0 attrs_0)
{
payload_3.value_1 = attrs_0.value_0;
return;
}
-
-#line 33
void myMiss_0(inout MyRayPayload_0 payload_4)
{
payload_4.value_1 = int(0);
return;
}
-
-#line 105
[shader("compute")][numthreads(1, 1, 1)]
void main(uint3 tid_0 : SV_DISPATCHTHREADID)
{
-
-#line 107
uint index_0 = tid_0.x;
+ RayQuery<int(512) > query_0;
-#line 112
MyRayPayload_0 payload_5;
-
-#line 112
payload_5.value_1 = int(-1);
- RayDesc ray_0 = { C_0.origin_0, C_0.tMin_0, C_0.direction_0, C_0.tMax_0 };
-#line 109
- RayQuery<int(512) > query_0;
+ RayDesc ray_0 = { C_0.origin_0, C_0.tMin_0, C_0.direction_0, C_0.tMax_0 };
-#line 114
query_0.TraceRayInline(myAccelerationStructure_0, C_0.rayFlags_0, C_0.instanceMask_0, ray_0);
-#line 114
MyProceduralHitAttrs_0 committedProceduralAttrs_0;
-#line 114
for(;;)
{
-#line 123
bool _S1 = query_0.Proceed();
-#line 123
if(!_S1)
{
-#line 123
break;
}
-#line 123
MyProceduralHitAttrs_0 committedProceduralAttrs_1;
-
switch(query_0.CandidateType())
{
case 1U:
{
MyProceduralHitAttrs_0 candidateProceduralAttrs_0;
-
-#line 129
candidateProceduralAttrs_0.value_0 = int(0);
+
float tHit_1 = 0.0;
bool _S2 = myProceduralIntersection_0(tHit_1, candidateProceduralAttrs_0);
-
-#line 131
if(_S2)
{
bool _S3 = myProceduralAnyHit_0(payload_5);
-
-#line 133
if(_S3)
{
query_0.CommitProceduralPrimitiveHit(tHit_1);
MyProceduralHitAttrs_0 _S4 = candidateProceduralAttrs_0;
if(C_0.shouldStopAtFirstHit_0 != 0U)
{
-
-#line 138
query_0.Abort();
-
-#line 137
}
else
- {
-
-#line 137
- }
+ {}
-#line 137
committedProceduralAttrs_1 = _S4;
-
-#line 137
}
else
{
-
-#line 137
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 137
}
-
-#line 137
}
else
{
-
-#line 137
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 137
}
-
-#line 137
break;
}
case 0U:
{
-
-#line 146
bool _S5 = myTriangleAnyHit_0(payload_5);
-
-#line 146
if(_S5)
{
query_0.CommitNonOpaqueTriangleHit();
if(C_0.shouldStopAtFirstHit_0 != 0U)
{
-
-#line 150
query_0.Abort();
-
-#line 149
}
else
- {
-
-#line 149
- }
-
-#line 146
+ {}
}
else
- {
-
-#line 146
- }
+ {}
-#line 146
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 146
break;
}
default:
{
-
-#line 146
committedProceduralAttrs_1 = committedProceduralAttrs_0;
-
-#line 146
break;
}
}
-#line 121
committedProceduralAttrs_0 = committedProceduralAttrs_1;
-
-#line 121
}
-#line 160
switch(query_0.CommittedStatus())
{
case 1U:
{
-
-#line 163
myTriangleClosestHit_0(payload_5);
break;
}
case 2U:
{
-
-#line 167
myProceduralClosestHit_0(payload_5, committedProceduralAttrs_0);
break;
}
case 0U:
{
-
-#line 171
myMiss_0(payload_5);
break;
}
default:
{
-
-#line 172
break;
}
}
resultBuffer_0[index_0] = payload_5.value_1;
return;
}
-