1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief SPIR-V Assembly Tests for OpBranchConditional instruction.
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSpvAsmConditionalBranchTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
28
29 #include "tcuStringTemplate.hpp"
30
31 namespace vkt
32 {
33 namespace SpirVAssembly
34 {
35
36 using namespace vk;
37 using std::map;
38 using std::string;
39 using std::vector;
40 using tcu::RGBA;
41 using tcu::IVec3;
42 using tcu::StringTemplate;
43
44 namespace
45 {
46
47 static const string conditions[] = { "true", "false" };
48
addComputeSameLabelsTest(tcu::TestCaseGroup * group)49 void addComputeSameLabelsTest (tcu::TestCaseGroup* group)
50 {
51 tcu::TestContext& testCtx = group->getTestContext();
52 const int numItems = 128;
53 vector<deUint32> outputData;
54
55 outputData.reserve(numItems);
56 for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
57 outputData.push_back(numIdx);
58
59 for (int conditionIdx = 0; conditionIdx < DE_LENGTH_OF_ARRAY(conditions); ++conditionIdx)
60 {
61 ComputeShaderSpec spec;
62 map<string, string> specs;
63 string testName = string("same_labels_") + conditions[conditionIdx];
64
65 const StringTemplate shaderSource (
66 " OpCapability Shader\n"
67 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
68 " OpMemoryModel Logical GLSL450\n"
69 " OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
70 " OpExecutionMode %main LocalSize 1 1 1\n"
71 " OpSource GLSL 430\n"
72 " OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
73 " OpDecorate %_arr_uint_uint_128 ArrayStride 4\n"
74 " OpMemberDecorate %Output 0 Offset 0\n"
75 " OpDecorate %Output BufferBlock\n"
76 " OpDecorate %dataOutput DescriptorSet 0\n"
77 " OpDecorate %dataOutput Binding 0\n"
78 " %void = OpTypeVoid\n"
79 " %3 = OpTypeFunction %void\n"
80 " %uint = OpTypeInt 32 0\n"
81 " %_ptr_Function_uint = OpTypePointer Function %uint\n"
82 " %v3uint = OpTypeVector %uint 3\n"
83 " %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
84 "%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
85 " %uint_0 = OpConstant %uint 0\n"
86 " %_ptr_Input_uint = OpTypePointer Input %uint\n"
87 " %bool = OpTypeBool\n"
88 " %true = OpConstantTrue %bool\n"
89 " %false = OpConstantFalse %bool\n"
90 " %uint_128 = OpConstant %uint 128\n"
91 " %_arr_uint_uint_128 = OpTypeArray %uint %uint_128\n"
92 " %Output = OpTypeStruct %_arr_uint_uint_128\n"
93 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
94 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
95 " %_ptr_Uniform_uint = OpTypePointer Uniform %uint\n"
96 " %uint_dummy = OpConstant %uint 2863311530\n"
97 " %main = OpFunction %void None %3\n"
98 " %5 = OpLabel\n"
99 " %i = OpVariable %_ptr_Function_uint Function\n"
100 " %14 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
101 " %15 = OpLoad %uint %14\n"
102 " OpStore %i %15\n"
103 " %uint_i = OpLoad %uint %i\n"
104 " OpSelectionMerge %merge None\n"
105 " OpBranchConditional %${condition} %live %live\n"
106 " %live = OpLabel\n"
107 " %31 = OpAccessChain %_ptr_Uniform_uint %dataOutput %uint_0 %uint_i\n"
108 " OpStore %31 %uint_i\n"
109 " OpBranch %merge\n"
110 " %dead = OpLabel\n"
111 " %35 = OpAccessChain %_ptr_Uniform_uint %dataOutput %uint_0 %uint_i\n"
112 " OpStore %35 %uint_dummy\n"
113 " OpBranch %merge\n"
114 " %merge = OpLabel\n"
115 " OpReturn\n"
116 " OpFunctionEnd\n");
117
118 specs["condition"] = conditions[conditionIdx];
119 spec.assembly = shaderSource.specialize(specs);
120 spec.numWorkGroups = IVec3(numItems, 1, 1);
121
122 spec.outputs.push_back(Resource(BufferSp(new Buffer<deUint32>(outputData))));
123
124 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), "Tests both labels pointing to a same branch.", spec));
125 }
126 }
127
addGraphicsSameLabelsTest(tcu::TestCaseGroup * group)128 void addGraphicsSameLabelsTest (tcu::TestCaseGroup* group)
129 {
130 const deUint32 numItems = 128;
131 RGBA defaultColors[4];
132 GraphicsResources resources;
133 vector<deUint32> outputData;
134 VulkanFeatures features;
135
136 outputData.reserve(numItems);
137 for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
138 outputData.push_back(numIdx);
139
140 resources.outputs.push_back(Resource(BufferSp(new Buffer<deUint32>(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
141
142 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
143 features.coreFeatures.fragmentStoresAndAtomics = true;
144
145 getDefaultColors(defaultColors);
146
147 for (int conditionIdx = 0; conditionIdx < DE_LENGTH_OF_ARRAY(conditions); ++conditionIdx)
148 {
149 map<string, string> fragments;
150 map<string, string> specs;
151 string testName = string("same_labels_") + conditions[conditionIdx];
152
153 fragments["pre_main"] =
154 " %c_u32_128 = OpConstant %u32 128\n"
155 " %true = OpConstantTrue %bool\n"
156 " %false = OpConstantFalse %bool\n"
157 " %_arr_uint_uint_128 = OpTypeArray %u32 %c_u32_128\n"
158 " %Output = OpTypeStruct %_arr_uint_uint_128\n"
159 "%_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
160 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
161 " %_ptr_Uniform_uint = OpTypePointer Uniform %u32\n"
162 " %fp_u32 = OpTypePointer Function %u32\n"
163 " %uint_dummy = OpConstant %u32 2863311530\n";
164
165 fragments["decoration"] =
166 " OpDecorate %_arr_uint_uint_128 ArrayStride 4\n"
167 " OpMemberDecorate %Output 0 Offset 0\n"
168 " OpDecorate %Output BufferBlock\n"
169 " OpDecorate %dataOutput DescriptorSet 0\n"
170 " OpDecorate %dataOutput Binding 0\n";
171
172 const StringTemplate testFun (
173 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
174 " %param = OpFunctionParameter %v4f32\n"
175
176 " %entry = OpLabel\n"
177 " %i = OpVariable %fp_u32 Function\n"
178 " OpStore %i %c_u32_0\n"
179 " OpBranch %loop\n"
180
181 " %loop = OpLabel\n"
182 " %15 = OpLoad %u32 %i\n"
183 " %lt = OpSLessThan %bool %15 %c_u32_128\n"
184 " OpLoopMerge %merge %inc None\n"
185 " OpBranchConditional %lt %write %merge\n"
186
187 " %write = OpLabel\n"
188 " %uint_i = OpLoad %u32 %i\n"
189 " OpSelectionMerge %condmerge None\n"
190 " OpBranchConditional %${condition} %live %live\n"
191 " %live = OpLabel\n"
192 " %31 = OpAccessChain %_ptr_Uniform_uint %dataOutput %c_u32_0 %uint_i\n"
193 " OpStore %31 %uint_i\n"
194 " OpBranch %condmerge\n"
195 " %dead = OpLabel\n"
196 " %35 = OpAccessChain %_ptr_Uniform_uint %dataOutput %c_u32_0 %uint_i\n"
197 " OpStore %35 %uint_dummy\n"
198 " OpBranch %condmerge\n"
199 " %condmerge = OpLabel\n"
200 " OpBranch %inc\n"
201
202 " %inc = OpLabel\n"
203 " %37 = OpLoad %u32 %i\n"
204 " %39 = OpIAdd %u32 %37 %c_u32_1\n"
205 " OpStore %i %39\n"
206 " OpBranch %loop\n"
207
208 " %merge = OpLabel\n"
209 " OpReturnValue %param\n"
210
211 " OpFunctionEnd\n");
212
213 specs["condition"] = conditions[conditionIdx];
214 fragments["testfun"] = testFun.specialize(specs);
215
216 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, resources, vector<string>(), group, features);
217 }
218 }
219
220 } // anonymous
221
createConditionalBranchComputeGroup(tcu::TestContext & testCtx)222 tcu::TestCaseGroup* createConditionalBranchComputeGroup (tcu::TestContext& testCtx)
223 {
224 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "conditional_branch", "Compute tests for OpBranchConditional."));
225 addComputeSameLabelsTest(group.get());
226
227 return group.release();
228 }
229
createConditionalBranchGraphicsGroup(tcu::TestContext & testCtx)230 tcu::TestCaseGroup* createConditionalBranchGraphicsGroup (tcu::TestContext& testCtx)
231 {
232 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "conditional_branch", "Graphics tests for OpBranchConditional."));
233 addGraphicsSameLabelsTest(group.get());
234
235 return group.release();
236 }
237
238 } // SpirVAssembly
239 } // vkt
240