Tests for VK_KHR_shader_terminate_invocation
authorAlan Baker <alanbaker@google.com>
Tue, 9 Jun 2020 19:18:31 +0000 (15:18 -0400)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Mon, 9 Nov 2020 08:22:05 +0000 (03:22 -0500)
* Adds tests for the extension
* Adds more amber test feature checks

Components: Vulkan

VK-GL-CTS Issue: 2396

New Tests: dEQP-VK.spirv_assembly.instruction.terminate_invocation.*

Change-Id: I3ac8dfae88f2a4bd5ec03f8e3aa2b26097eb7190
(cherry picked from commit a00b458dc43edfd3ad1b93a181d3873aaca63f4b)

30 files changed:
AndroidGen.mk
android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/fetch_sources.py
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_image_atomic.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_image_store.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_null_pointer_load.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_null_pointer_store.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_atomic.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_load.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_store.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_output_write.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_output_write_before_terminate.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_ssbo_atomic.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_ssbo_store.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/ssbo_atomic_before_terminate.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/ssbo_store_before_terminate.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/subgroup_ballot.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/subgroup_vote.amber [new file with mode: 0644]
external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/terminate_loop.amber [new file with mode: 0644]
external/vulkancts/framework/vulkan/vkDeviceExtensions.inl
external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
external/vulkancts/modules/vulkan/amber/vktAmberTestCase.cpp
external/vulkancts/modules/vulkan/spirv_assembly/CMakeLists.txt
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.hpp [new file with mode: 0644]
external/vulkancts/mustpass/master/vk-default.txt
external/vulkancts/scripts/src/extensions_data.txt
external/vulkancts/scripts/src/mandatory_features.txt

index ab3d6b2..5fde87e 100644 (file)
@@ -359,6 +359,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSignedOpTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersion1p4Tests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmSpirvVersionTests.cpp \
+       external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTrinaryMinMaxTests.cpp \
        external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTypeTests.cpp \
index 6e7a602..38cc392 100644 (file)
@@ -155332,6 +155332,21 @@ dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.scalar
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec2
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec3
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec4
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_output_write
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_output_write_before_terminate
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_ssbo_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_ssbo_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.ssbo_store_before_terminate
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_image_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_image_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_null_pointer_load
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_null_pointer_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_load
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.terminate_loop
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_ballot
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_vote
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_comp
 dEQP-VK.spirv_assembly.type.scalar.i8.add_comp
 dEQP-VK.spirv_assembly.type.scalar.i8.sub_comp
