Test SPIR-V switch case jumping to the merge block
authorRicardo Garcia <rgarcia@igalia.com>
Wed, 18 Nov 2020 15:04:47 +0000 (16:04 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 26 Nov 2020 12:56:55 +0000 (07:56 -0500)
Add new case that tests OpSwitch containing a case that jumps directly
to the merge block.

New test:
dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.switch-case-to-merge-block

Components: Vulkan
VK-GL-CTS issue: 2657

Change-Id: Ibfabc4341dd35b96795aac8cf9bd8ce5fa61ebe6

android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/switch/switch-case-to-merge-block.amber [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
external/vulkancts/mustpass/master/vk-default.txt

index eaa40b0..2d50748 100644 (file)
@@ -168058,6 +168058,7 @@ dEQP-VK.spirv_assembly.instruction.graphics.unused_variables.set_0_binding_5_ver
 dEQP-VK.spirv_assembly.instruction.graphics.unused_variables.set_5_binding_5_vertex_normal_tessc_normal_tesse_unused_var_frag_normal
 dEQP-VK.spirv_assembly.instruction.graphics.unused_variables.set_0_binding_5_vertex_normal_tessc_normal_tesse_unused_func_frag_normal
 dEQP-VK.spirv_assembly.instruction.graphics.unused_variables.set_5_binding_5_vertex_normal_tessc_normal_tesse_unused_func_frag_normal
+dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.switch-case-to-merge-block
 dEQP-VK.spirv_assembly.instruction.graphics.opspecconstantop.shiftrightlogical_i64_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opspecconstantop.shiftrightlogical_i64_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opspecconstantop.shiftrightlogical_i64_tesse
index a1f7efc..570c3b7 100644 (file)
@@ -408012,6 +408012,7 @@ dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_tess
 dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_tesse
 dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_geom
 dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_frag
+dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.switch-case-to-merge-block
 dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order_tesse
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/switch/switch-case-to-merge-block.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/switch/switch-case-to-merge-block.amber
new file mode 100644 (file)
index 0000000..aee4ce5
--- /dev/null
@@ -0,0 +1,117 @@
+#!amber
+#
+# Copyright 2020 The Khronos Group Inc.
+# Copyright 2020 Valve Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+SHADER compute comp SPIRV-ASM TARGET_ENV spv1.0
+; SPIR-V
+; Version: 1.0
+                     OpCapability Shader
+                     OpMemoryModel Logical GLSL450
+                     OpEntryPoint GLCompute %main "main"
+                     OpExecutionMode %main LocalSize 1 1 1
+                     OpMemberDecorate %InputBlock 0 Offset 0
+                     OpDecorate %InputBlock BufferBlock
+                     OpDecorate %inputBuffer DescriptorSet 0
+                     OpDecorate %inputBuffer Binding 0
+                     OpMemberDecorate %OutputBlock 0 Offset 0
+                     OpDecorate %OutputBlock BufferBlock
+                     OpDecorate %outputBuffer DescriptorSet 0
+                     OpDecorate %outputBuffer Binding 1
+             %void = OpTypeVoid
+         %voidFunc = OpTypeFunction %void
+             %uint = OpTypeInt 32 0
+           %uint_4 = OpConstant %uint 4
+           %uint_5 = OpConstant %uint 5
+           %uint_6 = OpConstant %uint 6
+           %uint_7 = OpConstant %uint 7
+           %uint_8 = OpConstant %uint 8
+       %InputBlock = OpTypeStruct %uint
+   %InputBlock_ptr = OpTypePointer Uniform %InputBlock
+      %inputBuffer = OpVariable %InputBlock_ptr Uniform
+              %int = OpTypeInt 32 1
+            %int_0 = OpConstant %int 0
+ %uint_uniform_ptr = OpTypePointer Uniform %uint
+%uint_Function_ptr = OpTypePointer Function %uint
+      %OutputBlock = OpTypeStruct %uint
+  %OutputBlock_ptr = OpTypePointer Uniform %OutputBlock
+     %outputBuffer = OpVariable %OutputBlock_ptr Uniform
+             %main = OpFunction %void None %voidFunc
+        %mainLabel = OpLabel
+;
+; %aux will contain value 4 by default and it should not be modified.
+;
+              %aux = OpVariable %uint_Function_ptr Function
+                     OpStore %aux %uint_4
+            %ptrIn = OpAccessChain %uint_uniform_ptr %inputBuffer %int_0
+         %inputVal = OpLoad %uint %ptrIn
+;
+; From fauly.asm in https://gitlab.freedesktop.org/mesa/mesa/-/issues/3460
+;
+;               OpSelectionMerge %3153 None
+;               OpSwitch %166 %3152 0 %3153 1 %3151 2 %3150 3 %3149
+;       %3152 = OpLabel
+;               OpBranch %3153
+;       %3151 = OpLabel
+;               OpBranch %3153
+;       %3150 = OpLabel
+;        %345 = OpAccessChain %_ptr_StorageBuffer_v4float %71 %uint_0 %uint_37
+;        %346 = OpLoad %v4float %345
+;        %347 = OpBitcast %v4uint %346
+;        %348 = OpCompositeExtract %uint %347 0
+;        %188 = OpShiftLeftLogical %uint %348 %uint_1
+;               OpBranch %3153
+;       %3149 = OpLabel
+;               OpBranch %3153
+;       %3153 = OpLabel
+;
+; Similar structure replicated below.
+; Value 0 jumps to the merge label while the others store unexpected values in %aux.
+;
+                     OpSelectionMerge %mergeLabel None
+                     OpSwitch %inputVal %defaultLabel 0 %mergeLabel 1 %val1Label 2 %val2Label 3 %val3Label
+     %defaultLabel = OpLabel
+                     OpStore %aux %uint_5
+                     OpBranch %mergeLabel
+        %val1Label = OpLabel
+                     OpStore %aux %uint_6
+                     OpBranch %mergeLabel
+        %val2Label = OpLabel
+                     OpStore %aux %uint_7
+                     OpBranch %mergeLabel
+        %val3Label = OpLabel
+                     OpStore %aux %uint_8
+                     OpBranch %mergeLabel
+       %mergeLabel = OpLabel
+           %ptrOut = OpAccessChain %uint_uniform_ptr %outputBuffer %int_0
+          %aux_val = OpLoad %uint %aux
+                     OpStore %ptrOut %aux_val
+                     OpReturn
+                     OpFunctionEnd
+END
+
+BUFFER inputBuffer  DATA_TYPE uint32 DATA 0 END
+BUFFER outputBuffer DATA_TYPE uint32 DATA 0 END
+
+# Store 0 as the input value to make the switch go directly to the merge label.
+PIPELINE compute compute_pipeline
+  ATTACH comp
+  BIND BUFFER inputBuffer  AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER outputBuffer AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN compute_pipeline 1 1 1
+# Expect 4, the initial value stored in %aux before the switch.
+EXPECT outputBuffer IDX 0 EQ 4
index 9ca03b2..ec35382 100644 (file)
@@ -3163,6 +3163,28 @@ void addOpUnreachableAmberTests(tcu::TestCaseGroup& group, tcu::TestContext& tes
        }
 }
 
+void addOpSwitchAmberTests(tcu::TestCaseGroup& group, tcu::TestContext& testCtx)
+{
+       static const char dataDir[] = "spirv_assembly/instruction/compute/switch";
+
+       struct Case
+       {
+               string  name;
+               string  desc;
+       };
+
+       static const Case cases[] =
+       {
+               { "switch-case-to-merge-block", "Test switch containing a case that jumps directly to the merge block"  },
+       };
+
+       for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
+       {
+               const string fileName = cases[i].name + ".amber";
+               group.addChild(cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].desc.c_str(), dataDir, fileName));
+       }
+}
+
 tcu::TestCaseGroup* createOpArrayLengthComputeGroup (tcu::TestContext& testCtx)
 {
        de::MovePtr<tcu::TestCaseGroup> group           (new tcu::TestCaseGroup(testCtx, "oparraylength", "Test the OpArrayLength instruction"));
@@ -7937,6 +7959,8 @@ tcu::TestCaseGroup* createSwitchBlockOrderTests(tcu::TestContext& testCtx)
 
        createTestsForAllStages("out_of_order", inputColors, outputColors, fragments, group.get());
 
+       addOpSwitchAmberTests(*group, testCtx);
+
        return group.release();
 }
 
index 1d121a7..63aecd5 100644 (file)
@@ -408018,6 +408018,7 @@ dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_tess
 dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_tesse
 dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_geom
 dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.out_of_order_frag
+dEQP-VK.spirv_assembly.instruction.graphics.switch_block_order.switch-case-to-merge-block
 dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order_vert
 dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order_tessc
 dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order_tesse