summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDarren Wihandi <65404740+fairywreath@users.noreply.github.com>2025-01-18 02:07:16 -0500
committerGitHub <noreply@github.com>2025-01-17 23:07:16 -0800
commita85c350df03c6cdf9b433f58fc0e66affda03e9e (patch)
tree3e80ea7121b3b5bb5c17aee88599212b78abec38 /tests
parent87a08160289c194ddfb337d521893f576ceb9f97 (diff)
Implement Quad Control intrinsics (#5981)
Diffstat (limited to 'tests')
-rw-r--r--tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang40
-rw-r--r--tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang.expected.txt16
-rw-r--r--tests/hlsl-intrinsic/quad-control/quad-control-frag-many-entry-points.slang96
-rw-r--r--tests/hlsl-intrinsic/quad-control/quad-control-frag.slang53
4 files changed, 205 insertions, 0 deletions
diff --git a/tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang b/tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang
new file mode 100644
index 000000000..c8f82772d
--- /dev/null
+++ b/tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang
@@ -0,0 +1,40 @@
+//TEST(compute):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -emit-spirv-directly
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -profile cs_6_7 -dx12 -use-dxil -shaderobj -render-feature hardware-device
+//TEST(compute):COMPARE_COMPUTE_EX:-metal -compute -shaderobj
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<uint> outputBuffer;
+
+[numthreads(16, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ uint index = dispatchThreadID.x;
+
+ if (index < 4)
+ {
+ // Quad 1.
+ // Should return true, index 0's expr is true while all other indices' expr are false.
+ outputBuffer[index] = uint(QuadAny((index % 4) == 0));
+ }
+ else if (index < 8)
+ {
+ // Quad 2.
+ // Should return false, all indices' expr are false.
+ bool falseCondition = (5 == 4);
+ outputBuffer[index] = uint(QuadAny(falseCondition));
+ }
+ else if (index < 12)
+ {
+ // Quad 3.
+ // Should return false, index 0's expr is true while all other indices' expr are false.
+ outputBuffer[index] = uint(QuadAll((index % 4) == 0));
+ }
+ else
+ {
+ // Quad 4.
+ // Should return true, all indices' expr are true.
+ bool trueCondition = (5 == 5);
+ outputBuffer[index] = uint(QuadAll(trueCondition));
+ }
+}
+
diff --git a/tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang.expected.txt b/tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang.expected.txt
new file mode 100644
index 000000000..945f08f2c
--- /dev/null
+++ b/tests/hlsl-intrinsic/quad-control/quad-control-comp-functionality.slang.expected.txt
@@ -0,0 +1,16 @@
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
diff --git a/tests/hlsl-intrinsic/quad-control/quad-control-frag-many-entry-points.slang b/tests/hlsl-intrinsic/quad-control/quad-control-frag-many-entry-points.slang
new file mode 100644
index 000000000..2312f0c95
--- /dev/null
+++ b/tests/hlsl-intrinsic/quad-control/quad-control-frag-many-entry-points.slang
@@ -0,0 +1,96 @@
+//TEST:SIMPLE(filecheck=CHECK_SPIRV): -target spirv -fvk-use-entrypoint-name
+//TEST:SIMPLE(filecheck=CHECK_GLSL): -target glsl -fvk-use-entrypoint-name
+
+//
+// Check that SPIRV quad control execution modes and GLSL layout/attribute decorations are only
+// set on entry points that contain quad control functions and/or quad control decorations.
+//
+
+Texture2D colorTexture1;
+SamplerState samplerState;
+
+struct FragmentInput {
+ float2 uv : TEXCOORD0;
+};
+
+float4 getFragColor(float2 uv) {
+ float4 fragColor = float4(1.0, 1.0, 1.0, 1.0);
+ bool nonUniformCondition = uv.x > 0.5;
+
+ if (QuadAny(nonUniformCondition)) {
+ float4 color = colorTexture1.Sample(samplerState, uv);
+ if (nonUniformCondition) {
+ fragColor = color;
+ }
+ }
+
+ return fragColor;
+}
+
+// CHECK_SPIRV: OpExecutionMode %fragmentMain1 MaximallyReconvergesKHR
+// CHECK_SPIRV: OpExecutionMode %fragmentMain1 QuadDerivativesKHR
+// CHECK_GLSL: layout(quad_derivatives) in
+// CHECK_GLSL: [maximally_reconverges]
+[shader("fragment")]
+float4 fragmentMain1(FragmentInput input) : SV_Target
+{
+ bool nonUniformCondition = input.uv.x > 0.5;
+
+ float4 fragColor = float4(1.0, 1.0, 1.0, 1.0);
+
+ if (QuadAny(nonUniformCondition)) {
+ float4 color = colorTexture1.Sample(samplerState, input.uv);
+ if (nonUniformCondition) {
+ fragColor = color;
+ }
+ }
+
+ return fragColor;
+}
+
+// CHECK_SPIRV-NOT: OpExecutionMode %fragmentMain2 QuadDerivativesKHR
+// CHECK_SPIRV: OpExecutionMode %fragmentMain2 MaximallyReconvergesKHR
+// CHECK_GLSL-NOT: layout(quad_derivatives) in
+// CHECK_GLSL: [maximally_reconverges]
+[MaximallyReconverges]
+[shader("fragment")]
+float4 fragmentMain2(FragmentInput input) : SV_Target
+{
+ return float4(1.0, 1.0, 1.0, 1.0);
+}
+
+
+// CHECK_SPIRV-NOT: OpExecutionMode %fragmentMain3 MaximallyReconvergesKHR
+// CHECK_SPIRV-NOT: OpExecutionMode %fragmentMain3 QuadDerivativesKHR
+// CHECK_SPIRV: OpExecutionMode %fragmentMain3 RequireFullQuadsKHR
+// CHECK_GLSL-NOT: layout(quad_derivatives) in
+// CHECK_GLSL: layout(full_quads) in
+// CHECK_GLSL-NOT: [maximally_reconverges]
+[RequireFullQuads]
+[shader("fragment")]
+float4 fragmentMain3(FragmentInput input) : SV_Target
+{
+ return float4(1.0, 1.0, 1.0, 1.0);
+}
+
+// CHECK_SPIRV: OpExecutionMode %fragmentMain4 MaximallyReconvergesKHR
+// CHECK_SPIRV: OpExecutionMode %fragmentMain4 QuadDerivativesKHR
+// CHECK_GLSL: layout(quad_derivatives) in
+// CHECK_GLSL: [maximally_reconverges]
+[shader("fragment")]
+float4 fragmentMain4(FragmentInput input) : SV_Target
+{
+ return getFragColor(input.uv);
+}
+
+// CHECK_SPIRV-NOT: OpExecutionMode %fragmentMain5 MaximallyReconvergesKHR
+// CHECK_SPIRV-NOT: OpExecutionMode %fragmentMain5 QuadDerivativesKHR
+// CHECK_SPIRV-NOT: OpExecutionMode %fragmentMain5 RequireFullQuadsKHR
+// CHECK_GLSL-NOT: layout(quad_derivatives) in
+// CHECK_GLSL-NOT: layout(full_quads) in
+// CHECK_GLSL-NOT: [maximally_reconverges]
+[shader("fragment")]
+float4 fragmentMain5(FragmentInput input) : SV_Target
+{
+ return float4(1.0, 1.0, 1.0, 1.0);
+}
diff --git a/tests/hlsl-intrinsic/quad-control/quad-control-frag.slang b/tests/hlsl-intrinsic/quad-control/quad-control-frag.slang
new file mode 100644
index 000000000..29a9546a0
--- /dev/null
+++ b/tests/hlsl-intrinsic/quad-control/quad-control-frag.slang
@@ -0,0 +1,53 @@
+//TEST:SIMPLE(filecheck=CHECK_SPIRV): -entry fragmentMain -stage fragment -target spirv
+//TEST:SIMPLE(filecheck=CHECK_GLSL): -entry fragmentMain -stage fragment -target glsl
+//TEST:SIMPLE(filecheck=CHECK_HLSL): -entry fragmentMain -stage fragment -target hlsl
+//TEST:SIMPLE(filecheck=CHECK_METAL): -entry fragmentMain -stage fragment -target metal
+
+Texture2D colorTexture1;
+Texture2D colorTexture2;
+SamplerState samplerState;
+
+struct FragmentInput {
+ float2 uv : TEXCOORD0;
+};
+
+// CHECK_SPIRV: OpExecutionMode %fragmentMain MaximallyReconvergesKHR
+// CHECK_SPIRV: OpExecutionMode %fragmentMain QuadDerivativesKHR
+// CHECK_SPIRV: OpExecutionMode %fragmentMain RequireFullQuadsKHR
+// CHECK_GLSL: layout(quad_derivatives) in
+// CHECK_GLSL: layout(full_quads) in
+// CHECK_GLSL: [maximally_reconverges]
+[QuadDerivatives]
+[RequireFullQuads]
+float4 fragmentMain(FragmentInput input) : SV_Target
+{
+ bool nonUniformCondition1 = input.uv.x > 0.5;
+ bool nonUniformCondition2 = input.uv.y > 0.8;
+
+ float4 fragColor = float4(1.0, 1.0, 1.0, 1.0);
+
+ // CHECK_SPIRV: OpGroupNonUniformQuadAnyKHR
+ // CHECK_GLSL: subgroupQuadAny
+ // CHECK_HLSL: QuadAny
+ // CHECK_METAL: quad_any
+ if (QuadAny(nonUniformCondition1)) {
+ float4 color = colorTexture1.Sample(samplerState, input.uv);
+ if (nonUniformCondition1) {
+ fragColor = color;
+ }
+ }
+
+ // CHECK_SPIRV: OpGroupNonUniformQuadAllKHR
+ // CHECK_GLSL: subgroupQuadAll
+ // CHECK_HLSL: QuadAll
+ // CHECK_METAL: quad_all
+ if (QuadAll(nonUniformCondition2)) {
+ float4 color = colorTexture2.Sample(samplerState, input.uv);
+ if (nonUniformCondition2) {
+ fragColor += color * 0.5;
+ }
+ }
+
+ return fragColor;
+}
+