index 1739c65..91f22f3 100644 (file)
@@ -407275,6 +407275,21 @@ dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.scalar
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec2
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec3
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec4
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_output_write
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_output_write_before_terminate
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_ssbo_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_ssbo_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.ssbo_store_before_terminate
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_image_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_image_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_null_pointer_load
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_null_pointer_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_load
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.terminate_loop
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_ballot
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_vote
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_vert
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_tessc
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_tesse
index 0852f8c..2699492 100644 (file)
@@ -316,7 +316,7 @@ PACKAGES = [
        GitRepo(
                "https://github.com/KhronosGroup/SPIRV-Tools.git",
                None,
-               "4b07d50cd9a0a537ccb28252227f87d36273cf53",
+               "f7da527757140ae701be58274ce6db2f4234d9ff",
                "spirv-tools"),
        GitRepo(
                "https://github.com/KhronosGroup/glslang.git",
@@ -327,7 +327,7 @@ PACKAGES = [
        GitRepo(
                "https://github.com/KhronosGroup/SPIRV-Headers.git",
                None,
-               "d4e76fb323745e81677ee4181986c983bf5e4d88",
+               "7845730cab6ebbdeb621e7349b7dc1a59c3377be",
                "spirv-headers"),
        GitRepo(
                "https://github.com/google/amber.git",
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_image_atomic.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_image_atomic.amber
new file mode 100644 (file)
index 0000000..c160ac3
--- /dev/null
@@ -0,0 +1,166 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0, r32i) uniform iimage2D im2d;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  imageAtomicAdd(im2d, ivec2(x_coord, y_coord), x_coord);
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %im2d DescriptorSet 0
+OpDecorate %im2d Binding 0
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%device = OpConstant %int 1
+%relaxed = OpConstant %int 0
+%int2 = OpTypeVector %int 2
+%int4 = OpTypeVector %int 4
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%image = OpTypeImage %int 2D 0 0 0 2 R32i
+%ptr_image_uniform = OpTypePointer UniformConstant %image
+%im2d = OpVariable %ptr_image_uniform UniformConstant
+%ptr_int_image = OpTypePointer Image %int
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%im_coord = OpCompositeConstruct %int2 %x %y
+%im_ptr = OpImageTexelPointer %ptr_int_image %im2d %im_coord %int_0
+%old = OpAtomicIAdd %int %im_ptr %device %relaxed %x
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE a_buf DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage_image DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf IDX   0 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX  32 EQ 0 1 2 3 4 5 6 7
+EXPECT a_buf IDX  64 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX  96 EQ 0 1 2 3 4 5 6 7
+EXPECT a_buf IDX 128 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX 160 EQ 0 1 2 3 4 5 6 7
+EXPECT a_buf IDX 192 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX 224 EQ 0 1 2 3 4 5 6 7
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_image_store.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_image_store.amber
new file mode 100644 (file)
index 0000000..b0d7c9e
--- /dev/null
@@ -0,0 +1,165 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0, r32i) uniform iimage2D im2d;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  ivec4 data = ivec4(x_coord, 0, 0, 0);
+;  imageStore(im2d, ivec2(x_coord, y_coord), data);
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %im2d DescriptorSet 0
+OpDecorate %im2d Binding 0
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%int2 = OpTypeVector %int 2
+%int4 = OpTypeVector %int 4
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%image = OpTypeImage %int 2D 0 0 0 2 R32i
+%ptr_image_uniform = OpTypePointer UniformConstant %image
+%im2d = OpVariable %ptr_image_uniform UniformConstant
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%im_data = OpCompositeConstruct %int4 %x %int_0 %int_0 %int_0
+%im_coord = OpCompositeConstruct %int2 %x %y
+%ld_im2d = OpLoad %image %im2d
+OpImageWrite %ld_im2d %im_coord %im_data
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE a_buf DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage_image DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf IDX   0 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX  32 EQ 0 1 2 3 4 5 6 7
+EXPECT a_buf IDX  64 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX  96 EQ 0 1 2 3 4 5 6 7
+EXPECT a_buf IDX 128 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX 160 EQ 0 1 2 3 4 5 6 7
+EXPECT a_buf IDX 192 EQ 0 1 0 3 0 5 0 7
+EXPECT a_buf IDX 224 EQ 0 1 2 3 4 5 6 7
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_null_pointer_load.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_null_pointer_load.amber
new file mode 100644 (file)
index 0000000..b030de0
--- /dev/null
@@ -0,0 +1,185 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;layout(set = 0, binding = 1) buffer B { uint b[]; } b;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  int* b_ptr = &b.b[x_coord + 8 * y_coord];
+;  if (combined == int(gl_FragCoord.z)) {
+;     b_ptr = nullptr;
+;    terminateInvocation;
+;  }
+;
+;  a.a[x_coord + 8 * y_coord] = *b_ptr;;
+;}
+OpCapability Shader
+OpCapability VariablePointersStorageBuffer
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpExtension "SPV_KHR_variable_pointers"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %b DescriptorSet 0
+OpDecorate %b Binding 1
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%b = OpVariable %ptr_a_ssbo StorageBuffer
+%nullptr = OpConstantNull %ptr_int_ssbo
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%b_ptr = OpAccessChain %ptr_int_ssbo %b %int_0 %idx
+%b_sel = OpSelect %ptr_int_ssbo %cmp %nullptr %b_ptr
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+OpCopyMemory %a_gep %b_sel
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER b_buf DATA_TYPE int32 SIZE 64 SERIES_FROM 0 INC_BY 1
+BUFFER expect_buf DATA_TYPE int32 DATA
+ 0  1  0  3  0  5  0  7
+ 8  9 10 11 12 13 14 15
+ 0 17  0 19  0 21  0 23
+24 25 26 27 28 29 30 31
+ 0 33  0 35  0 37  0 39
+40 41 42 43 44 45 46 47
+ 0 49  0 51  0 53  0 55
+56 57 58 59 60 61 62 63
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER b_buf AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_null_pointer_store.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_null_pointer_store.amber
new file mode 100644 (file)
index 0000000..60459ac
--- /dev/null
@@ -0,0 +1,185 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;layout(set = 0, binding = 1) buffer B { uint b[]; } b;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  int* a_ptr = &a.a[x_coord + 8 * y_coord];
+;  if (combined == int(gl_FragCoord.z)) {
+;     a_ptr = nullptr;
+;    terminateInvocation;
+;  }
+;
+;  *a_ptr = b.b[x_coord + 8 * y_coord];
+;}
+OpCapability Shader
+OpCapability VariablePointersStorageBuffer
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpExtension "SPV_KHR_variable_pointers"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %b DescriptorSet 0
+OpDecorate %b Binding 1
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%b = OpVariable %ptr_a_ssbo StorageBuffer
+%nullptr = OpConstantNull %ptr_int_ssbo
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%b_ptr = OpAccessChain %ptr_int_ssbo %b %int_0 %idx
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+%a_sel = OpSelect %ptr_int_ssbo %cmp %nullptr %a_gep
+OpCopyMemory %a_sel %b_ptr
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER b_buf DATA_TYPE int32 SIZE 64 SERIES_FROM 0 INC_BY 1
+BUFFER expect_buf DATA_TYPE int32 DATA
+ 0  1  0  3  0  5  0  7
+ 8  9 10 11 12 13 14 15
+ 0 17  0 19  0 21  0 23
+24 25 26 27 28 29 30 31
+ 0 33  0 35  0 37  0 39
+40 41 42 43 44 45 46 47
+ 0 49  0 51  0 53  0 55
+56 57 58 59 60 61 62 63
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER b_buf AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_atomic.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_atomic.amber
new file mode 100644 (file)
index 0000000..83279e9
--- /dev/null
@@ -0,0 +1,192 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;layout(set = 0, binding = 1) buffer B { uint b[]; } b;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int add = (x_coord & 0x1) + (y_coord & 0x1);
+;  int combined = add + in_data;
+;  if (combined == int(gl_FragCoord.z)) {
+;    terminateInvocation;
+;  }
+;
+;  int* a_ptr = (add == 0) ? &a.a[0] + a.a.length() : &a.a[x_coord + 8 * y_coord];
+;  atomicAdd(*a_ptr, b.b[x_coord + 8 * y_coord]);
+;}
+OpCapability Shader
+OpCapability VariablePointersStorageBuffer
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpExtension "SPV_KHR_variable_pointers"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %b DescriptorSet 0
+OpDecorate %b Binding 1
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%device = OpConstant %int 1
+%relaxed = OpConstant %int 0
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%b = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%b_ptr = OpAccessChain %ptr_int_ssbo %b %int_0 %idx
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+%a_len = OpArrayLength %int %a 0
+%a_0_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %int_0
+%oob_ptr = OpPtrAccessChain %ptr_int_ssbo %a_0_gep %a_len
+%cmp2 = OpIEqual %bool %add %int_0
+%a_sel = OpSelect %ptr_int_ssbo %cmp2 %oob_ptr %a_gep
+%b_val = OpLoad %int %b_ptr
+%old = OpAtomicIAdd %int %a_sel %device %relaxed %b_val
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER b_buf DATA_TYPE int32 SIZE 64 SERIES_FROM 0 INC_BY 1
+BUFFER expect_buf DATA_TYPE int32 DATA
+ 0  1  0  3  0  5  0  7
+ 8  9 10 11 12 13 14 15
+ 0 17  0 19  0 21  0 23
+24 25 26 27 28 29 30 31
+ 0 33  0 35  0 37  0 39
+40 41 42 43 44 45 46 47
+ 0 49  0 51  0 53  0 55
+56 57 58 59 60 61 62 63
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER b_buf AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_load.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_load.amber
new file mode 100644 (file)
index 0000000..0ae1fa6
--- /dev/null
@@ -0,0 +1,189 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;layout(set = 0, binding = 1) buffer B { uint b[]; } b;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int add = (x_coord & 0x1) + (y_coord & 0x1);
+;  int combined = add + in_data;
+;  if (combined == int(gl_FragCoord.z)) {
+;    terminateInvocation;
+;  }
+;
+;  int* b_ptr = (add == 0) ? &b.b[0] + b.b.length() : &b.b[x_coord + 8 * y_coord];
+;  a.a[x_coord + 8 * y_coord] = *b_ptr;;
+;}
+OpCapability Shader
+OpCapability VariablePointersStorageBuffer
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpExtension "SPV_KHR_variable_pointers"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %b DescriptorSet 0
+OpDecorate %b Binding 1
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%b = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%b_ptr = OpAccessChain %ptr_int_ssbo %b %int_0 %idx
+%len = OpArrayLength %int %b 0
+%b_0_ptr = OpAccessChain %ptr_int_ssbo %b %int_0 %int_0
+%oob_ptr = OpPtrAccessChain %ptr_int_ssbo %b_0_ptr %len
+%cmp2 = OpIEqual %bool %add %int_0
+%b_sel = OpSelect %ptr_int_ssbo %cmp2 %oob_ptr %b_ptr
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+OpCopyMemory %a_gep %b_sel
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER b_buf DATA_TYPE int32 SIZE 64 SERIES_FROM 0 INC_BY 1
+BUFFER expect_buf DATA_TYPE int32 DATA
+ 0  1  0  3  0  5  0  7
+ 8  9 10 11 12 13 14 15
+ 0 17  0 19  0 21  0 23
+24 25 26 27 28 29 30 31
+ 0 33  0 35  0 37  0 39
+40 41 42 43 44 45 46 47
+ 0 49  0 51  0 53  0 55
+56 57 58 59 60 61 62 63
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER b_buf AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_store.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_out_of_bounds_store.amber
new file mode 100644 (file)
index 0000000..db92860
--- /dev/null
@@ -0,0 +1,188 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;layout(set = 0, binding = 1) buffer B { uint b[]; } b;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int add = (x_coord & 0x1) + (y_coord & 0x1);
+;  int combined = add + in_data;
+;  if (combined == int(gl_FragCoord.z)) {
+;    terminateInvocation;
+;  }
+;
+;  int* a_ptr = (add == 0) ? &a.a[0] + a.a.length() : &a.a[x_coord + 8 * y_coord];
+;  *a_ptr = b.b[x_coord + 8 * y_coord];
+;}
+OpCapability Shader
+OpCapability VariablePointersStorageBuffer
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpExtension "SPV_KHR_variable_pointers"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %b DescriptorSet 0
+OpDecorate %b Binding 1
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%b = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%b_ptr = OpAccessChain %ptr_int_ssbo %b %int_0 %idx
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+%a_len = OpArrayLength %int %a 0
+%a_0_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %int_0
+%oob_ptr = OpPtrAccessChain %ptr_int_ssbo %a_0_gep %a_len
+%cmp2 = OpIEqual %bool %add %int_0
+%a_sel = OpSelect %ptr_int_ssbo %cmp2 %oob_ptr %a_gep
+OpCopyMemory %a_sel %b_ptr
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER b_buf DATA_TYPE int32 SIZE 64 SERIES_FROM 0 INC_BY 1
+BUFFER expect_buf DATA_TYPE int32 DATA
+ 0  1  0  3  0  5  0  7
+ 8  9 10 11 12 13 14 15
+ 0 17  0 19  0 21  0 23
+24 25 26 27 28 29 30 31
+ 0 33  0 35  0 37  0 39
+40 41 42 43 44 45 46 47
+ 0 49  0 51  0 53  0 55
+56 57 58 59 60 61 62 63
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+  BIND BUFFER b_buf AS storage DESCRIPTOR_SET 0 BINDING 1
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_output_write.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_output_write.amber
new file mode 100644 (file)
index 0000000..a4a3619
--- /dev/null
@@ -0,0 +1,161 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  out_data = 1;
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_1 = OpConstant %int 1
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+OpStore %out_data %int_1
+OpReturn
+OpFunctionEnd
+END
+
+SHADER vertex passthrough PASSTHROUGH
+SHADER fragment expect_fs GLSL
+#version 450
+
+layout(location = 0) out int out_data;
+void main() {
+  bool x_is_odd = (int(gl_FragCoord.x) & 0x1) == 1;
+  bool y_is_odd = (int(gl_FragCoord.y) & 0x1) == 1;
+  out_data = (x_is_odd || y_is_odd) ? 1 : 0;
+}
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE expect_frame DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+END
+
+PIPELINE graphics expect_pipe
+  ATTACH passthrough
+  ATTACH expect_fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  BIND BUFFER expect_frame AS color LOCATION 0
+END
+
+RUN expect_pipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT out_data EQ_BUFFER expect_frame
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_output_write_before_terminate.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_output_write_before_terminate.amber
new file mode 100644 (file)
index 0000000..d94e3e4
--- /dev/null
@@ -0,0 +1,160 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  out_data = 1;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_1 = OpConstant %int 1
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+OpStore %out_data %int_1
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+OpReturn
+OpFunctionEnd
+END
+
+SHADER vertex passthrough PASSTHROUGH
+SHADER fragment expect_fs GLSL
+#version 450
+
+layout(location = 0) out int out_data;
+void main() {
+  bool x_is_odd = (int(gl_FragCoord.x) & 0x1) == 1;
+  bool y_is_odd = (int(gl_FragCoord.y) & 0x1) == 1;
+  out_data = (x_is_odd || y_is_odd) ? 1 : 0;
+}
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE expect_frame DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+END
+
+PIPELINE graphics expect_pipe
+  ATTACH passthrough
+  ATTACH expect_fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  BIND BUFFER expect_frame AS color LOCATION 0
+END
+
+RUN expect_pipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT out_data EQ_BUFFER expect_frame
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_ssbo_atomic.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_ssbo_atomic.amber
new file mode 100644 (file)
index 0000000..7f06a6e
--- /dev/null
@@ -0,0 +1,173 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  atomicAdd(a.a[x_coord + 8 * y_coord], x_coord);
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%device = OpConstant %int 1
+%relaxed = OpConstant %int 0
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+%old = OpAtomicIAdd %int %a_gep %device %relaxed %x
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER expect_buf DATA_TYPE int32 DATA
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_ssbo_store.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/no_ssbo_store.amber
new file mode 100644 (file)
index 0000000..69a8ffe
--- /dev/null
@@ -0,0 +1,171 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  a.a[x_coord + 8 * y_coord] = x_coord;
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+OpStore %a_gep %x
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER expect_buf DATA_TYPE int32 DATA
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+0 1 0 3 0 5 0 7
+0 1 2 3 4 5 6 7
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/ssbo_atomic_before_terminate.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/ssbo_atomic_before_terminate.amber
new file mode 100644 (file)
index 0000000..6126f36
--- /dev/null
@@ -0,0 +1,172 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  atomicAdd(a.a[x_coord + 8 * y_coord], x_coord);
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%device = OpConstant %int 1
+%relaxed = OpConstant %int 0
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+%old = OpAtomicIAdd %int %a_gep %device %relaxed %x
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER expect_buf DATA_TYPE int32 DATA
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/ssbo_store_before_terminate.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/ssbo_store_before_terminate.amber
new file mode 100644 (file)
index 0000000..b56f86c
--- /dev/null
@@ -0,0 +1,170 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#pragma GL_EXT_terminate_invocation : enable
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;layout(set = 0, binding = 0) buffer A { uint a[]; } a;
+;void main() {
+;  out_data = 1;
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  a.a[x_coord + 8 * y_coord] = x_coord;
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %a DescriptorSet 0
+OpDecorate %a Binding 0
+OpDecorate %a_block Block
+OpMemberDecorate %a_block 0 Offset 0
+OpDecorate %rta ArrayStride 4
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_8 = OpConstant %int 8
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%rta = OpTypeRuntimeArray %int
+%a_block = OpTypeStruct %rta
+%ptr_int_ssbo = OpTypePointer StorageBuffer %int
+%ptr_a_ssbo = OpTypePointer StorageBuffer %a_block
+%a = OpVariable %ptr_a_ssbo StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpStore %out_data %int_1
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%offset = OpIMul %int %y %int_8
+%idx = OpIAdd %int %x %offset
+%a_gep = OpAccessChain %ptr_int_ssbo %a %int_0 %idx
+OpStore %a_gep %x
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+OpReturn
+OpFunctionEnd
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+BUFFER a_buf DATA_TYPE int32 SIZE 64 FILL 0
+BUFFER expect_buf DATA_TYPE int32 DATA
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+END
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+  BIND BUFFER a_buf AS storage DESCRIPTOR_SET 0 BINDING 0
+END
+
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT a_buf EQ_BUFFER expect_buf
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/subgroup_ballot.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/subgroup_ballot.amber
new file mode 100644 (file)
index 0000000..cb3a11b
--- /dev/null
@@ -0,0 +1,225 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#extension GL_KHR_shader_subgroup_ballot : enable
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;
+;void main() {
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  bool cond = combined == int(gl_FragCoord.z);
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  int quad_idx = (x_coord & 0x1) + 2 * (y_coord & 0x1);
+;  uvec4 b = subgroupBallot(true);
+;  uint element;
+;  if (gl_SubgroupInvocationID < 32)
+;      element = b.x;
+;  else if (gl_SubgroupInvocationID < 64)
+;      element = b.y;
+;  else if (gl_SubgroupInvocationID < 96)
+;      element = b.z;
+;  else
+;      element = b.w;
+;  uint base_bit = (gl_SubgroupInvocationID - quad_idx) % 32;
+;  bool check_quad_idx_0 = ((element >> base_bit) & 0x1) == 0;
+;  out_data = check_quad_idx_0 ? 1 : 0;
+;
+;}
+OpCapability Shader
+OpCapability GroupNonUniformBallot
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data %subgroupID
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %subgroupID Flat
+OpDecorate %subgroupID BuiltIn SubgroupLocalInvocationId
+%void = OpTypeVoid
+%bool = OpTypeBool
+%true = OpConstantTrue %bool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_2 = OpConstant %int 2
+%int_3 = OpConstant %int 3
+%int_32 = OpConstant %int 32
+%int_64 = OpConstant %int 64
+%int_96 = OpConstant %int 96
+%subgroup = OpConstant %int 3
+%int4 = OpTypeVector %int 4
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%subgroupID = OpVariable %ptr_int_input Input
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%y_2 = OpIMul %int %int_2 %y_and_1
+%quad_idx = OpIAdd %int %x_and_1 %y_2
+%b = OpGroupNonUniformBallot %int4 %subgroup %true
+%sid = OpLoad %int %subgroupID
+%less_than_32 = OpULessThan %bool %sid %int_32
+OpSelectionMerge %merge_32 None
+OpBranchConditional %less_than_32 %then_32 %else_32
+%then_32 = OpLabel
+%element_0 = OpCompositeExtract %int %b 0
+OpBranch %merge_32
+%else_32 = OpLabel
+%less_than_64 = OpULessThan %bool %sid %int_64
+OpSelectionMerge %merge_64 None
+OpBranchConditional %less_than_64 %then_64 %else_64
+%then_64 = OpLabel
+%element_1 = OpCompositeExtract %int %b 1
+OpBranch %merge_64
+%else_64 = OpLabel
+%less_than_96 = OpULessThan %bool %sid %int_96
+%element_2 = OpCompositeExtract %int %b 2
+%element_3 = OpCompositeExtract %int %b 3
+%sel_96 = OpSelect %int %less_than_96 %element_2 %element_3
+OpBranch %merge_64
+%merge_64 = OpLabel
+%phi_64 = OpPhi %int %element_1 %then_64 %sel_96 %else_64
+OpBranch %merge_32
+%merge_32 = OpLabel
+%phi_32 = OpPhi %int %element_0 %then_32 %phi_64 %merge_64
+%bit = OpISub %int %sid %quad_idx
+%base_bit = OpUMod %int %bit %int_32
+%idx_0_shift = OpShiftRightLogical %int %phi_32 %base_bit
+%idx_0_shift_and_1 = OpBitwiseAnd %int %idx_0_shift %int_1
+%idx_0_check = OpIEqual %bool %idx_0_shift_and_1 %int_0
+%out_val = OpSelect %int %idx_0_check %int_1 %int_0
+OpStore %out_data %out_val
+OpReturn
+OpFunctionEnd
+END
+
+SHADER vertex passthrough PASSTHROUGH
+SHADER fragment expect_fs GLSL
+#version 450
+
+layout(location = 0) out int out_data;
+void main() {
+  bool x_is_odd = (int(gl_FragCoord.x) & 0x1) == 1;
+  bool y_is_odd = (int(gl_FragCoord.y) & 0x1) == 1;
+  out_data = (x_is_odd || y_is_odd) ? 1 : 0;
+}
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE expect_frame DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+END
+
+PIPELINE graphics expect_pipe
+  ATTACH passthrough
+  ATTACH expect_fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  BIND BUFFER expect_frame AS color LOCATION 0
+END
+
+RUN expect_pipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT out_data EQ_BUFFER expect_frame
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/subgroup_vote.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/subgroup_vote.amber
new file mode 100644 (file)
index 0000000..15731ac
--- /dev/null
@@ -0,0 +1,176 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;#extension GL_KHR_shader_subgroup_vote : enable
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;
+;void main() {
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  bool cond = combined == int(gl_FragCoord.z);
+;  if (combined == int(gl_FragCoord.z))
+;    terminateInvocation;
+;
+;  bool all = subgroupAll(cond);
+;  out_data = all ? 1 : 0;
+;}
+OpCapability Shader
+OpCapability GroupNonUniformVote
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data %subgroupID
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+OpDecorate %subgroupID Flat
+OpDecorate %subgroupID BuiltIn SubgroupLocalInvocationId
+%void = OpTypeVoid
+%bool = OpTypeBool
+%true = OpConstantTrue %bool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%subgroup = OpConstant %int 3
+%int4 = OpTypeVector %int 4
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%subgroupID = OpVariable %ptr_int_input Input
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+%not_cmp = OpLogicalNot %bool %cmp
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+OpTerminateInvocation
+%exit = OpLabel
+%all = OpGroupNonUniformAll %bool %subgroup %not_cmp
+%sel = OpSelect %int %all %int_1 %int_0
+OpStore %out_data %sel
+OpReturn
+OpFunctionEnd
+END
+
+SHADER vertex passthrough PASSTHROUGH
+SHADER fragment expect_fs GLSL
+#version 450
+
+layout(location = 0) out int out_data;
+void main() {
+  bool x_is_odd = (int(gl_FragCoord.x) & 0x1) == 1;
+  bool y_is_odd = (int(gl_FragCoord.y) & 0x1) == 1;
+  out_data = (x_is_odd || y_is_odd) ? 1 : 0;
+}
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE expect_frame DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+END
+
+PIPELINE graphics expect_pipe
+  ATTACH passthrough
+  ATTACH expect_fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  BIND BUFFER expect_frame AS color LOCATION 0
+END
+
+RUN expect_pipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT out_data EQ_BUFFER expect_frame
+
diff --git a/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/terminate_loop.amber b/external/vulkancts/data/vulkan/amber/spirv_assembly/instruction/terminate_invocation/terminate_loop.amber
new file mode 100644 (file)
index 0000000..561ba53
--- /dev/null
@@ -0,0 +1,174 @@
+#!amber
+
+SHADER vertex vs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in vec3 position;
+;layout(location = 1) in int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  gl_Position = vec4(position, 1.0);
+;  out_data = int(in_data);
+;}
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %position %in_data %out_data %per_vertex
+OpDecorate %position Location 0
+OpDecorate %in_data Location 1
+OpDecorate %out_data Location 0
+OpDecorate %block Block
+OpMemberDecorate %block 0 BuiltIn Position
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float_1 = OpConstant %float 1
+%float3 = OpTypeVector %float 3
+%float4 = OpTypeVector %float 4
+%ptr_float3_input = OpTypePointer Input %float3
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%block = OpTypeStruct %float4
+%ptr_float4_output = OpTypePointer Output %float4
+%ptr_block_output = OpTypePointer Output %block
+%position = OpVariable %ptr_float3_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%per_vertex = OpVariable %ptr_block_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%ld_pos = OpLoad %float3 %position
+%out_pos = OpCompositeConstruct %float4 %ld_pos %float_1
+%out_pos_gep = OpAccessChain %ptr_float4_output %per_vertex %int_0
+OpStore %out_pos_gep %out_pos
+OpCopyMemory %out_data %in_data
+OpReturn
+OpFunctionEnd
+END
+
+SHADER fragment fs SPIRV-ASM
+;#version 450
+;
+;layout(location = 0) in flat int in_data;
+;layout(location = 0) out int out_data;
+;void main() {
+;  int x_coord = int(gl_FragCoord.x);
+;  int y_coord = int(gl_FragCoord.y);
+;  int combined = (x_coord & 0x1) + (y_coord & 0x1) + in_data;
+;  if (combined == int(gl_FragCoord.z))
+;    for (int i = 0; i < 10; i += in_data)
+;      terminate_invocation;
+;
+;  out_data = 1;
+;}
+OpCapability Shader
+OpExtension "SPV_KHR_terminate_invocation"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %frag_coord %in_data %out_data
+OpExecutionMode %main OriginUpperLeft
+OpDecorate %frag_coord BuiltIn FragCoord
+OpDecorate %in_data Location 0
+OpDecorate %in_data Flat
+OpDecorate %out_data Location 0
+%void = OpTypeVoid
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_10 = OpConstant %int 10
+%float = OpTypeFloat 32
+%float4 = OpTypeVector %float 4
+%ptr_int_input = OpTypePointer Input %int
+%ptr_int_output = OpTypePointer Output %int
+%ptr_float4_input = OpTypePointer Input %float4
+%frag_coord = OpVariable %ptr_float4_input Input
+%in_data = OpVariable %ptr_int_input Input
+%out_data = OpVariable %ptr_int_output Output
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%coord = OpLoad %float4 %frag_coord
+%x_coord = OpCompositeExtract %float %coord 0
+%y_coord = OpCompositeExtract %float %coord 1
+%z_coord = OpCompositeExtract %float %coord 2
+%x = OpConvertFToS %int %x_coord
+%y = OpConvertFToS %int %y_coord
+%z = OpConvertFToS %int %z_coord
+%x_and_1 = OpBitwiseAnd %int %x %int_1
+%y_and_1 = OpBitwiseAnd %int %y %int_1
+%add = OpIAdd %int %x_and_1 %y_and_1
+%ld_in_data = OpLoad %int %in_data
+%combined = OpIAdd %int %add %ld_in_data
+%cmp = OpIEqual %bool %combined %z
+OpSelectionMerge %exit None
+OpBranchConditional %cmp %then %exit
+%then = OpLabel
+%i = OpPhi %int %int_0 %entry %inc %continue
+%i_cmp = OpULessThan %bool %i %int_10
+OpLoopMerge %loop_merge %continue None
+OpBranchConditional %i_cmp %body %loop_merge
+%body = OpLabel
+OpTerminateInvocation
+%continue = OpLabel
+%inc = OpIAdd %int %i %int_1
+OpBranch %then
+%loop_merge = OpLabel
+OpBranch %exit
+%exit = OpLabel
+OpStore %out_data %int_1
+OpReturn
+OpFunctionEnd
+END
+
+SHADER vertex passthrough PASSTHROUGH
+SHADER fragment expect_fs GLSL
+#version 450
+
+layout(location = 0) out int out_data;
+void main() {
+  bool x_is_odd = (int(gl_FragCoord.x) & 0x1) == 1;
+  bool y_is_odd = (int(gl_FragCoord.y) & 0x1) == 1;
+  out_data = (x_is_odd || y_is_odd) ? 1 : 0;
+}
+END
+
+BUFFER position_buf DATA_TYPE vec3<float> DATA
+-1 -1 0
+-1  1 0
+ 1 -1 0
+
+-1  1 0
+ 1 -1 0
+ 1  1 0
+END
+
+BUFFER in_data_buf DATA_TYPE int32 SIZE 6 FILL 0
+
+IMAGE out_data DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+IMAGE expect_frame DATA_TYPE int32 DIM_2D WIDTH 8 HEIGHT 8 FILL 0
+
+PIPELINE graphics gpipe
+  ATTACH vs
+  ATTACH fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  VERTEX_DATA in_data_buf LOCATION 1
+  BIND BUFFER out_data AS color LOCATION 0
+END
+
+PIPELINE graphics expect_pipe
+  ATTACH passthrough
+  ATTACH expect_fs
+
+  FRAMEBUFFER_SIZE 8 8
+  VERTEX_DATA position_buf LOCATION 0
+  BIND BUFFER expect_frame AS color LOCATION 0
+END
+
+RUN expect_pipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+RUN gpipe DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
+EXPECT out_data EQ_BUFFER expect_frame
+
index ca59c52..a11211e 100644 (file)
@@ -63,5 +63,6 @@ static const char* s_allowedDeviceKhrExtensions[] =
        "VK_KHR_performance_query",
        "VK_KHR_shader_non_semantic_info",
        "VK_KHR_copy_commands2",
