1#!amber
2
3# Copyright 2020 Valve Corporation.
4# Copyright 2020 The Khronos Group Inc.
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18
19SHADER vertex vtx_shader SPIRV-ASM
20; SPIR-V
21; Version: 1.0
22; Generator: Khronos Glslang Reference Front End; 8
23; Bound: 30
24; Schema: 0
25;
26; Originally created from code like this one:
27;
28; #version 450
29; layout(location=0) in vec4 position;
30; void main() { gl_Position = position; }
31;
32                            OpCapability Shader
33                       %1 = OpExtInstImport "GLSL.std.450"
34                            OpMemoryModel Logical GLSL450
35                            OpEntryPoint Vertex %main "main" %_ %position
36                            OpSource GLSL 450
37                            OpName %main "main"
38                            OpName %gl_PerVertex "gl_PerVertex"
39                            OpMemberName %gl_PerVertex 0 "gl_Position"
40                            OpMemberName %gl_PerVertex 1 "gl_PointSize"
41                            OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
42                            OpMemberName %gl_PerVertex 3 "gl_CullDistance"
43                            OpName %_ ""
44                            OpName %position "position"
45                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
46                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
47                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
48                            OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
49                            OpDecorate %gl_PerVertex Block
50                            OpDecorate %position Location 0
51                    %void = OpTypeVoid
52                       %3 = OpTypeFunction %void
53                     %int = OpTypeInt 32 1
54                   %int_1 = OpConstant %int 1
55                   %float = OpTypeFloat 32
56                 %v4float = OpTypeVector %float 4
57                    %uint = OpTypeInt 32 0
58                  %uint_1 = OpConstant %uint 1
59       %_arr_float_uint_1 = OpTypeArray %float %uint_1
60            %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
61%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
62                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output
63                   %int_0 = OpConstant %int 0
64      %_ptr_Input_v4float = OpTypePointer Input %v4float
65                %position = OpVariable %_ptr_Input_v4float Input
66     %_ptr_Output_v4float = OpTypePointer Output %v4float
67                    %main = OpFunction %void None %3
68;
69; The rest of code below has been manually tuned.
70; The assignment to gl_Position is in the OpLoad, OpAccessChain and OpStore sequence.
71; It's wrapped inside a loop statement roughly equivalent to this:
72;
73; for (;;) {
74;     switch (1) {
75;         default:
76;            gl_Position = position;
77;            goto end;
78;     }
79; }
80; end:
81; return;
82;
83; Which means the code jumps directly from the end of the default block to the
84; loop exit, something that cannot be directly done in GLSL because it has no
85; goto nor any other equivalent instruction to directly exit the loop.
86;
87; The switch's merge block is unreachable and marked with OpUnreachable.
88; According to VK-GL-CTS issue #952, at least one driver goes into an infinite
89; loop when doing so.
90;
91              %main_start = OpLabel
92                            OpBranch %loop_start
93              %loop_start = OpLabel
94                            OpLoopMerge %loop_exit %loop_end None
95                            OpBranch %select_start
96            %select_start = OpLabel
97                            OpSelectionMerge %select_merge None
98                            OpSwitch %int_1 %switch_default
99          %switch_default = OpLabel
100                      %25 = OpLoad %v4float %position
101                      %27 = OpAccessChain %_ptr_Output_v4float %_ %int_0
102                            OpStore %27 %25
103                            OpBranch %loop_exit
104            %select_merge = OpLabel
105                            OpUnreachable
106                %loop_end = OpLabel
107                            OpBranch %loop_start
108               %loop_exit = OpLabel
109                            OpReturn
110                            OpFunctionEnd
111
112END
113
114SHADER fragment frag_shader GLSL
115#version 450
116
117layout(location = 0) out vec4 color_out;
118
119void main() {
120	// Red color.
121	color_out = vec4(1.0, 0.0, 0.0, 1.0);
122}
123END
124
125# Full-screen quad.
126BUFFER position_buf DATA_TYPE vec2<float> DATA
127-1 -1
128 1 -1
129-1  1
130-1  1
131 1 -1
132 1  1
133END
134
135BUFFER framebuffer FORMAT B8G8R8A8_UNORM
136
137PIPELINE graphics pipeline
138  ATTACH vtx_shader
139  ATTACH frag_shader
140
141  VERTEX_DATA position_buf LOCATION 0
142
143  FRAMEBUFFER_SIZE 64 64
144  BIND BUFFER framebuffer AS color LOCATION 0
145END
146
147CLEAR pipeline
148
149RUN pipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 6
150EXPECT framebuffer IDX 0 0 SIZE 64 64 EQ_RGBA 255 0 0 255
151