Refactor: Compatible compute and graphics VerifyIO
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmVariableInitTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 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 OpVariable initializer
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSpvAsmVariableInitTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
28 #include "tcuStringTemplate.hpp"
29
30 namespace vkt
31 {
32 namespace SpirVAssembly
33 {
34
35 using namespace vk;
36 using std::map;
37 using std::string;
38 using std::vector;
39 using tcu::IVec3;
40 using tcu::Vec4;
41 using tcu::RGBA;
42 using tcu::StringTemplate;
43
44 namespace
45 {
46
47 void addShaderCodeOutputFloat           (vk::SourceCollections& dst, InstanceContext context);
48 void addShaderCodeOutputVector          (vk::SourceCollections& dst, InstanceContext context);
49 void addShaderCodeOutputMatrix          (vk::SourceCollections& dst, InstanceContext context);
50 void addShaderCodeOutputFloatArray      (vk::SourceCollections& dst, InstanceContext context);
51 void addShaderCodeOutputStruct          (vk::SourceCollections& dst, InstanceContext context);
52
53 struct TestParams
54 {
55         string                                                                                  name;
56         string                                                                                  type;
57         int                                                                                             numComponents;
58         FunctionPrograms1<InstanceContext>::Function    shaderInit;
59 };
60
61 const TestParams        params[]        =
62 {
63         { "float",              "f32",                  1                               , addShaderCodeOutputFloat              },
64         { "vec4",               "v4f32",                4                               , addShaderCodeOutputVector             },
65         { "matrix",             "matrix",               2 * 4                   , addShaderCodeOutputMatrix             },
66         { "floatarray", "floatArray",   8                               , addShaderCodeOutputFloatArray },
67         { "struct",             "struct",               2 * 4 + 4 + 4   , addShaderCodeOutputStruct             }
68 };
69
70 const string            common          =
71         "                %f32_1 = OpConstant %f32 1\n"
72         "              %v4f32_1 = OpConstantComposite %v4f32 %f32_1 %f32_1 %f32_1 %f32_1\n"
73         "               %matrix = OpTypeMatrix %v4f32 2\n"
74         "             %matrix_1 = OpConstantComposite %matrix %v4f32_1 %v4f32_1\n"
75         "               %struct = OpTypeStruct %matrix %v4f32 %f32 %f32 %f32 %f32\n"
76         "             %struct_1 = OpConstantComposite %struct %matrix_1 %v4f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
77         "              %c_u32_8 = OpConstant %u32 8\n"
78         "           %floatArray = OpTypeArray %f32 %c_u32_8\n"
79         "         %floatArray_1 = OpConstantComposite %floatArray %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
80         "          %numElements = OpConstant %u32 ${count}\n"
81         "          %outputArray = OpTypeArray %${type} %numElements\n"
82         "               %Output = OpTypeStruct %outputArray\n"
83         "          %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
84         "                %sbPtr = OpTypePointer StorageBuffer %${type}\n"
85         "           %dataOutput = OpVariable %_ptr_Output StorageBuffer\n";
86
87 const string            decorations     =
88         "                         OpDecorate %outputArray ArrayStride ${arrayStride}\n"
89         "                         OpMemberDecorate %Output 0 Offset 0\n"
90         "                         OpDecorate %Output Block\n"
91         "                         OpDecorate %dataOutput DescriptorSet 0\n"
92         "                         OpDecorate %dataOutput Binding 0\n"
93         "                         OpDecorate %floatArray ArrayStride 4\n"
94         "                         OpMemberDecorate %struct 0 ColMajor\n"
95         "                         OpMemberDecorate %struct 0 Offset 0\n"
96         "                         OpMemberDecorate %struct 0 MatrixStride 16\n"
97         "                         OpMemberDecorate %struct 1 Offset 32\n"
98         "                         OpMemberDecorate %struct 2 Offset 48\n"
99         "                         OpMemberDecorate %struct 3 Offset 52\n"
100         "                         OpMemberDecorate %struct 4 Offset 56\n"
101         "                         OpMemberDecorate %struct 5 Offset 60\n"
102         "${extraDecorations:opt}";
103
104 void addComputeVariableInitPrivateTest (tcu::TestCaseGroup* group)
105 {
106         tcu::TestContext&       testCtx                 = group->getTestContext();
107         const int                       numFloats               = 128;
108         tcu::TestCaseGroup*     privateGroup    = new tcu::TestCaseGroup(testCtx, "private", "Tests OpVariable initialization in private storage class.");
109         ComputeShaderSpec       spec;
110         vector<float>           expectedOutput;
111
112         const StringTemplate shaderSourceTemplate (
113                 string(
114                 "                         OpCapability Shader\n"
115                 "                         OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
116                 "                    %1 = OpExtInstImport \"GLSL.std.450\"\n"
117                 "                         OpMemoryModel Logical GLSL450\n"
118                 "                         OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
119                 "                         OpExecutionMode %main LocalSize 1 1 1\n"
120                 "                         OpSource GLSL 430\n"
121                 "                         OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n")
122                 + decorations + string(
123                 "                 %void = OpTypeVoid\n"
124                 "             %voidFunc = OpTypeFunction %void\n"
125                 "                  %f32 = OpTypeFloat 32\n"
126                 "                  %u32 = OpTypeInt 32 0\n"
127                 "              %c_u32_0 = OpConstant %u32 0\n"
128                 "                %v4f32 = OpTypeVector %f32 4\n")
129                 + common + string(
130                 "              %dataPtr = OpTypePointer Private %${type}\n"
131                 "   %_ptr_Function_uint = OpTypePointer Function %u32\n"
132                 "               %v3uint = OpTypeVector %u32 3\n"
133                 "    %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
134                 "%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
135                 "      %_ptr_Input_uint = OpTypePointer Input %u32\n"
136                 "                  %int = OpTypeInt 32 1\n"
137                 "                %int_0 = OpConstant %int 0\n"
138                 "                   %f1 = OpVariable %dataPtr Private %${constData}\n"
139                 "                 %main = OpFunction %void None %voidFunc\n"
140                 "                %entry = OpLabel\n"
141                 "        %invocationPtr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %c_u32_0\n"
142                 "           %invocation = OpLoad %u32 %invocationPtr\n"
143                 "           %outputData = OpLoad %${type} %f1\n"
144                 "            %outputPtr = OpAccessChain %sbPtr %dataOutput %int_0 %invocation\n"
145                 "                         OpStore %outputPtr %outputData\n"
146                 "                         OpReturn\n"
147                 "                         OpFunctionEnd\n"));
148
149         group->addChild(privateGroup);
150
151         expectedOutput.reserve(numFloats);
152         for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
153                 expectedOutput.push_back(1.0f);
154
155         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
156
157         for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
158         {
159                 map<string, string> shaderSpec;
160                 const int                       numComponents   = params[paramIdx].numComponents;
161                 const int                       numElements             = numFloats / numComponents;
162
163                 shaderSpec["type"]                      = params[paramIdx].type;
164                 shaderSpec["arrayStride"]       = de::toString(numComponents * 4);
165                 shaderSpec["count"]                     = de::toString(numElements);
166                 shaderSpec["constData"]         = params[paramIdx].type + "_1";
167
168                 if (params[paramIdx].type == "matrix")
169                 {
170                         shaderSpec["extraDecorations"] =
171                                 "                         OpMemberDecorate %Output 0 ColMajor\n"
172                                 "                         OpMemberDecorate %Output 0 MatrixStride 16\n";
173                 }
174
175                 spec.assembly                           = shaderSourceTemplate.specialize(shaderSpec);
176                 spec.numWorkGroups                      = IVec3(numElements, 1, 1);
177                 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
178
179                 privateGroup->addChild(new SpvAsmComputeShaderCase(testCtx, params[paramIdx].name.c_str(), "", spec));
180         }
181 }
182
183 void addGraphicsVariableInitPrivateTest (tcu::TestCaseGroup* group)
184 {
185         tcu::TestContext&               testCtx                         = group->getTestContext();
186         map<string, string>             fragments;
187         RGBA                                    defaultColors[4];
188         GraphicsResources               resources;
189         vector<string>                  extensions;
190         tcu::TestCaseGroup*             privateGroup            = new tcu::TestCaseGroup(testCtx, "private", "Tests OpVariable initialization in private storage class.");
191         const int                               numFloats                       = 128;
192         vector<float>                   expectedOutput;
193
194         StringTemplate                  preMain                         (
195                 common +
196                 "              %dataPtr = OpTypePointer Private %${type}\n"
197                 "                   %f1 = OpVariable %dataPtr Private %${constData}\n"
198                 );
199
200         StringTemplate                  decoration                      (decorations);
201
202         StringTemplate                  testFun                         (
203                 "            %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
204                 "                %param = OpFunctionParameter %v4f32\n"
205                 "                %entry = OpLabel\n"
206                 "                    %i = OpVariable %fp_i32 Function\n"
207                 "           %outputData = OpLoad %${type} %f1\n"
208                 "                         OpStore %i %c_i32_0\n"
209                 "                         OpBranch %loop\n"
210                 "                 %loop = OpLabel\n"
211                 "                   %15 = OpLoad %i32 %i\n"
212                 "                   %lt = OpSLessThan %bool %15 %numElements\n"
213                 "                         OpLoopMerge %merge %inc None\n"
214                 "                         OpBranchConditional %lt %write %merge\n"
215                 "                %write = OpLabel\n"
216                 "                   %30 = OpLoad %i32 %i\n"
217                 "            %outputPtr = OpAccessChain %sbPtr %dataOutput %c_i32_0 %30\n"
218                 "                         OpStore %outputPtr %outputData\n"
219                 "                         OpBranch %inc\n"
220                 "                  %inc = OpLabel\n"
221                 "                   %37 = OpLoad %i32 %i\n"
222                 "                   %39 = OpIAdd %i32 %37 %c_i32_1\n"
223                 "                         OpStore %i %39\n"
224                 "                         OpBranch %loop\n"
225                 "                %merge = OpLabel\n"
226                 "                         OpReturnValue %param\n"
227                 "                         OpFunctionEnd\n");
228
229
230         group->addChild(privateGroup);
231
232         getDefaultColors(defaultColors);
233
234         expectedOutput.reserve(numFloats);
235         for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
236                 expectedOutput.push_back(1.0f);
237
238         resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
239         extensions.push_back("VK_KHR_storage_buffer_storage_class");
240
241         for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
242         {
243                 map<string, string> shaderSpec;
244                 const int                       numComponents   = params[paramIdx].numComponents;
245                 const int                       numElements             = numFloats / numComponents;
246
247                 shaderSpec["type"]                      = params[paramIdx].type;
248                 shaderSpec["arrayStride"]       = de::toString(numComponents * 4);
249                 shaderSpec["count"]                     = de::toString(numElements);
250                 shaderSpec["constData"]         = params[paramIdx].type + "_1";
251
252                 if (params[paramIdx].type == "matrix")
253                 {
254                         shaderSpec["extraDecorations"] =
255                                 "                         OpMemberDecorate %Output 0 ColMajor\n"
256                                 "                         OpMemberDecorate %Output 0 MatrixStride 16\n";
257                 }
258
259                 fragments["extension"]          = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
260                 fragments["pre_main"]           = preMain.specialize(shaderSpec);
261                 fragments["decoration"]         = decoration.specialize(shaderSpec);
262                 fragments["testfun"]            = testFun.specialize(shaderSpec);
263
264                 createTestsForAllStages(params[paramIdx].name, defaultColors, defaultColors, fragments, resources, extensions, privateGroup);
265         }
266 }
267
268 void addShaderCodeOutput(vk::SourceCollections& dst, InstanceContext& context, string type)
269 {
270         SpirvVersion                    targetSpirvVersion      = context.resources.spirvVersion;
271         map<string, string>             spec;
272
273         // Needed for preventing duplicate pointer declarations.
274         if (type == "v4f32")
275         {
276                 spec["vec4ptrDeclOutput"]       = "";
277                 spec["vec4ptrOutput"]           = "outputPtr";
278                 spec["vec4ptrDeclInput"]        = "";
279                 spec["vec4ptrInput"]            = "inputPtr";
280         }
281         else
282         {
283                 spec["vec4ptrDeclOutput"]       = "     %_ptr_Output_v4f32 = OpTypePointer Output %v4f32\n";
284                 spec["vec4ptrOutput"]           = "_ptr_Output_v4f32";
285                 spec["vec4ptrDeclInput"]        = "     %_ptr_Input_v4f32 = OpTypePointer Input %v4f32\n";
286                 spec["vec4ptrInput"]            = "_ptr_Input_v4f32";
287         }
288
289         const string                    types                           =
290                 "                     %u32 = OpTypeInt 32 0\n"
291                 "                     %f32 = OpTypeFloat 32\n"
292                 "                   %v4f32 = OpTypeVector %f32 4\n"
293                 "                  %matrix = OpTypeMatrix %v4f32 2\n"
294                 "                 %c_u32_0 = OpConstant %u32 0\n"
295                 "                 %c_u32_8 = OpConstant %u32 8\n"
296                 "              %floatArray = OpTypeArray %f32 %c_u32_8\n";
297
298         string                                  outputDecoration        = "                       OpDecorate %Output Block\n";
299
300         if (type == "matrix")
301         {
302                 spec["extraDecorations"] =
303                         "                       OpMemberDecorate %Output 0 ColMajor\n"
304                         "                       OpMemberDecorate %Output 0 MatrixStride 16\n";
305         }
306
307         // Output selected data type with all components having value one.
308         const StringTemplate    vertexShader            (
309                 string(
310                 "                            OpCapability Shader\n"
311                 "                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
312                 "                            OpMemoryModel Logical GLSL450\n"
313                 "                            OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %outData\n"
314                 "                            OpSource GLSL 430\n"
315                 "                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
316                 "                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
317                 "                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
318                 "                            OpDecorate %gl_PerVertex Block\n"
319                 "                            OpDecorate %position Location 0\n"
320                 "                            OpDecorate %vtxColor Location 1\n"
321                 "                            OpDecorate %color Location 1\n"
322                 "                            OpDecorate %outData Location 2\n"
323                 "                            OpDecorate %floatArray ArrayStride 4\n"
324                 "                    %void = OpTypeVoid\n"
325                 "                       %3 = OpTypeFunction %void\n")
326                 + types + string(
327                 "                   %f32_1 = OpConstant %f32 1\n"
328                 "                 %v4f32_1 = OpConstantComposite %v4f32 %f32_1 %f32_1 %f32_1 %f32_1\n"
329                 "                %matrix_1 = OpConstantComposite %matrix %v4f32_1 %v4f32_1\n"
330                 "            %floatArray_1 = OpConstantComposite %floatArray %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1 %f32_1\n"
331                 "                 %c_u32_1 = OpConstant %u32 1\n"
332                 "          %_arr_f32_u32_1 = OpTypeArray %f32 %c_u32_1\n"
333                 "            %gl_PerVertex = OpTypeStruct %v4f32 %f32 %_arr_f32_u32_1\n"
334                 "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
335                 "                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
336                 "               %outputPtr = OpTypePointer Output %${type}\n"
337                 "                 %outData = OpVariable %outputPtr Output %${type}_1\n"
338                 "        %_ptr_Input_v4f32 = OpTypePointer Input %v4f32\n"
339                 "                %position = OpVariable %_ptr_Input_v4f32 Input\n"
340                 "${vec4ptrDeclOutput}"
341                 "                %vtxColor = OpVariable %${vec4ptrOutput} Output\n"
342                 "                   %color = OpVariable %_ptr_Input_v4f32 Input\n"
343                 "                    %main = OpFunction %void None %3\n"
344                 "                   %entry = OpLabel\n"
345                 "                 %posData = OpLoad %v4f32 %position\n"
346                 "            %posOutputPtr = OpAccessChain %${vec4ptrOutput} %_ %c_u32_0\n"
347                 "                            OpStore %posOutputPtr %posData\n"
348                 "               %colorData = OpLoad %v4f32 %color\n"
349                 "                            OpStore %vtxColor %colorData\n"
350                 "                            OpReturn\n"
351                 "                            OpFunctionEnd\n"));
352
353         // Pass incoming data into buffer
354         const StringTemplate    fragmentShader          (
355                 string(
356                 "                       OpCapability Shader\n"
357                 "                       OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
358                 "                  %1 = OpExtInstImport \"GLSL.std.450\"\n"
359                 "                       OpMemoryModel Logical GLSL450\n"
360                 "                       OpEntryPoint Fragment %main \"main\" %fragColor %vtxColor %inData\n"
361                 "                       OpExecutionMode %main OriginUpperLeft\n"
362                 "                       OpSource GLSL 430\n"
363                 "                       OpDecorate %fragColor Location 0\n"
364                 "                       OpDecorate %vtxColor Location 1\n"
365                 "                       OpMemberDecorate %Output 0 Offset 0\n"
366                 "                       OpDecorate %Output Block\n"
367                 "                       OpDecorate %dataOutput DescriptorSet 0\n"
368                 "                       OpDecorate %dataOutput Binding 0\n"
369                 "                       OpDecorate %inData Location 2\n"
370                 "                       OpDecorate %floatArray ArrayStride 4\n"
371                 "${extraDecorations:opt}"
372                 "               %void = OpTypeVoid\n"
373                 "                  %3 = OpTypeFunction %void\n")
374                 + types + string(
375                 "           %inputPtr = OpTypePointer Input %${type}\n"
376                 "             %inData = OpVariable %inputPtr Input\n"
377                 "  %_ptr_Output_v4f32 = OpTypePointer Output %v4f32\n"
378                 "          %fragColor = OpVariable %_ptr_Output_v4f32 Output\n"
379                 "${vec4ptrDeclInput}"
380                 "           %vtxColor = OpVariable %${vec4ptrInput} Input\n"
381                 "             %Output = OpTypeStruct %${type}\n"
382                 "        %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
383                 "         %dataOutput = OpVariable %_ptr_Output StorageBuffer\n"
384                 "          %outputPtr = OpTypePointer StorageBuffer %${type}\n"
385                 "               %main = OpFunction %void None %3\n"
386                 "              %entry = OpLabel\n"
387                 "          %colorData = OpLoad %v4f32 %vtxColor\n"
388                 "                       OpStore %fragColor %colorData\n"
389                 "          %inputData = OpLoad %${type} %inData\n"
390                 "      %outputDataPtr = OpAccessChain %outputPtr %dataOutput %c_u32_0\n"
391                 "                       OpStore %outputDataPtr %inputData\n"
392                 "                       OpReturn\n"
393                 "                       OpFunctionEnd\n"));
394
395         spec["type"] = type;
396
397         const deUint32 vulkanVersion = dst.usedVulkanVersion;
398         dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
399         dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader.specialize(spec) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
400 }
401
402 void addShaderCodeOutputFloat (vk::SourceCollections& dst, InstanceContext context)
403 {
404         addShaderCodeOutput(dst, context, "f32");
405 }
406
407 void addShaderCodeOutputVector (vk::SourceCollections& dst, InstanceContext context)
408 {
409         addShaderCodeOutput(dst, context, "v4f32");
410 }
411
412 void addShaderCodeOutputMatrix (vk::SourceCollections& dst, InstanceContext context)
413 {
414         addShaderCodeOutput(dst, context, "matrix");
415 }
416
417 void addShaderCodeOutputFloatArray (vk::SourceCollections& dst, InstanceContext context)
418 {
419         addShaderCodeOutput(dst, context, "floatArray");
420 }
421
422 void addShaderCodeOutputStruct (vk::SourceCollections& dst, InstanceContext context)
423 {
424         SpirvVersion            targetSpirvVersion      = context.resources.spirvVersion;
425
426         // Output structure of matrix, vec4, and four floats all having values of 1.
427         const string    vertexShader    =
428                 "                            OpCapability Shader\n"
429                 "                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
430                 "                            OpMemoryModel Logical GLSL450\n"
431                 "                            OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %outData\n"
432                 "                            OpSource GLSL 430\n"
433                 "                            OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
434                 "                            OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
435                 "                            OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
436                 "                            OpDecorate %gl_PerVertex Block\n"
437                 "                            OpDecorate %position Location 0\n"
438                 "                            OpDecorate %vtxColor Location 1\n"
439                 "                            OpDecorate %color Location 1\n"
440                 "                            OpDecorate %outData Location 2\n"
441                 "                            OpMemberDecorate %Data 0 ColMajor\n"
442                 "                            OpMemberDecorate %Data 0 Offset 0\n"
443                 "                            OpMemberDecorate %Data 0 MatrixStride 16\n"
444                 "                            OpMemberDecorate %Data 1 Offset 32\n"
445                 "                            OpMemberDecorate %Data 2 Offset 48\n"
446                 "                            OpMemberDecorate %Data 3 Offset 52\n"
447                 "                            OpMemberDecorate %Data 4 Offset 56\n"
448                 "                            OpMemberDecorate %Data 5 Offset 60\n"
449                 "                            OpMemberDecorate %DataOutput 0 Offset 0\n"
450                 "                    %void = OpTypeVoid\n"
451                 "                %voidFunc = OpTypeFunction %void\n"
452                 "                   %float = OpTypeFloat 32\n"
453                 "                 %v4float = OpTypeVector %float 4\n"
454                 "                    %uint = OpTypeInt 32 0\n"
455                 "                  %uint_1 = OpConstant %uint 1\n"
456                 "       %_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
457                 "            %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1\n"
458                 "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
459                 "                       %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
460                 "                     %int = OpTypeInt 32 1\n"
461                 "                   %int_0 = OpConstant %int 0\n"
462                 "      %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
463                 "                %position = OpVariable %_ptr_Input_v4float Input\n"
464                 "     %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
465                 "                %vtxColor = OpVariable %_ptr_Output_v4float Output\n"
466                 "                   %color = OpVariable %_ptr_Input_v4float Input\n"
467                 "             %mat2v4float = OpTypeMatrix %v4float 2\n"
468                 "                    %Data = OpTypeStruct %mat2v4float %v4float %float %float %float %float\n"
469                 "              %DataOutput = OpTypeStruct %Data\n"
470                 "  %_ptr_Output_DataOutput = OpTypePointer Output %DataOutput\n"
471                 "                 %float_1 = OpConstant %float 1\n"
472                 "                  %vec4_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n"
473                 "                %matrix_1 = OpConstantComposite %mat2v4float %vec4_1 %vec4_1\n"
474                 " %_ptr_Output_mat2v4float = OpTypePointer Output %mat2v4float\n"
475                 "       %_ptr_Output_float = OpTypePointer Output %float\n"
476                 "                  %data_1 = OpConstantComposite %Data %matrix_1 %vec4_1 %float_1 %float_1 %float_1 %float_1\n"
477                 "            %dataOutput_1 = OpConstantComposite %DataOutput %data_1\n"
478                 "                 %outData = OpVariable %_ptr_Output_DataOutput Output %dataOutput_1\n"
479                 "                    %main = OpFunction %void None %voidFunc\n"
480                 "                   %entry = OpLabel\n"
481                 "                 %posData = OpLoad %v4float %position\n"
482                 "                  %posPtr = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
483                 "                            OpStore %posPtr %posData\n"
484                 "               %colorData = OpLoad %v4float %color\n"
485                 "                            OpStore %vtxColor %colorData\n"
486                 "                            OpReturn\n"
487                 "                            OpFunctionEnd\n";
488
489         // Pass the incoming input struct into buffer.
490         const string    fragmentShader  =
491                 "                            OpCapability Shader\n"
492                 "                            OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
493                 "                       %1 = OpExtInstImport \"GLSL.std.450\"\n"
494                 "                            OpMemoryModel Logical GLSL450\n"
495                 "                            OpEntryPoint Fragment %main \"main\" %fragColor %vtxColor %inData\n"
496                 "                            OpExecutionMode %main OriginUpperLeft\n"
497                 "                            OpSource GLSL 430\n"
498                 "                            OpDecorate %fragColor Location 0\n"
499                 "                            OpDecorate %vtxColor Location 1\n"
500                 "                            OpMemberDecorate %Data 0 ColMajor\n"
501                 "                            OpMemberDecorate %Data 0 Offset 0\n"
502                 "                            OpMemberDecorate %Data 0 MatrixStride 16\n"
503                 "                            OpMemberDecorate %Data 1 Offset 32\n"
504                 "                            OpMemberDecorate %Data 2 Offset 48\n"
505                 "                            OpMemberDecorate %Data 3 Offset 52\n"
506                 "                            OpMemberDecorate %Data 4 Offset 56\n"
507                 "                            OpMemberDecorate %Data 5 Offset 60\n"
508                 "                            OpMemberDecorate %Output 0 Offset 0\n"
509                 "                            OpDecorate %Output Block\n"
510                 "                            OpDecorate %dataOutput DescriptorSet 0\n"
511                 "                            OpDecorate %dataOutput Binding 0\n"
512                 "                            OpDecorate %inData Location 2\n"
513                 "                    %void = OpTypeVoid\n"
514                 "                %voidFunc = OpTypeFunction %void\n"
515                 "                   %float = OpTypeFloat 32\n"
516                 "                 %v4float = OpTypeVector %float 4\n"
517                 "     %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
518                 "               %fragColor = OpVariable %_ptr_Output_v4float Output\n"
519                 "      %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
520                 "                %vtxColor = OpVariable %_ptr_Input_v4float Input\n"
521                 "             %mat2v4float = OpTypeMatrix %v4float 2\n"
522                 "                    %Data = OpTypeStruct %mat2v4float %v4float %float %float %float %float\n"
523                 "                  %Output = OpTypeStruct %Data\n"
524                 "             %_ptr_Output = OpTypePointer StorageBuffer %Output\n"
525                 "              %dataOutput = OpVariable %_ptr_Output StorageBuffer\n"
526                 "                     %int = OpTypeInt 32 1\n"
527                 "                   %int_0 = OpConstant %int 0\n"
528                 "               %DataInput = OpTypeStruct %Data\n"
529                 "    %_ptr_Input_DataInput = OpTypePointer Input %DataInput\n"
530                 "                  %inData = OpVariable %_ptr_Input_DataInput Input\n"
531                 "         %_ptr_Input_Data = OpTypePointer Input %Data\n"
532                 "               %_ptr_Data = OpTypePointer StorageBuffer %Data\n"
533                 "                    %main = OpFunction %void None %voidFunc\n"
534                 "                   %entry = OpLabel\n"
535                 "               %colorData = OpLoad %v4float %vtxColor\n"
536                 "                            OpStore %fragColor %colorData\n"
537                 "            %inputDataPtr = OpAccessChain %_ptr_Input_Data %inData %int_0\n"
538                 "               %inputData = OpLoad %Data %inputDataPtr\n"
539                 "           %outputDataPtr = OpAccessChain %_ptr_Data %dataOutput %int_0\n"
540                 "                            OpStore %outputDataPtr %inputData\n"
541                 "                            OpReturn\n"
542                 "                            OpFunctionEnd\n";
543
544         const deUint32 vulkanVersion = dst.usedVulkanVersion;
545         dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
546         dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
547 }
548
549 void addGraphicsVariableInitOutputTest (tcu::TestCaseGroup* group)
550 {
551         tcu::TestContext&               testCtx                         = group->getTestContext();
552         map<string, string>             fragments;
553         RGBA                                    defaultColors[4];
554         tcu::TestCaseGroup*             outputGroup                     = new tcu::TestCaseGroup(testCtx, "output", "Tests OpVariable initialization in output storage class.");
555         SpecConstants                   noSpecConstants;
556         PushConstants                   noPushConstants;
557         GraphicsInterfaces              noInterfaces;
558         vector<string>                  extensions;
559         vector<string>                  features;
560         map<string, string>             noFragments;
561         StageToSpecConstantMap  specConstantMap;
562
563         const ShaderElement             pipelineStages[]        =
564         {
565                 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
566                 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
567         };
568
569         specConstantMap[VK_SHADER_STAGE_VERTEX_BIT]             = noSpecConstants;
570         specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT]   = noSpecConstants;
571
572         getDefaultColors(defaultColors);
573
574         group->addChild(outputGroup);
575
576         features.push_back("fragmentStoresAndAtomics");
577         extensions.push_back("VK_KHR_storage_buffer_storage_class");
578
579         for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
580         {
581                 const deUint32          numComponents   = params[paramIdx].numComponents;
582                 GraphicsResources       resources;
583                 vector<float>           expectedOutput;
584
585                 expectedOutput.reserve(numComponents);
586                 for (deUint32 numIdx = 0; numIdx < numComponents; ++numIdx)
587                         expectedOutput.push_back(1.0f);
588
589                 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
590
591                 {
592                         const InstanceContext& instanceContext = createInstanceContext(pipelineStages,
593                                                                                                                                                    defaultColors,
594                                                                                                                                                    defaultColors,
595                                                                                                                                                    noFragments,
596                                                                                                                                                    specConstantMap,
597                                                                                                                                                    noPushConstants,
598                                                                                                                                                    resources,
599                                                                                                                                                    noInterfaces,
600                                                                                                                                                    extensions,
601                                                                                                                                                    features,
602                                                                                                                                                    VulkanFeatures(),
603                                                                                                                                                    VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
604                                                                                                                                                    QP_TEST_RESULT_FAIL,
605                                                                                                                                                    string());
606
607
608                         addFunctionCaseWithPrograms<InstanceContext>(outputGroup,
609                                                                                                                  params[paramIdx].name.c_str(),
610                                                                                                                  "",
611                                                                                                                  params[paramIdx].shaderInit,
612                                                                                                                  runAndVerifyDefaultPipeline,
613                                                                                                                  instanceContext);
614                 }
615         }
616 }
617
618 } // anonymous
619
620 tcu::TestCaseGroup* createVariableInitComputeGroup (tcu::TestContext& testCtx)
621 {
622         de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "variable_init", "Compute tests for OpVariable initialization."));
623         addComputeVariableInitPrivateTest(group.get());
624
625         return group.release();
626 }
627
628 tcu::TestCaseGroup* createVariableInitGraphicsGroup (tcu::TestContext& testCtx)
629 {
630         de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "variable_init", "Graphics tests for OpVariable initialization."));
631         addGraphicsVariableInitPrivateTest(group.get());
632         addGraphicsVariableInitOutputTest(group.get());
633
634         return group.release();
635 }
636
637 } // SpirVAssembly
638 } // vkt