1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 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 indexing with different bit sizes.
22 *//*--------------------------------------------------------------------*/
24 #include "vktSpvAsmIndexingTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
29 #include "tcuStringTemplate.hpp"
33 namespace SpirVAssembly
45 using tcu::StringTemplate;
52 CHAIN_OP_ACCESS_CHAIN = 0,
53 CHAIN_OP_IN_BOUNDS_ACCESS_CHAIN,
54 CHAIN_OP_PTR_ACCESS_CHAIN,
58 static const int idxSizes[] = { 16, 32, 64 };
59 static const ComputeTestFeatures computeTestFeatures[] = { COMPUTE_TEST_USES_INT16, COMPUTE_TEST_USES_NONE, COMPUTE_TEST_USES_INT64 };
60 static const string chainOpTestNames[] = { "opaccesschain", "opinboundsaccesschain", "opptraccesschain" };
67 void addComputeIndexingTests (tcu::TestCaseGroup* group)
69 tcu::TestContext& testCtx = group->getTestContext();
70 de::Random rnd (deStringHash(group->getName()));
71 const int numItems = 128;
72 const int numStructs = 2;
73 const int numInputFloats = (int)sizeof(InputData) / 4 * numStructs;
74 vector<float> inputData;
75 vector<UVec4> indexSelectorData;
77 inputData.reserve(numInputFloats);
78 for (deUint32 numIdx = 0; numIdx < numInputFloats; ++numIdx)
79 inputData.push_back(rnd.getFloat());
81 indexSelectorData.reserve(numItems);
82 for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
83 indexSelectorData.push_back(UVec4(rnd.getUint32() % 32, rnd.getUint32() % 32, rnd.getUint32() % 4, rnd.getUint32() % 4));
85 for (int chainOpIdx = 0; chainOpIdx < CHAIN_OP_LAST; ++chainOpIdx)
87 for (int idxSizeIdx = 0; idxSizeIdx < DE_LENGTH_OF_ARRAY(idxSizes); ++idxSizeIdx)
89 for (int sign = 0; sign < 2; ++sign)
91 const int idxSize = idxSizes[idxSizeIdx];
92 const string testName = chainOpTestNames[chainOpIdx] + string(sign == 0 ? "_u" : "_s") + de::toString(idxSize);
93 VulkanFeatures vulkanFeatures;
94 map<string, string> specs;
95 vector<float> outputData;
96 ComputeShaderSpec spec;
97 const ComputeTestFeatures features = computeTestFeatures[idxSizeIdx];
100 // Index an input buffer containing 2D array of 4x4 matrices. The indices are read from another
101 // input and converted to the desired bit size and sign.
102 const StringTemplate shaderSource(
103 " OpCapability Shader\n"
105 " ${variablepointercaps:opt}\n"
106 " ${extensions:opt}\n"
107 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
108 " OpMemoryModel Logical GLSL450\n"
109 " OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
110 " OpExecutionMode %main LocalSize 1 1 1\n"
111 " OpSource GLSL 430\n"
112 " OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
113 " OpDecorate %_arr_float_uint_128 ArrayStride 4\n"
114 " OpMemberDecorate %Output 0 Offset 0\n"
115 " OpDecorate %Output BufferBlock\n"
116 " OpDecorate %dataOutput DescriptorSet 0\n"
117 " OpDecorate %dataOutput Binding 2\n"
118 " OpDecorate %_arr_mat4v4float_uint_32 ArrayStride 64\n"
119 " OpDecorate %_arr__arr_mat4v4float_uint_32_uint_32 ArrayStride 2048\n"
120 " OpMemberDecorate %InputStruct 0 ColMajor\n"
121 " OpMemberDecorate %InputStruct 0 Offset 0\n"
122 " OpMemberDecorate %InputStruct 0 MatrixStride 16\n"
123 " OpDecorate %InputStructArr ArrayStride 65536\n"
124 " OpDecorate %Input ${inputdecoration}\n"
125 " OpMemberDecorate %Input 0 Offset 0\n"
126 " OpDecorate %dataInput DescriptorSet 0\n"
127 " OpDecorate %dataInput Binding 0\n"
128 " OpDecorate %_ptr_buffer_InputStruct ArrayStride 65536\n"
129 " OpDecorate %_arr_v4uint_uint_128 ArrayStride 16\n"
130 " OpMemberDecorate %DataSelector 0 Offset 0\n"
131 " OpDecorate %DataSelector BufferBlock\n"
132 " OpDecorate %selector DescriptorSet 0\n"
133 " OpDecorate %selector Binding 1\n"
134 " %void = OpTypeVoid\n"
135 " %3 = OpTypeFunction %void\n"
136 " %u32 = OpTypeInt 32 0\n"
137 " %i32 = OpTypeInt 32 1\n"
139 " %idx_0 = OpConstant ${idx_int} 0\n"
140 " %idx_1 = OpConstant ${idx_int} 1\n"
141 " %idx_2 = OpConstant ${idx_int} 2\n"
142 " %idx_3 = OpConstant ${idx_int} 3\n"
143 " %_ptr_Function_uint32 = OpTypePointer Function %u32\n"
144 " %v3uint32 = OpTypeVector %u32 3\n"
145 " %_ptr_Input_v3uint32 = OpTypePointer Input %v3uint32\n"
146 " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint32 Input\n"
147 " %_ptr_Input_uint32 = OpTypePointer Input %u32\n"
148 " %float = OpTypeFloat 32\n"
149 " %uint_128 = OpConstant %u32 128\n"
150 " %uint_32 = OpConstant %u32 32\n"
151 " %uint_2 = OpConstant %u32 2\n"
152 " %_arr_float_uint_128 = OpTypeArray %float %uint_128\n"
153 " %Output = OpTypeStruct %_arr_float_uint_128\n"
154 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
155 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
156 " %v4float = OpTypeVector %float 4\n"
157 " %mat4v4float = OpTypeMatrix %v4float 4\n"
158 " %_arr_mat4v4float_uint_32 = OpTypeArray %mat4v4float %uint_32\n"
159 " %_arr__arr_mat4v4float_uint_32_uint_32 = OpTypeArray %_arr_mat4v4float_uint_32 %uint_32\n"
160 " %InputStruct = OpTypeStruct %_arr__arr_mat4v4float_uint_32_uint_32\n"
161 " %InputStructArr = OpTypeArray %InputStruct %uint_2\n"
162 " %Input = OpTypeStruct %InputStructArr\n"
163 " %_ptr_buffer_Input = OpTypePointer ${inputstorageclass} %Input\n"
164 " %dataInput = OpVariable %_ptr_buffer_Input ${inputstorageclass}\n"
165 " %_ptr_buffer_InputStruct = OpTypePointer ${inputstorageclass} %InputStruct\n"
166 " %v4uint32 = OpTypeVector %u32 4\n"
167 " %_arr_v4uint_uint_128 = OpTypeArray %v4uint32 %uint_128\n"
168 " %DataSelector = OpTypeStruct %_arr_v4uint_uint_128\n"
169 "%_ptr_Uniform_DataSelector = OpTypePointer Uniform %DataSelector\n"
170 " %selector = OpVariable %_ptr_Uniform_DataSelector Uniform\n"
171 " %_ptr_Uniform_uint32 = OpTypePointer Uniform %u32\n"
172 " %_ptr_Uniform_float = OpTypePointer Uniform %float\n"
173 " ${ptr_buffer_float:opt}\n"
175 " %main = OpFunction %void None %3\n"
177 " %i = OpVariable %_ptr_Function_uint32 Function\n"
178 " %14 = OpAccessChain %_ptr_Input_uint32 %gl_GlobalInvocationID %idx_0\n"
179 " %15 = OpLoad %u32 %14\n"
181 " %uint_i = OpLoad %u32 %i\n"
182 " %39 = OpAccessChain %_ptr_Uniform_uint32 %selector %idx_0 %uint_i %idx_0\n"
183 " %40 = OpLoad %u32 %39\n"
184 " %43 = OpAccessChain %_ptr_Uniform_uint32 %selector %idx_0 %uint_i %idx_1\n"
185 " %44 = OpLoad %u32 %43\n"
186 " %47 = OpAccessChain %_ptr_Uniform_uint32 %selector %idx_0 %uint_i %idx_2\n"
187 " %48 = OpLoad %u32 %47\n"
188 " %51 = OpAccessChain %_ptr_Uniform_uint32 %selector %idx_0 %uint_i %idx_3\n"
189 " %52 = OpLoad %u32 %51\n"
190 " %i0 = ${convert} ${idx_int} %40\n"
191 " %i1 = ${convert} ${idx_int} %44\n"
192 " %i2 = ${convert} ${idx_int} %48\n"
193 " %i3 = ${convert} ${idx_int} %52\n"
194 " %inputFirstElement = OpAccessChain %_ptr_buffer_InputStruct %dataInput %idx_0 %idx_0\n"
195 " %54 = ${accesschain}\n"
196 " %55 = OpLoad %float %54\n"
197 " %56 = OpAccessChain %_ptr_Uniform_float %dataOutput %idx_0 %uint_i\n"
205 case CHAIN_OP_ACCESS_CHAIN:
206 specs["accesschain"] = "OpAccessChain %_ptr_Uniform_float %inputFirstElement %idx_0 %i0 %i1 %i2 %i3\n";
207 specs["inputdecoration"] = "BufferBlock";
208 specs["inputstorageclass"] = "Uniform";
210 case CHAIN_OP_IN_BOUNDS_ACCESS_CHAIN:
211 specs["accesschain"] = "OpInBoundsAccessChain %_ptr_Uniform_float %inputFirstElement %idx_0 %i0 %i1 %i2 %i3\n";
212 specs["inputdecoration"] = "BufferBlock";
213 specs["inputstorageclass"] = "Uniform";
216 DE_ASSERT(chainOpIdx == CHAIN_OP_PTR_ACCESS_CHAIN);
217 specs["accesschain"] = "OpPtrAccessChain %_ptr_StorageBuffer_float %inputFirstElement %idx_1 %idx_0 %i0 %i1 %i2 %i3\n";
218 specs["inputdecoration"] = "Block";
219 specs["inputstorageclass"] = "StorageBuffer";
220 specs["variablepointercaps"] = "OpCapability VariablePointersStorageBuffer";
221 specs["ptr_buffer_float"] = "%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float";
222 specs["extensions"] = "OpExtension \"SPV_KHR_variable_pointers\"\n "
223 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"";
225 vulkanFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
226 spec.extensions.push_back("VK_KHR_variable_pointers");
230 spec.inputs.push_back(BufferSp(new Float32Buffer(inputData)));
231 spec.inputs.push_back(BufferSp(new Buffer<UVec4>(indexSelectorData)));
233 outputData.reserve(numItems);
234 for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
236 // Determine the selected output float for the selected indices.
237 const UVec4 vec = indexSelectorData[numIdx];
238 outputData.push_back(inputData[element * sizeof(InputData) / 4 + vec.x() * (32 * 4 * 4) + vec.y() * 4 * 4 + vec.z() * 4 + vec.w()]);
243 specs["intcaps"] = "OpCapability Int16";
244 specs["convert"] = "OpSConvert";
245 specs["intdecl"] = " %u16 = OpTypeInt 16 0\n"
246 " %i16 = OpTypeInt 16 1\n";
248 else if (idxSize == 64)
250 specs["intcaps"] = "OpCapability Int64";
251 specs["convert"] = "OpSConvert";
252 specs["intdecl"] = " %u64 = OpTypeInt 64 0\n"
253 " %i64 = OpTypeInt 64 1\n";
255 specs["convert"] = "OpCopyObject";
258 specs["idx_uint"] = "%u" + de::toString(idxSize);
259 specs["idx_int"] = (sign ? "%i" : "%u") + de::toString(idxSize);
261 spec.assembly = shaderSource.specialize(specs);
262 spec.numWorkGroups = IVec3(numItems, 1, 1);
263 spec.requestedVulkanFeatures = vulkanFeatures;
264 spec.inputTypes[0] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
265 spec.inputTypes[1] = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
267 spec.outputs.push_back(BufferSp(new Float32Buffer(outputData)));
269 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec, features));
275 void addGraphicsIndexingTests (tcu::TestCaseGroup* group)
277 de::Random rnd (deStringHash(group->getName()));
278 const int numItems = 128;
279 const int numStructs = 2;
280 const int numInputFloats = (int)sizeof(InputData) / 4 * numStructs;
281 RGBA defaultColors[4];
282 vector<float> inputData;
283 vector<UVec4> indexSelectorData;
285 inputData.reserve(numInputFloats);
286 for (deUint32 numIdx = 0; numIdx < numInputFloats; ++numIdx)
287 inputData.push_back(rnd.getFloat());
289 indexSelectorData.reserve(numItems);
290 for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
291 indexSelectorData.push_back(UVec4(rnd.getUint32() % 32, rnd.getUint32() % 32, rnd.getUint32() % 4, rnd.getUint32() % 4));
293 getDefaultColors(defaultColors);
295 for (int chainOpIdx = 0; chainOpIdx < CHAIN_OP_LAST; ++chainOpIdx)
297 for (int idxSizeIdx = 0; idxSizeIdx < DE_LENGTH_OF_ARRAY(idxSizes); ++idxSizeIdx)
299 for (int sign = 0; sign < 2; sign++)
301 const int idxSize = idxSizes[idxSizeIdx];
302 const string testName = chainOpTestNames[chainOpIdx] + string(sign == 0 ? "_u" : "_s") + de::toString(idxSize);
303 VulkanFeatures vulkanFeatures;
304 vector<string> extensions;
305 vector<string> features;
306 vector<deInt32> noSpecConstants;
307 PushConstants noPushConstants;
308 GraphicsInterfaces noInterfaces;
309 map<string, string> specs;
310 map<string, string> fragments;
311 vector<float> outputData;
312 ComputeShaderSpec spec;
314 GraphicsResources resources;
316 const StringTemplate preMain(
318 " %c_i32_128 = OpConstant %i32 128\n"
319 " %uint_0 = OpConstant ${idx_uint} 0\n"
320 " %uint_128 = OpConstant %u32 128\n"
321 " %uint_32 = OpConstant %u32 32\n"
322 " %uint_1 = OpConstant ${idx_uint} 1\n"
323 " %uint_2 = OpConstant ${idx_uint} 2\n"
324 " %uint_3 = OpConstant ${idx_uint} 3\n"
325 " %_arr_float_uint_128 = OpTypeArray %f32 %uint_128\n"
326 " %Output = OpTypeStruct %_arr_float_uint_128\n"
327 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
328 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
329 " %int_0 = OpConstant ${idx_int} 0\n"
330 " %mat4v4float = OpTypeMatrix %v4f32 4\n"
331 " %_arr_mat4v4float_uint_32 = OpTypeArray %mat4v4float %uint_32\n"
332 " %_arr__arr_mat4v4float_uint_32_uint_32 = OpTypeArray %_arr_mat4v4float_uint_32 %uint_32\n"
333 " %InputStruct = OpTypeStruct %_arr__arr_mat4v4float_uint_32_uint_32\n"
334 " %InputStructArr = OpTypeArray %InputStruct %uint_2\n"
335 " %Input = OpTypeStruct %InputStructArr\n"
336 " %_ptr_buffer_Input = OpTypePointer ${inputstorageclass} %Input\n"
337 " %dataInput = OpVariable %_ptr_buffer_Input ${inputstorageclass}\n"
338 " %_ptr_buffer_InputStruct = OpTypePointer ${inputstorageclass} %InputStruct\n"
339 " %_arr_v4uint_uint_128 = OpTypeArray %v4u32 %uint_128\n"
340 " %DataSelector = OpTypeStruct %_arr_v4uint_uint_128\n"
341 "%_ptr_Uniform_DataSelector = OpTypePointer Uniform %DataSelector\n"
342 " %selector = OpVariable %_ptr_Uniform_DataSelector Uniform\n"
343 " %_ptr_Uniform_uint32 = OpTypePointer Uniform %u32\n"
344 " %_ptr_Uniform_float = OpTypePointer Uniform %f32\n"
345 " ${ptr_buffer_float:opt}\n");
348 const StringTemplate decoration(
349 "OpDecorate %_arr_float_uint_128 ArrayStride 4\n"
350 "OpMemberDecorate %Output 0 Offset 0\n"
351 "OpDecorate %Output BufferBlock\n"
352 "OpDecorate %dataOutput DescriptorSet 0\n"
353 "OpDecorate %dataOutput Binding 2\n"
354 "OpDecorate %_arr_mat4v4float_uint_32 ArrayStride 64\n"
355 "OpDecorate %_arr__arr_mat4v4float_uint_32_uint_32 ArrayStride 2048\n"
356 "OpMemberDecorate %InputStruct 0 ColMajor\n"
357 "OpMemberDecorate %InputStruct 0 Offset 0\n"
358 "OpMemberDecorate %InputStruct 0 MatrixStride 16\n"
359 "OpDecorate %InputStructArr ArrayStride 65536\n"
360 "OpDecorate %Input ${inputdecoration}\n"
361 "OpMemberDecorate %Input 0 Offset 0\n"
362 "OpDecorate %dataInput DescriptorSet 0\n"
363 "OpDecorate %dataInput Binding 0\n"
364 "OpDecorate %_ptr_buffer_InputStruct ArrayStride 65536\n"
365 "OpDecorate %_arr_v4uint_uint_128 ArrayStride 16\n"
366 "OpMemberDecorate %DataSelector 0 Offset 0\n"
367 "OpDecorate %DataSelector BufferBlock\n"
368 "OpDecorate %selector DescriptorSet 0\n"
369 "OpDecorate %selector Binding 1\n");
371 // Index an input buffer containing 2D array of 4x4 matrices. The indices are read from another
372 // input and converted to the desired bit size and sign.
373 const StringTemplate testFun(
374 " %test_code = OpFunction %v4f32 None %v4f32_function\n"
375 " %param = OpFunctionParameter %v4f32\n"
377 " %entry = OpLabel\n"
378 " %i = OpVariable %fp_i32 Function\n"
379 " OpStore %i %c_i32_0\n"
383 " %15 = OpLoad %i32 %i\n"
384 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
385 " OpLoopMerge %merge %inc None\n"
386 " OpBranchConditional %lt %write %merge\n"
388 " %write = OpLabel\n"
389 " %int_i = OpLoad %i32 %i\n"
390 " %39 = OpAccessChain %_ptr_Uniform_uint32 %selector %int_0 %int_i %uint_0\n"
391 " %40 = OpLoad %u32 %39\n"
392 " %43 = OpAccessChain %_ptr_Uniform_uint32 %selector %int_0 %int_i %uint_1\n"
393 " %44 = OpLoad %u32 %43\n"
394 " %47 = OpAccessChain %_ptr_Uniform_uint32 %selector %int_0 %int_i %uint_2\n"
395 " %48 = OpLoad %u32 %47\n"
396 " %51 = OpAccessChain %_ptr_Uniform_uint32 %selector %int_0 %int_i %uint_3\n"
397 " %52 = OpLoad %u32 %51\n"
398 " %i0 = ${convert} ${idx_uint} %40\n"
399 " %i1 = ${convert} ${idx_uint} %44\n"
400 " %i2 = ${convert} ${idx_uint} %48\n"
401 " %i3 = ${convert} ${idx_uint} %52\n"
402 "%inputFirstElement = OpAccessChain %_ptr_buffer_InputStruct %dataInput %uint_0 %uint_0\n"
403 " %54 = ${accesschain}\n"
404 " %55 = OpLoad %f32 %54\n"
405 " %56 = OpAccessChain %_ptr_Uniform_float %dataOutput %int_0 %int_i\n"
410 " %67 = OpLoad %i32 %i\n"
411 " %69 = OpIAdd %i32 %67 %c_i32_1\n"
415 " %merge = OpLabel\n"
416 " OpReturnValue %param\n"
420 resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(inputData))));
421 resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Buffer<UVec4>(indexSelectorData))));
425 fragments["capability"] = "OpCapability Int16\n";
426 features.push_back("shaderInt16");
427 specs["convert"] = "OpUConvert";
428 specs["intdecl"] = " %u16 = OpTypeInt 16 0\n"
429 " %i16 = OpTypeInt 16 1\n";
431 else if (idxSize == 64)
433 fragments["capability"] = "OpCapability Int64\n";
434 features.push_back("shaderInt64");
435 specs["convert"] = "OpUConvert";
436 specs["intdecl"] = " %u64 = OpTypeInt 64 0\n"
437 " %i64 = OpTypeInt 64 1\n";
439 specs["convert"] = "OpCopyObject";
442 specs["idx_uint"] = "%u" + de::toString(idxSize);
443 specs["idx_int"] = (sign ? "%i" : "%u") + de::toString(idxSize);
447 case CHAIN_OP_ACCESS_CHAIN:
448 specs["accesschain"] = "OpAccessChain %_ptr_Uniform_float %inputFirstElement %int_0 %i0 %i1 %i2 %i3\n";
449 specs["inputdecoration"] = "BufferBlock";
450 specs["inputstorageclass"] = "Uniform";
452 case CHAIN_OP_IN_BOUNDS_ACCESS_CHAIN:
453 specs["accesschain"] = "OpInBoundsAccessChain %_ptr_Uniform_float %inputFirstElement %int_0 %i0 %i1 %i2 %i3\n";
454 specs["inputdecoration"] = "BufferBlock";
455 specs["inputstorageclass"] = "Uniform";
458 DE_ASSERT(chainOpIdx == CHAIN_OP_PTR_ACCESS_CHAIN);
459 specs["accesschain"] = "OpPtrAccessChain %_ptr_StorageBuffer_float %inputFirstElement %uint_1 %int_0 %i0 %i1 %i2 %i3\n";
460 specs["inputdecoration"] = "Block";
461 specs["inputstorageclass"] = "StorageBuffer";
462 specs["ptr_buffer_float"] = "%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %f32";
463 fragments["capability"] += "OpCapability VariablePointersStorageBuffer";
464 fragments["extension"] = "OpExtension \"SPV_KHR_variable_pointers\"\nOpExtension \"SPV_KHR_storage_buffer_storage_class\"";
465 extensions.push_back ("VK_KHR_variable_pointers");
466 vulkanFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
471 outputData.reserve(numItems);
472 for (deUint32 numIdx = 0; numIdx < numItems; ++numIdx)
474 // Determine the selected output float for the selected indices.
475 const UVec4 vec = indexSelectorData[numIdx];
476 outputData.push_back(inputData[element * sizeof(InputData) / 4 + vec.x() * (32 * 4 * 4) + vec.y() * 4 * 4 + vec.z() * 4 + vec.w()]);
479 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(outputData))));
481 fragments["pre_main"] = preMain.specialize(specs);
482 fragments["decoration"] = decoration.specialize(specs);
483 fragments["testfun"] = testFun.specialize(specs);
485 createTestsForAllStages(
486 testName.c_str(), defaultColors, defaultColors, fragments, noSpecConstants,
487 noPushConstants, resources, noInterfaces, extensions, features, vulkanFeatures, group);
495 tcu::TestCaseGroup* createIndexingComputeGroup (tcu::TestContext& testCtx)
497 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "indexing", "Compute tests for data indexing."));
498 addComputeIndexingTests(group.get());
500 return group.release();
503 tcu::TestCaseGroup* createIndexingGraphicsGroup (tcu::TestContext& testCtx)
505 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "indexing", "Graphics tests for data indexing."));
506 addGraphicsIndexingTests(group.get());
508 return group.release();