+       "VK_KHR_shader_terminate_invocation",
 };
 
index e8c7646..4460381 100644 (file)
@@ -266,6 +266,16 @@ bool checkMandatoryFeatures(const vkt::Context& context)
                nextPtr  = &physicalDeviceShaderSubgroupExtendedTypesFeaturesKHR.pNext;
        }
 
+       vk::VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR physicalDeviceShaderTerminateInvocationFeaturesKHR;
+       deMemset(&physicalDeviceShaderTerminateInvocationFeaturesKHR, 0, sizeof(physicalDeviceShaderTerminateInvocationFeaturesKHR));
+
+       if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_terminate_invocation")) )
+       {
+               physicalDeviceShaderTerminateInvocationFeaturesKHR.sType = getStructureType<VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR>();
+               *nextPtr = &physicalDeviceShaderTerminateInvocationFeaturesKHR;
+               nextPtr  = &physicalDeviceShaderTerminateInvocationFeaturesKHR.pNext;
+       }
+
        vk::VkPhysicalDeviceSubgroupSizeControlFeaturesEXT physicalDeviceSubgroupSizeControlFeaturesEXT;
        deMemset(&physicalDeviceSubgroupSizeControlFeaturesEXT, 0, sizeof(physicalDeviceSubgroupSizeControlFeaturesEXT));
 
