blob: 3423b61696d703e343958a6d75bf70303bd3c14a [file] [log] [blame]
#!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 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
;
;#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 1
%uint = 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
%uint4 = OpTypeVector %uint 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 %uint4 %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 %uint %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 %uint %b 1
OpBranch %merge_64
%else_64 = OpLabel
%less_than_96 = OpULessThan %bool %sid %int_96
%element_2 = OpCompositeExtract %uint %b 2
%element_3 = OpCompositeExtract %uint %b 3
%sel_96 = OpSelect %uint %less_than_96 %element_2 %element_3
OpBranch %merge_64
%merge_64 = OpLabel
%phi_64 = OpPhi %uint %element_1 %then_64 %sel_96 %else_64
OpBranch %merge_32
%merge_32 = OpLabel
%phi_32 = OpPhi %uint %element_0 %then_32 %phi_64 %merge_64
%bit = OpISub %int %sid %quad_idx
%base_bit = OpSMod %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