| #!amber |
| |
| DEVICE_EXTENSION VK_KHR_shader_terminate_invocation |
| |
| 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 1 |
| %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 1 |
| %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 |
| |