@@ -1099,6 +1109,15 @@ bool checkMandatoryFeatures(const vkt::Context& context)
                }
        }
 
+       if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_shader_terminate_invocation")) )
+       {
+               if ( physicalDeviceShaderTerminateInvocationFeaturesKHR.shaderTerminateInvocation == VK_FALSE )
+               {
+                       log << tcu::TestLog::Message << "Mandatory feature shaderTerminateInvocation not supported" << tcu::TestLog::EndMessage;
+                       result = false;
+               }
+       }
+
        return result;
 }
 
index 9676839..f4eb914 100644 (file)
@@ -87,6 +87,8 @@ static bool isFeatureSupported(const vkt::Context& ctx, const std::string& featu
                return ctx.getDeviceFeatures().tessellationShader;
        if (feature == "Features.geometryShader")
                return ctx.getDeviceFeatures().geometryShader;
+       if (feature == "Features.fragmentStoresAndAtomics")
+               return ctx.getDeviceFeatures().fragmentStoresAndAtomics;
        if (feature == "Features.vertexPipelineStoresAndAtomics")
                return ctx.getDeviceFeatures().vertexPipelineStoresAndAtomics;
        if (feature == "Features.fillModeNonSolid")
@@ -97,6 +99,12 @@ static bool isFeatureSupported(const vkt::Context& ctx, const std::string& featu
                return ctx.getVariablePointersFeatures().variablePointersStorageBuffer;
        if (feature == "VariablePointerFeatures.variablePointers")
                return ctx.getVariablePointersFeatures().variablePointers;
+       if (feature == "SubgroupProperties.supportedStages.fragment")
+               return (ctx.getSubgroupProperties().supportedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0;
+       if (feature == "SubgroupProperties.supportedOperations.vote")
+               return (ctx.getSubgroupProperties().supportedOperations & vk::VK_SUBGROUP_FEATURE_VOTE_BIT) != 0;
+       if (feature == "SubgroupProperties.supportedOperations.ballot")
+               return (ctx.getSubgroupProperties().supportedOperations & vk::VK_SUBGROUP_FEATURE_BALLOT_BIT) != 0;
 
        std::string message = std::string("Unexpected feature name: ") + feature;
        TCU_THROW(InternalError, message.c_str());
index fe47bf6..abaae17 100644 (file)
@@ -41,6 +41,8 @@ set(DEQP_VK_SPIRV_ASSEMBLY_SRCS
        vktSpvAsm64bitCompareTests.hpp
        vktSpvAsmTypeTests.cpp
        vktSpvAsmTypeTests.hpp
+       vktSpvAsmTerminateInvocationTests.cpp
+       vktSpvAsmTerminateInvocationTests.hpp
        vktSpvAsmTests.cpp
        vktSpvAsmTests.hpp
        vktSpvAsmUtils.cpp
index e93750b..276bc5c 100644 (file)
@@ -83,6 +83,7 @@
 #include "vktSpvAsmNonSemanticInfoTests.hpp"
 #include "vktSpvAsm64bitCompareTests.hpp"
 #include "vktSpvAsmTrinaryMinMaxTests.hpp"
+#include "vktSpvAsmTerminateInvocationTests.hpp"
 
 #include <cmath>
 #include <limits>
@@ -20540,6 +20541,7 @@ tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
        instructionTests->addChild(createSpirvVersion1p4Group(testCtx));
        instructionTests->addChild(createFunctionParamsGroup(testCtx));
        instructionTests->addChild(createTrinaryMinMaxGroup(testCtx));
+       instructionTests->addChild(createTerminateInvocationGroup(testCtx));
 
        return instructionTests.release();
 }
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.cpp
new file mode 100644 (file)
index 0000000..14afeea
--- /dev/null
@@ -0,0 +1,148 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2020 Google LLC
+ * Copyright (c) 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.
+ *
+ *//*!
+ * \file
+ * \brief Test new features in VK_KHR_shader_terminate_invocation
+ *//*--------------------------------------------------------------------*/
+
+#include <string>
+#include <vector>
+#include <amber/amber.h>
+
+#include "tcuDefs.hpp"
+
+#include "vkDefs.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktAmberTestCase.hpp"
+#include "vktSpvAsmTerminateInvocationTests.hpp"
+#include "vktTestGroupUtil.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+namespace
+{
+
+struct Case
+{
+       Case(const char* b, const char* d, bool v) : basename(b), description(d), spv1p3(v), requirements() { }
+       Case(const char* b, const char* d, bool v, const std::vector<std::string>& e) : basename(b), description(d), spv1p3(v), requirements(e) { }
+       const char *basename;
+       const char *description;
+       bool spv1p3;
+       // Additional Vulkan requirements, if any.
+       std::vector<std::string> requirements;
+};
+struct CaseGroup
+{
+       CaseGroup(const char* the_data_dir) : data_dir(the_data_dir) { }
+       void add(const char* basename, const char* description, bool spv1p3)
+       {
+               cases.push_back(Case(basename, description, spv1p3));
+       }
+       void add(const char* basename, const char* description, bool spv1p3, const std::vector<std::string>& requirements)
+       {
+               cases.push_back(Case(basename, description, spv1p3, requirements));
+       }
+
+       const char* data_dir;
+       std::vector<Case> cases;
+};
+
+
+void addTestsForAmberFiles (tcu::TestCaseGroup* tests, CaseGroup group)
+{
+       tcu::TestContext& testCtx = tests->getTestContext();
+       const std::string data_dir(group.data_dir);
+       const std::string category = data_dir;
+       std::vector<Case> cases(group.cases);
+
+       for (unsigned i = 0; i < cases.size() ; ++i)
+       {
+               deUint32 vulkan_version = cases[i].spv1p3 ? VK_MAKE_VERSION(1, 1, 0) : VK_MAKE_VERSION(1, 0, 0);
+               vk::SpirvVersion spirv_version = cases[i].spv1p3 ? vk::SPIRV_VERSION_1_3 : vk::SPIRV_VERSION_1_0;
+               vk::SpirVAsmBuildOptions asm_options(vulkan_version, spirv_version);
+
+               const std::string file = std::string(cases[i].basename) + ".amber";
+               cts_amber::AmberTestCase *testCase = cts_amber::createAmberTestCase(testCtx,
+                                                                                                                                                       cases[i].basename,
+                                                                                                                                                       cases[i].description,
+                                                                                                                                                       category.c_str(),
+                                                                                                                                                       file);
+               DE_ASSERT(testCase != DE_NULL);
+               testCase->addRequirement("VK_KHR_shader_terminate_invocation");
+               const std::vector<std::string>& reqmts = cases[i].requirements;
+               for (size_t r = 0; r < reqmts.size() ; ++r)
+               {
+                       testCase->addRequirement(reqmts[r]);
+               }
+
+               testCase->setSpirVAsmBuildOptions(asm_options);
+               tests->addChild(testCase);
+       }
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createTerminateInvocationGroup(tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> terminateTests(new tcu::TestCaseGroup(testCtx, "terminate_invocation", "VK_KHR_shader_terminate_invocation tests"));
+
+       const char* data_data = "spirv_assembly/instruction/terminate_invocation";
+
+       std::vector<std::string> Stores;
+       Stores.push_back("Features.fragmentStoresAndAtomics");
+
+       std::vector<std::string> VarPtr;
+       VarPtr.push_back("VariablePointerFeatures.variablePointersStorageBuffer");
+       VarPtr.push_back("Features.fragmentStoresAndAtomics");
+
+       std::vector<std::string> Vote;
+       Vote.push_back("SubgroupProperties.supportedOperations.vote");
+       Vote.push_back("SubgroupProperties.supportedStages.fragment");
+
+       std::vector<std::string> Ballot;
+       Ballot.push_back("SubgroupProperties.supportedOperations.ballot");
+       Ballot.push_back("SubgroupProperties.supportedStages.fragment");
+
+       CaseGroup group(data_data);
+       group.add("no_output_write", "no write to after calling terminate invocation", false);
+       group.add("no_output_write_before_terminate", "no write to output despite occurring before terminate invocation", false);
+       group.add("no_ssbo_store", "no store to SSBO when it occurs after terminate invocation", false, Stores);
+       group.add("no_ssbo_atomic", "no atomic update to SSBO when it occurs after terminate invocation", false, Stores);
+       group.add("ssbo_store_before_terminate", "ssbo store commits when it occurs before terminate invocation", false, Stores);
+       group.add("no_image_store", "no image write when it occurs after terminate invocation", false, Stores);
+       group.add("no_image_atomic", "no image atomic updates when it occurs after terminate invocation", false, Stores);
+       group.add("no_null_pointer_load", "null pointer should not be accessed by a load in a terminated invocation", false, VarPtr);
+       group.add("no_null_pointer_store", "null pointer should not be accessed by a store in a terminated invocation", false, VarPtr);
+       group.add("no_out_of_bounds_load", "out of bounds pointer should not be accessed by a load in a terminated invocation", false, VarPtr);
+       group.add("no_out_of_bounds_store", "out of bounds pointer should not be accessed by a store in a terminated invocation", false, VarPtr);
+       group.add("no_out_of_bounds_atomic", "out of bounds pointer should not be accessed by an atomic in a terminated invocation", false, VarPtr);
+       group.add("terminate_loop", "\"inifinite\" loop that calls terminate invocation", false);
+       group.add("subgroup_ballot", "checks that terminated invocations don't participate in the ballot", true, Ballot);
+       group.add("subgroup_vote", "checks that a subgroup all does not include any terminated invocations", true, Vote);
+       terminateTests->addChild(createTestGroup(testCtx, "terminate", "Terminate Invocation", addTestsForAmberFiles, group));
+
+       return terminateTests.release();
+}
+
+} // SpirVAssembly
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.hpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmTerminateInvocationTests.hpp
new file mode 100644 (file)
index 0000000..43074fd
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _VKTSPVASMTERMINATEINVOCATIONTESTS_HPP
+#define _VKTSPVASMTERMINATEINVOCATIONTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2020 Google LLC
+ * Copyright (c) 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.
+ *
+ *//*!
+ * \file
+ * \brief Test new features in VK_KHR_shader_terminate_invocation
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace SpirVAssembly
+{
+
+tcu::TestCaseGroup*    createTerminateInvocationGroup (tcu::TestContext& testCtx);
+
+} // SpirVAssembly
+} // vkt
+
+#endif // _VKTSPVASMTERMINATEINVOCATIONTESTS_HPP
index 01bbfdb..500ea66 100644 (file)
@@ -407261,6 +407261,21 @@ dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.scalar
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec2
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec3
 dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.vec4
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_output_write
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_output_write_before_terminate
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_ssbo_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_ssbo_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.ssbo_store_before_terminate
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_image_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_image_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_null_pointer_load
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_null_pointer_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_load
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_store
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.no_out_of_bounds_atomic
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.terminate_loop
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_ballot
+dEQP-VK.spirv_assembly.instruction.terminate_invocation.terminate.subgroup_vote
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_vert
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_tessc
 dEQP-VK.spirv_assembly.type.scalar.i8.negate_tesse
index b97fdab..a4654ae 100644 (file)
@@ -82,3 +82,4 @@ VK_KHR_shader_clock                                                   DEVICE
 VK_KHR_performance_query                                       DEVICE
 VK_KHR_shader_non_semantic_info                                DEVICE
 VK_KHR_copy_commands2                                          DEVICE
+VK_KHR_shader_terminate_invocation                     DEVICE
index b24d354..88ed3f4 100644 (file)
@@ -85,3 +85,4 @@ VkPhysicalDeviceVulkan12Features                                                      FEATURES ( samplerMirrorClampToEdge )
 VkPhysicalDeviceVulkan12Features                                                       FEATURES ( samplerFilterMinmax )                                                                REQUIREMENTS ( "ApiVersion(1, 2, 0)" VK_EXT_sampler_filter_minmax )
 VkPhysicalDeviceVulkan12Features                                                       FEATURES ( shaderOutputViewportIndex )                                                  REQUIREMENTS ( "ApiVersion(1, 2, 0)" VK_EXT_shader_viewport_index_layer )
 VkPhysicalDeviceVulkan12Features                                                       FEATURES ( shaderOutputLayer )                                                                  REQUIREMENTS ( "ApiVersion(1, 2, 0)" VK_EXT_shader_viewport_index_layer )
+VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR           FEATURES ( shaderTerminateInvocation )                                                  REQUIREMENTS ( VK_KHR_shader_terminate_invocation )