Test OpUndef with OpConstantComposite and OpSpecConstantComposite
authorRicardo Garcia <rgarcia@igalia.com>
Thu, 27 Feb 2020 16:30:52 +0000 (17:30 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 12 Mar 2020 08:27:26 +0000 (04:27 -0400)
This commit tests OpUndef can be used to create partially defined
constant composite structures by using OpUndev values when constructing
other values with OpConstantComposite and OpSpecConstantComposite.

New tests:
dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_*

Components: Vulkan
VK-GL-CTS issue: 2243

Change-Id: I518dd029b4e00a5d5d33603d4776ce643c2adba8

android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/undef/undefined_constant_composite.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/undef/undefined_spec_constant_composite.amber [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
external/vulkancts/mustpass/master/vk-default-no-waivers.txt
external/vulkancts/mustpass/master/vk-default.txt

index 24c0f87..c6b9918 100644 (file)
@@ -86410,6 +86410,8 @@ dEQP-VK.spirv_assembly.instruction.compute.opspecconstantop.shiftleftlogical_s_i
 dEQP-VK.spirv_assembly.instruction.compute.opspecconstantop.shiftrightlogical_s_i8
 dEQP-VK.spirv_assembly.instruction.compute.opspecconstantop.shiftrightarithmetic_s_i8
 dEQP-VK.spirv_assembly.instruction.compute.opspecconstantop.shiftleftlogical_s_i8
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_constant_composite
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.unreachable-switch-merge-in-loop
 dEQP-VK.spirv_assembly.instruction.compute.uconvert.int8_to_uint16
 dEQP-VK.spirv_assembly.instruction.compute.uconvert.int8_to_uint32
index a4b41bd..1ea988b 100644 (file)
@@ -308378,6 +308378,8 @@ dEQP-VK.spirv_assembly.instruction.compute.opundef.array
 dEQP-VK.spirv_assembly.instruction.compute.opundef.runtimearray
 dEQP-VK.spirv_assembly.instruction.compute.opundef.struct
 dEQP-VK.spirv_assembly.instruction.compute.opundef.pointer
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_constant_composite
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.all
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.unreachable-switch-merge-in-loop
 dEQP-VK.spirv_assembly.instruction.compute.opquantize.infinities
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/undef/undefined_constant_composite.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/undef/undefined_constant_composite.amber
new file mode 100644 (file)
index 0000000..b2e76b1
--- /dev/null
@@ -0,0 +1,135 @@
+#!amber
+
+# Copyright 2020 Valve Corporation.
+# Copyright 2020 The Khronos Group Inc.
+#
+# 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
+#
+#     http://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
+;
+; The shader below is based on the following GLSL shader:
+;
+;     #version 450
+;
+;     struct Pair {
+;         int first;
+;         int second;
+;     };
+;
+;     const Pair constant_pair = { 100, 200 };
+;
+;     layout(set=0, binding=0, std430) buffer InputBlock {
+;         int array[10];
+;     } inputValues;
+;
+;     layout(set=0, binding=1, std430) buffer OutputBlock {
+;         int array[10];
+;     } outputValues;
+;
+;     int add_second (int value, Pair pair) {
+;         return value + pair.second;
+;     }
+;
+;     void main() {
+;         uint idx = gl_GlobalInvocationID.x;
+;         outputValues.array[idx] = add_second(inputValues.array[idx], constant_pair);
+;     }
+;
+; However, the first element of constant_pair has been modified to be undefined.
+;
+                            OpCapability Shader
+                  %std450 = OpExtInstImport "GLSL.std.450"
+                            OpMemoryModel Logical GLSL450
+                            OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+                            OpExecutionMode %main LocalSize 1 1 1
+                            OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+                            OpDecorate %_arr_int_uint_10 ArrayStride 4
+                            OpMemberDecorate %OutputBlock 0 Offset 0
+                            OpDecorate %OutputBlock BufferBlock
+                            OpDecorate %outputValues DescriptorSet 0
+                            OpDecorate %outputValues Binding 1
+                            OpMemberDecorate %InputBlock 0 Offset 0
+                            OpDecorate %InputBlock BufferBlock
+                            OpDecorate %inputValues DescriptorSet 0
+                            OpDecorate %inputValues Binding 0
+                    %void = OpTypeVoid
+               %void_func = OpTypeFunction %void
+                     %int = OpTypeInt 32 1
+                    %uint = OpTypeInt 32 0
+                  %v3uint = OpTypeVector %uint 3
+                   %int_0 = OpConstant %int 0
+                   %int_1 = OpConstant %int 1
+                 %int_200 = OpConstant %int 200
+                  %uint_0 = OpConstant %uint 0
+                 %uint_10 = OpConstant %uint 10
+       %_ptr_Function_int = OpTypePointer Function %int
+                    %Pair = OpTypeStruct %int %int
+      %_ptr_Function_Pair = OpTypePointer Function %Pair
+    %add_second_func_type = OpTypeFunction %int %_ptr_Function_int %_ptr_Function_Pair
+      %_ptr_Function_uint = OpTypePointer Function %uint
+       %_ptr_Input_v3uint = OpTypePointer Input %v3uint
+         %_ptr_Input_uint = OpTypePointer Input %uint
+        %_arr_int_uint_10 = OpTypeArray %int %uint_10
+             %OutputBlock = OpTypeStruct %_arr_int_uint_10
+%_ptr_Uniform_OutputBlock = OpTypePointer Uniform %OutputBlock
+            %outputValues = OpVariable %_ptr_Uniform_OutputBlock Uniform
+              %InputBlock = OpTypeStruct %_arr_int_uint_10
+ %_ptr_Uniform_InputBlock = OpTypePointer Uniform %InputBlock
+             %inputValues = OpVariable %_ptr_Uniform_InputBlock Uniform
+                            ; Replaced %int_100 with an undefined int.
+               %undef_int = OpUndef %int
+                            ; Composed a constant Pair with the undefined int in the first member.
+              %const_Pair = OpConstantComposite %Pair %undef_int %int_200
+        %_ptr_Uniform_int = OpTypePointer Uniform %int
+   %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+                    %main = OpFunction %void None %void_func
+              %main_label = OpLabel
+                 %param_1 = OpVariable %_ptr_Function_int Function
+                 %param_2 = OpVariable %_ptr_Function_Pair Function
+                %gidx_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
+                    %gidx = OpLoad %uint %gidx_ptr
+         %input_value_ptr = OpAccessChain %_ptr_Uniform_int %inputValues %int_0 %gidx
+             %input_value = OpLoad %int %input_value_ptr
+                            OpStore %param_1 %input_value
+                            OpStore %param_2 %const_Pair
+                  %retval = OpFunctionCall %int %add_second %param_1 %param_2
+        %output_value_ptr = OpAccessChain %_ptr_Uniform_int %outputValues %int_0 %gidx
+                            OpStore %output_value_ptr %retval
+                            OpReturn
+                            OpFunctionEnd
+              %add_second = OpFunction %int None %add_second_func_type
+               %value_ptr = OpFunctionParameter %_ptr_Function_int
+                    %pair = OpFunctionParameter %_ptr_Function_Pair
+        %add_second_label = OpLabel
+                   %value = OpLoad %int %value_ptr
+                            ; Access the second struct member, which is defined.
+         %pair_second_ptr = OpAccessChain %_ptr_Function_int %pair %int_1
+             %pair_second = OpLoad %int %pair_second_ptr
+              %add_result = OpIAdd %int %value %pair_second
+                            OpReturnValue %add_result
+                            OpFunctionEnd
+END
+
+BUFFER input_buffer DATA_TYPE int32 SIZE 10 SERIES_FROM 1000 INC_BY 1
+BUFFER output_buffer DATA_TYPE int32 SIZE 10 FILL 0
+BUFFER reference_buffer DATA_TYPE int32 SIZE 10 SERIES_FROM 1200 INC_BY 1
+
+PIPELINE compute compute_pipeline
+       ATTACH comp
+       BIND BUFFER input_buffer AS storage DESCRIPTOR_SET 0 BINDING 0
+       BIND BUFFER output_buffer AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN compute_pipeline 10 1 1
+EXPECT output_buffer EQ_BUFFER reference_buffer
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/undef/undefined_spec_constant_composite.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/compute/undef/undefined_spec_constant_composite.amber
new file mode 100644 (file)
index 0000000..5c04910
--- /dev/null
@@ -0,0 +1,155 @@
+#!amber
+
+# Copyright 2020 Valve Corporation.
+# Copyright 2020 The Khronos Group Inc.
+#
+# 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
+#
+#     http://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
+;
+; The shader below is based on the following GLSL shader:
+;
+;     #version 450
+;
+;     struct Pair {
+;         int first;
+;         int second;
+;     };
+;
+;     const Pair constant_pair = { 100, 200 };
+;
+;     layout (constant_id=0) const int constantFirst = 0;
+;
+;     Pair spec_constant_pair = { constantFirst, 200 };
+;
+;     layout(set=0, binding=0, std430) buffer InputBlock {
+;         int array[10];
+;     } inputValues;
+;
+;     layout(set=0, binding=1, std430) buffer OutputBlock {
+;         int array[10];
+;     } outputValues;
+;
+;     int add_first_and_second (int value, Pair p1, Pair p2) {
+;         return value + p1.first + p2.second;
+;     }
+;
+;     void main() {
+;         uint idx = gl_GlobalInvocationID.x;
+;         outputValues.array[idx] = add_first_and_second(inputValues.array[idx], spec_constant_pair, constant_pair);
+;     }
+;
+; However, both the constant_pair and the spec_constant_pair have one of their members replaced by undefined values.
+;
+                              OpCapability Shader
+                    %std450 = OpExtInstImport "GLSL.std.450"
+                              OpMemoryModel Logical GLSL450
+                              OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+                              OpExecutionMode %main LocalSize 1 1 1
+                              OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+                              OpDecorate %_arr_int_uint_10 ArrayStride 4
+                              OpMemberDecorate %OutputBlock 0 Offset 0
+                              OpDecorate %OutputBlock BufferBlock
+                              OpDecorate %outputValues DescriptorSet 0
+                              OpDecorate %outputValues Binding 1
+                              OpMemberDecorate %InputBlock 0 Offset 0
+                              OpDecorate %InputBlock BufferBlock
+                              OpDecorate %inputValues DescriptorSet 0
+                              OpDecorate %inputValues Binding 0
+                              OpDecorate %spec_constant SpecId 0
+                      %void = OpTypeVoid
+                 %void_func = OpTypeFunction %void
+                       %int = OpTypeInt 32 1
+                      %uint = OpTypeInt 32 0
+                    %v3uint = OpTypeVector %uint 3
+                     %int_0 = OpConstant %int 0
+                     %int_1 = OpConstant %int 1
+                   %int_200 = OpConstant %int 200
+                    %uint_0 = OpConstant %uint 0
+                   %uint_10 = OpConstant %uint 10
+         %_ptr_Function_int = OpTypePointer Function %int
+                      %Pair = OpTypeStruct %int %int
+        %_ptr_Function_Pair = OpTypePointer Function %Pair
+%add_pair_members_func_type = OpTypeFunction %int %_ptr_Function_int %_ptr_Function_Pair %_ptr_Function_Pair
+        %_ptr_Function_uint = OpTypePointer Function %uint
+         %_ptr_Input_v3uint = OpTypePointer Input %v3uint
+           %_ptr_Input_uint = OpTypePointer Input %uint
+          %_arr_int_uint_10 = OpTypeArray %int %uint_10
+               %OutputBlock = OpTypeStruct %_arr_int_uint_10
+  %_ptr_Uniform_OutputBlock = OpTypePointer Uniform %OutputBlock
+              %outputValues = OpVariable %_ptr_Uniform_OutputBlock Uniform
+                %InputBlock = OpTypeStruct %_arr_int_uint_10
+   %_ptr_Uniform_InputBlock = OpTypePointer Uniform %InputBlock
+               %inputValues = OpVariable %_ptr_Uniform_InputBlock Uniform
+                              ; Replaced %int_100 with an undefined int.
+                 %undef_int = OpUndef %int
+                              ; Composed a spec constant Pair with an undefined int in the second member.
+             %spec_constant = OpSpecConstant %int 0
+           %spec_const_Pair = OpSpecConstantComposite %Pair %spec_constant %undef_int
+                              ; Composed a constant Pair with the undefined int in the first member.
+                %const_Pair = OpConstantComposite %Pair %undef_int %int_200
+          %_ptr_Uniform_int = OpTypePointer Uniform %int
+     %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+                      %main = OpFunction %void None %void_func
+                %main_label = OpLabel
+                   %param_1 = OpVariable %_ptr_Function_int Function
+                   %param_2 = OpVariable %_ptr_Function_Pair Function
+                   %param_3 = OpVariable %_ptr_Function_Pair Function
+                  %gidx_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
+                      %gidx = OpLoad %uint %gidx_ptr
+           %input_value_ptr = OpAccessChain %_ptr_Uniform_int %inputValues %int_0 %gidx
+               %input_value = OpLoad %int %input_value_ptr
+                              OpStore %param_1 %input_value
+                              OpStore %param_2 %spec_const_Pair
+                              OpStore %param_3 %const_Pair
+                              ; Pass the input value as the first argument.
+                              ; Pass the specialization constant Pair as the second argument.
+                              ; Pass the constant Pair as the third argument.
+                    %retval = OpFunctionCall %int %add_pair_members %param_1 %param_2 %param_3
+          %output_value_ptr = OpAccessChain %_ptr_Uniform_int %outputValues %int_0 %gidx
+                              OpStore %output_value_ptr %retval
+                              OpReturn
+                              OpFunctionEnd
+          %add_pair_members = OpFunction %int None %add_pair_members_func_type
+                 %value_ptr = OpFunctionParameter %_ptr_Function_int
+                    %pair_1 = OpFunctionParameter %_ptr_Function_Pair
+                    %pair_2 = OpFunctionParameter %_ptr_Function_Pair
+    %add_pair_members_label = OpLabel
+                     %value = OpLoad %int %value_ptr
+                              ; Access the first struct member from the first pair.
+                              ; Access the second struct member from the second pair.
+                              ; Both should be defined according to the function call above.
+          %pair_1_first_ptr = OpAccessChain %_ptr_Function_int %pair_1 %int_0
+         %pair_2_second_ptr = OpAccessChain %_ptr_Function_int %pair_2 %int_1
+              %pair_1_first = OpLoad %int %pair_1_first_ptr
+             %pair_2_second = OpLoad %int %pair_2_second_ptr
+            %partial_result = OpIAdd %int %value %pair_1_first
+              %final_result = OpIAdd %int %partial_result %pair_2_second
+                              OpReturnValue %final_result
+                              OpFunctionEnd
+
+END
+
+BUFFER input_buffer DATA_TYPE int32 SIZE 10 SERIES_FROM 1000 INC_BY 1
+BUFFER output_buffer DATA_TYPE int32 SIZE 10 FILL 0
+BUFFER reference_buffer DATA_TYPE int32 SIZE 10 SERIES_FROM 1600 INC_BY 1
+
+PIPELINE compute compute_pipeline
+       ATTACH comp SPECIALIZE 0 AS int32 400
+       BIND BUFFER input_buffer AS storage DESCRIPTOR_SET 0 BINDING 0
+       BIND BUFFER output_buffer AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN compute_pipeline 10 1 1
+EXPECT output_buffer EQ_BUFFER reference_buffer
index a947fdc..5a5d4f7 100644 (file)
@@ -6938,7 +6938,32 @@ tcu::TestCaseGroup* createOpUndefGroup (tcu::TestContext& testCtx)
                group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
        }
 
-               return group.release();
+       // OpUndef with constants.
+       {
+               static const char data_dir[] = "spirv_assembly/instruction/compute/undef";
+
+               static const struct
+               {
+                       const std::string name;
+                       const std::string desc;
+               } amberCases[] =
+               {
+                       { "undefined_constant_composite",               "OpUndef value in OpConstantComposite"          },
+                       { "undefined_spec_constant_composite",  "OpUndef value in OpSpecConstantComposite"      },
+               };
+
+               for (int i = 0; i < DE_LENGTH_OF_ARRAY(amberCases); ++i)
+               {
+                       cts_amber::AmberTestCase *testCase = cts_amber::createAmberTestCase(testCtx,
+                                                                                                                                                               amberCases[i].name.c_str(),
+                                                                                                                                                               amberCases[i].desc.c_str(),
+                                                                                                                                                               data_dir,
+                                                                                                                                                               amberCases[i].name + ".amber");
+                       group->addChild(testCase);
+               }
+       }
+
+       return group.release();
 }
 
 // Checks that a compute shader can generate a constant composite value of various types, without exercising a computation on it.
