1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2018 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief SPIR-V Assembly Tests for OpVariable initializer
22 *//*--------------------------------------------------------------------*/
24 #include "vktSpvAsmVariableInitTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
28 #include "tcuStringTemplate.hpp"
32 namespace SpirVAssembly
42 using tcu::StringTemplate;
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);
58 FunctionPrograms1<InstanceContext>::Function shaderInit;
61 const TestParams params[] =
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 }
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";
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}";
104 void addComputeVariableInitPrivateTest (tcu::TestCaseGroup* group)
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;
112 const StringTemplate shaderSourceTemplate (
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")
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"
147 " OpFunctionEnd\n"));
149 group->addChild(privateGroup);
151 expectedOutput.reserve(numFloats);
152 for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
153 expectedOutput.push_back(1.0f);
155 spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
157 for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
159 map<string, string> shaderSpec;
160 const int numComponents = params[paramIdx].numComponents;
161 const int numElements = numFloats / numComponents;
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";
168 if (params[paramIdx].type == "matrix")
170 shaderSpec["extraDecorations"] =
171 " OpMemberDecorate %Output 0 ColMajor\n"
172 " OpMemberDecorate %Output 0 MatrixStride 16\n";
175 spec.assembly = shaderSourceTemplate.specialize(shaderSpec);
176 spec.numWorkGroups = IVec3(numElements, 1, 1);
177 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
179 privateGroup->addChild(new SpvAsmComputeShaderCase(testCtx, params[paramIdx].name.c_str(), "", spec));
183 void addGraphicsVariableInitPrivateTest (tcu::TestCaseGroup* group)
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;
194 StringTemplate preMain (
196 " %dataPtr = OpTypePointer Private %${type}\n"
197 " %f1 = OpVariable %dataPtr Private %${constData}\n"
200 StringTemplate decoration (decorations);
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"
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"
221 " %37 = OpLoad %i32 %i\n"
222 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
225 " %merge = OpLabel\n"
226 " OpReturnValue %param\n"
230 group->addChild(privateGroup);
232 getDefaultColors(defaultColors);
234 expectedOutput.reserve(numFloats);
235 for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
236 expectedOutput.push_back(1.0f);
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");
241 for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
243 map<string, string> shaderSpec;
244 const int numComponents = params[paramIdx].numComponents;
245 const int numElements = numFloats / numComponents;
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";
252 if (params[paramIdx].type == "matrix")
254 shaderSpec["extraDecorations"] =
255 " OpMemberDecorate %Output 0 ColMajor\n"
256 " OpMemberDecorate %Output 0 MatrixStride 16\n";
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);
264 createTestsForAllStages(params[paramIdx].name, defaultColors, defaultColors, fragments, resources, extensions, privateGroup);
268 void addShaderCodeOutput(vk::SourceCollections& dst, InstanceContext& context, string type)
270 SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
271 map<string, string> spec;
273 // Needed for preventing duplicate pointer declarations.
276 spec["vec4ptrDeclOutput"] = "";
277 spec["vec4ptrOutput"] = "outputPtr";
278 spec["vec4ptrDeclInput"] = "";
279 spec["vec4ptrInput"] = "inputPtr";
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";
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";
298 string outputDecoration = " OpDecorate %Output Block\n";
300 if (type == "matrix")
302 spec["extraDecorations"] =
303 " OpMemberDecorate %Output 0 ColMajor\n"
304 " OpMemberDecorate %Output 0 MatrixStride 16\n";
307 // Output selected data type with all components having value one.
308 const StringTemplate vertexShader (
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")
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"
351 " OpFunctionEnd\n"));
353 // Pass incoming data into buffer
354 const StringTemplate fragmentShader (
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")
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"
393 " OpFunctionEnd\n"));
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);
402 void addShaderCodeOutputFloat (vk::SourceCollections& dst, InstanceContext context)
404 addShaderCodeOutput(dst, context, "f32");
407 void addShaderCodeOutputVector (vk::SourceCollections& dst, InstanceContext context)
409 addShaderCodeOutput(dst, context, "v4f32");
412 void addShaderCodeOutputMatrix (vk::SourceCollections& dst, InstanceContext context)
414 addShaderCodeOutput(dst, context, "matrix");
417 void addShaderCodeOutputFloatArray (vk::SourceCollections& dst, InstanceContext context)
419 addShaderCodeOutput(dst, context, "floatArray");
422 void addShaderCodeOutputStruct (vk::SourceCollections& dst, InstanceContext context)
424 SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
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"
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"
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);
549 void addGraphicsVariableInitOutputTest (tcu::TestCaseGroup* group)
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;
563 const ShaderElement pipelineStages[] =
565 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
566 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
569 specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = noSpecConstants;
570 specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = noSpecConstants;
572 getDefaultColors(defaultColors);
574 group->addChild(outputGroup);
576 features.push_back("fragmentStoresAndAtomics");
577 extensions.push_back("VK_KHR_storage_buffer_storage_class");
579 for (int paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
581 const deUint32 numComponents = params[paramIdx].numComponents;
582 GraphicsResources resources;
583 vector<float> expectedOutput;
585 expectedOutput.reserve(numComponents);
586 for (deUint32 numIdx = 0; numIdx < numComponents; ++numIdx)
587 expectedOutput.push_back(1.0f);
589 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
592 const InstanceContext& instanceContext = createInstanceContext(pipelineStages,
603 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
608 addFunctionCaseWithPrograms<InstanceContext>(outputGroup,
609 params[paramIdx].name.c_str(),
611 params[paramIdx].shaderInit,
612 runAndVerifyDefaultPipeline,
620 tcu::TestCaseGroup* createVariableInitComputeGroup (tcu::TestContext& testCtx)
622 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "variable_init", "Compute tests for OpVariable initialization."));
623 addComputeVariableInitPrivateTest(group.get());
625 return group.release();
628 tcu::TestCaseGroup* createVariableInitGraphicsGroup (tcu::TestContext& testCtx)
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());
634 return group.release();