#!amber # Copyright 2020 Valve Corporation. # Copyright 2020 The Khronos Group Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. SHADER vertex vtx_shader SPIRV-ASM ; SPIR-V ; Version: 1.0 ; Generator: Khronos Glslang Reference Front End; 8 ; Bound: 30 ; Schema: 0 ; ; Originally created from code like this one: ; ; #version 450 ; layout(location=0) in vec4 position; ; void main() { gl_Position = position; } ; OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Vertex %main "main" %_ %position OpSource GLSL 450 OpName %main "main" OpName %gl_PerVertex "gl_PerVertex" OpMemberName %gl_PerVertex 0 "gl_Position" OpMemberName %gl_PerVertex 1 "gl_PointSize" OpMemberName %gl_PerVertex 2 "gl_ClipDistance" OpMemberName %gl_PerVertex 3 "gl_CullDistance" OpName %_ "" OpName %position "position" OpMemberDecorate %gl_PerVertex 0 BuiltIn Position OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance OpDecorate %gl_PerVertex Block OpDecorate %position Location 0 %void = OpTypeVoid %3 = OpTypeFunction %void %int = OpTypeInt 32 1 %int_1 = OpConstant %int 1 %float = OpTypeFloat 32 %v4float = OpTypeVector %float 4 %uint = OpTypeInt 32 0 %uint_1 = OpConstant %uint 1 %_arr_float_uint_1 = OpTypeArray %float %uint_1 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex %_ = OpVariable %_ptr_Output_gl_PerVertex Output %int_0 = OpConstant %int 0 %_ptr_Input_v4float = OpTypePointer Input %v4float %position = OpVariable %_ptr_Input_v4float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %main = OpFunction %void None %3 ; ; The rest of code below has been manually tuned. ; The assignment to gl_Position is in the OpLoad, OpAccessChain and OpStore sequence. ; It's wrapped inside a loop statement roughly equivalent to this: ; ; for (;;) { ; switch (1) { ; default: ; gl_Position = position; ; goto end; ; } ; } ; end: ; return; ; ; Which means the code jumps directly from the end of the default block to the ; loop exit, something that cannot be directly done in GLSL because it has no ; goto nor any other equivalent instruction to directly exit the loop. ; ; The switch's merge block is unreachable and marked with OpUnreachable. ; According to VK-GL-CTS issue #952, at least one driver goes into an infinite ; loop when doing so. ; %main_start = OpLabel OpBranch %loop_start %loop_start = OpLabel OpLoopMerge %loop_exit %loop_end None OpBranch %select_start %select_start = OpLabel OpSelectionMerge %select_merge None OpSwitch %int_1 %switch_default %switch_default = OpLabel %25 = OpLoad %v4float %position %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0 OpStore %27 %25 OpBranch %loop_exit %select_merge = OpLabel OpUnreachable %loop_end = OpLabel OpBranch %loop_start %loop_exit = OpLabel OpReturn OpFunctionEnd END SHADER fragment frag_shader GLSL #version 450 layout(location = 0) out vec4 color_out; void main() { // Red color. color_out = vec4(1.0, 0.0, 0.0, 1.0); } END # Full-screen quad. BUFFER position_buf DATA_TYPE vec2 DATA -1 -1 1 -1 -1 1 -1 1 1 -1 1 1 END BUFFER framebuffer FORMAT B8G8R8A8_UNORM PIPELINE graphics pipeline ATTACH vtx_shader ATTACH frag_shader VERTEX_DATA position_buf LOCATION 0 FRAMEBUFFER_SIZE 64 64 BIND BUFFER framebuffer AS color LOCATION 0 END CLEAR pipeline RUN pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6 EXPECT framebuffer IDX 0 0 SIZE 64 64 EQ_RGBA 255 0 0 255