index 94505c5..a7d9191 100644 (file)
@@ -308265,6 +308265,8 @@ dEQP-VK.spirv_assembly.instruction.compute.opundef.array
 dEQP-VK.spirv_assembly.instruction.compute.opundef.runtimearray
 dEQP-VK.spirv_assembly.instruction.compute.opundef.struct
 dEQP-VK.spirv_assembly.instruction.compute.opundef.pointer
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_constant_composite
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.all
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.unreachable-switch-merge-in-loop
 dEQP-VK.spirv_assembly.instruction.compute.opquantize.infinities
index a0bf3d5..132e54d 100644 (file)
@@ -308265,6 +308265,8 @@ dEQP-VK.spirv_assembly.instruction.compute.opundef.array
 dEQP-VK.spirv_assembly.instruction.compute.opundef.runtimearray
 dEQP-VK.spirv_assembly.instruction.compute.opundef.struct
 dEQP-VK.spirv_assembly.instruction.compute.opundef.pointer
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_constant_composite
+dEQP-VK.spirv_assembly.instruction.compute.opundef.undefined_spec_constant_composite
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.all
 dEQP-VK.spirv_assembly.instruction.compute.opunreachable.unreachable-switch-merge-in-loop
 dEQP-VK.spirv_assembly.instruction.compute.opquantize.infinities