1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Shader indexing (arrays, vector, matrices) tests.
34 *//*--------------------------------------------------------------------*/
36 #include "vktShaderRenderIndexingTests.hpp"
37 #include "vktShaderRender.hpp"
38 #include "gluShaderUtil.hpp"
39 #include "tcuStringTemplate.hpp"
57 INDEXACCESS_STATIC = 0,
59 INDEXACCESS_STATIC_LOOP,
60 INDEXACCESS_DYNAMIC_LOOP,
65 static const char* getIndexAccessTypeName (IndexAccessType accessType)
67 static const char* s_names[INDEXACCESS_LAST] =
75 DE_ASSERT(deInBounds32((int)accessType, 0, INDEXACCESS_LAST));
76 return s_names[(int)accessType];
85 SUBSCRIPT_STATIC_LOOP,
86 SUBSCRIPT_DYNAMIC_LOOP,
91 static const char* getVectorAccessTypeName (VectorAccessType accessType)
93 static const char* s_names[VECTORACCESS_LAST] =
99 "static_loop_subscript",
100 "dynamic_loop_subscript"
103 DE_ASSERT(deInBounds32((int)accessType, 0, VECTORACCESS_LAST));
104 return s_names[(int)accessType];
107 void evalArrayCoordsFloat (ShaderEvalContext& c) { c.color.x() = 1.875f * c.coords.x(); }
108 void evalArrayCoordsVec2 (ShaderEvalContext& c) { c.color.xy() = 1.875f * c.coords.swizzle(0,1); }
109 void evalArrayCoordsVec3 (ShaderEvalContext& c) { c.color.xyz() = 1.875f * c.coords.swizzle(0,1,2); }
110 void evalArrayCoordsVec4 (ShaderEvalContext& c) { c.color = 1.875f * c.coords; }
112 static ShaderEvalFunc getArrayCoordsEvalFunc (DataType dataType)
114 if (dataType == TYPE_FLOAT) return evalArrayCoordsFloat;
115 else if (dataType == TYPE_FLOAT_VEC2) return evalArrayCoordsVec2;
116 else if (dataType == TYPE_FLOAT_VEC3) return evalArrayCoordsVec3;
117 else if (dataType == TYPE_FLOAT_VEC4) return evalArrayCoordsVec4;
119 DE_FATAL("Invalid data type.");
123 void evalArrayUniformFloat (ShaderEvalContext& c) { c.color.x() = 1.875f * c.constCoords.x(); }
124 void evalArrayUniformVec2 (ShaderEvalContext& c) { c.color.xy() = 1.875f * c.constCoords.swizzle(0,1); }
125 void evalArrayUniformVec3 (ShaderEvalContext& c) { c.color.xyz() = 1.875f * c.constCoords.swizzle(0,1,2); }
126 void evalArrayUniformVec4 (ShaderEvalContext& c) { c.color = 1.875f * c.constCoords; }
128 static ShaderEvalFunc getArrayUniformEvalFunc (DataType dataType)
130 if (dataType == TYPE_FLOAT) return evalArrayUniformFloat;
131 else if (dataType == TYPE_FLOAT_VEC2) return evalArrayUniformVec2;
132 else if (dataType == TYPE_FLOAT_VEC3) return evalArrayUniformVec3;
133 else if (dataType == TYPE_FLOAT_VEC4) return evalArrayUniformVec4;
135 DE_FATAL("Invalid data type.");
139 static const char* getIntUniformName (int number)
143 case 0: return "ui_zero";
144 case 1: return "ui_one";
145 case 2: return "ui_two";
146 case 3: return "ui_three";
147 case 4: return "ui_four";
148 case 5: return "ui_five";
149 case 6: return "ui_six";
150 case 7: return "ui_seven";
151 case 8: return "ui_eight";
152 case 101: return "ui_oneHundredOne";
159 class IndexingTestUniformSetup : public UniformSetup
162 IndexingTestUniformSetup (const DataType varType, bool usesArray)
164 , m_usesArray(usesArray)
166 virtual ~IndexingTestUniformSetup (void)
169 virtual void setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;
172 const DataType m_varType;
173 const bool m_usesArray;
176 void IndexingTestUniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
178 instance.useUniform(0u, UI_ZERO);
179 instance.useUniform(1u, UI_ONE);
180 instance.useUniform(2u, UI_TWO);
181 instance.useUniform(3u, UI_THREE);
182 instance.useUniform(4u, UI_FOUR);
187 if (m_varType == TYPE_FLOAT)
189 arr[0] = Vec4(constCoords.x());
190 arr[1] = Vec4(constCoords.x() * 0.5f);
191 arr[2] = Vec4(constCoords.x() * 0.25f);
192 arr[3] = Vec4(constCoords.x() * 0.125f);
194 else if (m_varType == TYPE_FLOAT_VEC2)
196 arr[0] = constCoords.swizzle(0, 1).toWidth<4>();
197 arr[1] = (constCoords.swizzle(0, 1) * 0.5f).toWidth<4>();
198 arr[2] = (constCoords.swizzle(0, 1) * 0.25f).toWidth<4>();
199 arr[3] = (constCoords.swizzle(0, 1) * 0.125f).toWidth<4>();
201 else if (m_varType == TYPE_FLOAT_VEC3)
203 arr[0] = constCoords.swizzle(0, 1, 2).toWidth<4>();
204 arr[1] = (constCoords.swizzle(0, 1, 2) * 0.5f).toWidth<4>();
205 arr[2] = (constCoords.swizzle(0, 1, 2) * 0.25f).toWidth<4>();
206 arr[3] = (constCoords.swizzle(0, 1, 2) * 0.125f).toWidth<4>();
208 else if (m_varType == TYPE_FLOAT_VEC4)
210 arr[0] = constCoords;
211 arr[1] = constCoords * 0.5f;
212 arr[2] = constCoords * 0.25f;
213 arr[3] = constCoords * 0.125f;
216 throw tcu::TestError("invalid data type for u_arr");
218 instance.addUniform(5u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(Vec4) * 4, arr[0].getPtr());
222 // ShaderIndexingCase
224 class ShaderIndexingCase : public ShaderRenderCase
227 ShaderIndexingCase (tcu::TestContext& testCtx,
228 const std::string& name,
229 const std::string& description,
231 const ShaderEvalFunc evalFunc,
232 const std::string& vertShaderSource,
233 const std::string& fragShaderSource,
234 const DataType varType,
235 const bool usesArray);
236 virtual ~ShaderIndexingCase (void);
239 ShaderIndexingCase (const ShaderIndexingCase&); // not allowed!
240 ShaderIndexingCase& operator= (const ShaderIndexingCase&); // not allowed!
243 ShaderIndexingCase::ShaderIndexingCase (tcu::TestContext& testCtx,
244 const std::string& name,
245 const std::string& description,
246 const bool isVertexCase,
247 const ShaderEvalFunc evalFunc,
248 const std::string& vertShaderSource,
249 const std::string& fragShaderSource,
250 const DataType varType,
251 const bool usesArray)
252 : ShaderRenderCase(testCtx, name, description, isVertexCase, evalFunc, new IndexingTestUniformSetup(varType, usesArray), DE_NULL)
254 m_vertShaderSource = vertShaderSource;
255 m_fragShaderSource = fragShaderSource;
258 ShaderIndexingCase::~ShaderIndexingCase (void)
262 // Test case builders.
264 static de::MovePtr<ShaderIndexingCase> createVaryingArrayCase (tcu::TestContext& context,
265 const std::string& caseName,
266 const std::string& description,
268 IndexAccessType vertAccess,
269 IndexAccessType fragAccess)
271 std::ostringstream vtx;
272 vtx << "#version 310 es\n";
273 vtx << "#extension GL_ARB_separate_shader_objects : enable\n";
274 vtx << "#extension GL_ARB_shading_language_420pack : enable\n";
275 vtx << "layout(location = 0) in highp vec4 a_position;\n";
276 vtx << "layout(location = 1) in highp vec4 a_coords;\n";
277 if (vertAccess == INDEXACCESS_DYNAMIC)
279 vtx << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
280 vtx << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
281 vtx << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
282 vtx << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
284 else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
285 vtx << "layout(std140, binding = 4) uniform something { mediump int ui_four; };\n";
286 vtx << "layout(location = 0) out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
288 vtx << "void main()\n";
290 vtx << " gl_Position = a_position;\n";
291 if (vertAccess == INDEXACCESS_STATIC)
293 vtx << " var[0] = ${VAR_TYPE}(a_coords);\n";
294 vtx << " var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n";
295 vtx << " var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n";
296 vtx << " var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n";
298 else if (vertAccess == INDEXACCESS_DYNAMIC)
300 vtx << " var[ui_zero] = ${VAR_TYPE}(a_coords);\n";
301 vtx << " var[ui_one] = ${VAR_TYPE}(a_coords) * 0.5;\n";
302 vtx << " var[ui_two] = ${VAR_TYPE}(a_coords) * 0.25;\n";
303 vtx << " var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n";
305 else if (vertAccess == INDEXACCESS_STATIC_LOOP)
307 vtx << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
308 vtx << " for (int i = 0; i < 4; i++)\n";
310 vtx << " var[i] = ${VAR_TYPE}(coords);\n";
311 vtx << " coords = coords * 0.5;\n";
316 DE_ASSERT(vertAccess == INDEXACCESS_DYNAMIC_LOOP);
317 vtx << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
318 vtx << " for (int i = 0; i < ui_four; i++)\n";
320 vtx << " var[i] = ${VAR_TYPE}(coords);\n";
321 vtx << " coords = coords * 0.5;\n";
326 std::ostringstream frag;
327 frag << "#version 310 es\n";
328 frag << "#extension GL_ARB_separate_shader_objects : enable\n";
329 frag << "#extension GL_ARB_shading_language_420pack : enable\n";
330 frag << "precision mediump int;\n";
331 frag << "layout(location = 0) out mediump vec4 o_color;\n";
332 if (fragAccess == INDEXACCESS_DYNAMIC)
334 frag << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
335 frag << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
336 frag << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
337 frag << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
339 else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
340 frag << "layout(std140, binding = 4) uniform something4 { mediump int ui_four; };\n";
341 frag << "layout(location = 0) in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
343 frag << "void main()\n";
345 frag << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
346 if (fragAccess == INDEXACCESS_STATIC)
348 frag << " res += var[0];\n";
349 frag << " res += var[1];\n";
350 frag << " res += var[2];\n";
351 frag << " res += var[3];\n";
353 else if (fragAccess == INDEXACCESS_DYNAMIC)
355 frag << " res += var[ui_zero];\n";
356 frag << " res += var[ui_one];\n";
357 frag << " res += var[ui_two];\n";
358 frag << " res += var[ui_three];\n";
360 else if (fragAccess == INDEXACCESS_STATIC_LOOP)
362 frag << " for (int i = 0; i < 4; i++)\n";
363 frag << " res += var[i];\n";
367 DE_ASSERT(fragAccess == INDEXACCESS_DYNAMIC_LOOP);
368 frag << " for (int i = 0; i < ui_four; i++)\n";
369 frag << " res += var[i];\n";
371 frag << " o_color = vec4(res${PADDING});\n";
374 // Fill in shader templates.
375 map<string, string> params;
376 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
377 params.insert(pair<string, string>("ARRAY_LEN", "4"));
378 params.insert(pair<string, string>("PRECISION", "mediump"));
380 if (varType == TYPE_FLOAT)
381 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
382 else if (varType == TYPE_FLOAT_VEC2)
383 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
384 else if (varType == TYPE_FLOAT_VEC3)
385 params.insert(pair<string, string>("PADDING", ", 1.0"));
387 params.insert(pair<string, string>("PADDING", ""));
389 StringTemplate vertTemplate(vtx.str());
390 StringTemplate fragTemplate(frag.str());
391 string vertexShaderSource = vertTemplate.specialize(params);
392 string fragmentShaderSource = fragTemplate.specialize(params);
394 ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
395 return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, true, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
398 static de::MovePtr<ShaderIndexingCase> createUniformArrayCase (tcu::TestContext& context,
399 const std::string& caseName,
400 const std::string& description,
403 IndexAccessType readAccess)
405 std::ostringstream vtx;
406 std::ostringstream frag;
407 std::ostringstream& op = isVertexCase ? vtx : frag;
409 vtx << "#version 310 es\n";
410 vtx << "#extension GL_ARB_separate_shader_objects : enable\n";
411 vtx << "#extension GL_ARB_shading_language_420pack : enable\n";
412 frag << "#version 310 es\n";
413 frag << "#extension GL_ARB_separate_shader_objects : enable\n";
414 frag << "#extension GL_ARB_shading_language_420pack : enable\n";
416 vtx << "layout(location = 0) in highp vec4 a_position;\n";
417 vtx << "layout(location = 1) in highp vec4 a_coords;\n";
418 frag << "layout(location = 0) out mediump vec4 o_color;\n";
422 vtx << "layout(location = 0) out mediump vec4 v_color;\n";
423 frag << "layout(location = 0) in mediump vec4 v_color;\n";
427 vtx << "layout(location = 0) out mediump vec4 v_coords;\n";
428 frag << "layout(location = 0) in mediump vec4 v_coords;\n";
431 if (readAccess == INDEXACCESS_DYNAMIC)
433 op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
434 op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
435 op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
436 op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
438 else if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
439 op << "layout(std140, binding = 4) uniform something4 { mediump int ui_four; };\n";
441 op << "layout(std140, binding = 5) uniform something5 { ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}]; };\n";
444 vtx << "void main()\n";
446 vtx << " gl_Position = a_position;\n";
449 frag << "void main()\n";
453 op << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
454 if (readAccess == INDEXACCESS_STATIC)
456 op << " res += u_arr[0];\n";
457 op << " res += u_arr[1];\n";
458 op << " res += u_arr[2];\n";
459 op << " res += u_arr[3];\n";
461 else if (readAccess == INDEXACCESS_DYNAMIC)
463 op << " res += u_arr[ui_zero];\n";
464 op << " res += u_arr[ui_one];\n";
465 op << " res += u_arr[ui_two];\n";
466 op << " res += u_arr[ui_three];\n";
468 else if (readAccess == INDEXACCESS_STATIC_LOOP)
470 op << " for (int i = 0; i < 4; i++)\n";
471 op << " res += u_arr[i];\n";
475 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
476 op << " for (int i = 0; i < ui_four; i++)\n";
477 op << " res += u_arr[i];\n";
482 vtx << " v_color = vec4(res${PADDING});\n";
483 frag << " o_color = v_color;\n";
487 vtx << " v_coords = a_coords;\n";
488 frag << " o_color = vec4(res${PADDING});\n";
494 // Fill in shader templates.
495 map<string, string> params;
496 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
497 params.insert(pair<string, string>("ARRAY_LEN", "4"));
498 params.insert(pair<string, string>("PRECISION", "mediump"));
500 if (varType == TYPE_FLOAT)
501 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
502 else if (varType == TYPE_FLOAT_VEC2)
503 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
504 else if (varType == TYPE_FLOAT_VEC3)
505 params.insert(pair<string, string>("PADDING", ", 1.0"));
507 params.insert(pair<string, string>("PADDING", ""));
509 StringTemplate vertTemplate(vtx.str());
510 StringTemplate fragTemplate(frag.str());
511 string vertexShaderSource = vertTemplate.specialize(params);
512 string fragmentShaderSource = fragTemplate.specialize(params);
514 ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType);
515 return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, true));
518 static de::MovePtr<ShaderIndexingCase> createTmpArrayCase (tcu::TestContext& context,
519 const std::string& caseName,
520 const std::string& description,
523 IndexAccessType writeAccess,
524 IndexAccessType readAccess)
526 std::ostringstream vtx;
527 std::ostringstream frag;
528 std::ostringstream& op = isVertexCase ? vtx : frag;
530 vtx << "#version 310 es\n";
531 vtx << "#extension GL_ARB_separate_shader_objects : enable\n";
532 vtx << "#extension GL_ARB_shading_language_420pack : enable\n";
533 frag << "#version 310 es\n";
534 frag << "#extension GL_ARB_separate_shader_objects : enable\n";
535 frag << "#extension GL_ARB_shading_language_420pack : enable\n";
537 vtx << "layout(location = 0) in highp vec4 a_position;\n";
538 vtx << "layout(location = 1) in highp vec4 a_coords;\n";
539 frag << "layout(location = 0) out mediump vec4 o_color;\n";
543 vtx << "layout(location = 0) out mediump vec4 v_color;\n";
544 frag << "layout(location = 0) in mediump vec4 v_color;\n";
548 vtx << "layout(location = 0) out mediump vec4 v_coords;\n";
549 frag << "layout(location = 0) in mediump vec4 v_coords;\n";
552 if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
554 op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
555 op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
556 op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
557 op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
560 if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
561 op << "layout(std140, binding = 4) uniform something4 { mediump int ui_four; };\n";
564 vtx << "void main()\n";
566 vtx << " gl_Position = a_position;\n";
569 frag << "void main()\n";
574 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
576 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
578 op << " ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n";
579 if (writeAccess == INDEXACCESS_STATIC)
581 op << " arr[0] = ${VAR_TYPE}(coords);\n";
582 op << " arr[1] = ${VAR_TYPE}(coords) * 0.5;\n";
583 op << " arr[2] = ${VAR_TYPE}(coords) * 0.25;\n";
584 op << " arr[3] = ${VAR_TYPE}(coords) * 0.125;\n";
586 else if (writeAccess == INDEXACCESS_DYNAMIC)
588 op << " arr[ui_zero] = ${VAR_TYPE}(coords);\n";
589 op << " arr[ui_one] = ${VAR_TYPE}(coords) * 0.5;\n";
590 op << " arr[ui_two] = ${VAR_TYPE}(coords) * 0.25;\n";
591 op << " arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n";
593 else if (writeAccess == INDEXACCESS_STATIC_LOOP)
595 op << " for (int i = 0; i < 4; i++)\n";
597 op << " arr[i] = ${VAR_TYPE}(coords);\n";
598 op << " coords = coords * 0.5;\n";
603 DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
604 op << " for (int i = 0; i < ui_four; i++)\n";
606 op << " arr[i] = ${VAR_TYPE}(coords);\n";
607 op << " coords = coords * 0.5;\n";
612 op << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
613 if (readAccess == INDEXACCESS_STATIC)
615 op << " res += arr[0];\n";
616 op << " res += arr[1];\n";
617 op << " res += arr[2];\n";
618 op << " res += arr[3];\n";
620 else if (readAccess == INDEXACCESS_DYNAMIC)
622 op << " res += arr[ui_zero];\n";
623 op << " res += arr[ui_one];\n";
624 op << " res += arr[ui_two];\n";
625 op << " res += arr[ui_three];\n";
627 else if (readAccess == INDEXACCESS_STATIC_LOOP)
629 op << " for (int i = 0; i < 4; i++)\n";
630 op << " res += arr[i];\n";
634 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
635 op << " for (int i = 0; i < ui_four; i++)\n";
636 op << " res += arr[i];\n";
641 vtx << " v_color = vec4(res${PADDING});\n";
642 frag << " o_color = v_color;\n";
646 vtx << " v_coords = a_coords;\n";
647 frag << " o_color = vec4(res${PADDING});\n";
653 // Fill in shader templates.
654 map<string, string> params;
655 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
656 params.insert(pair<string, string>("ARRAY_LEN", "4"));
657 params.insert(pair<string, string>("PRECISION", "mediump"));
659 if (varType == TYPE_FLOAT)
660 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
661 else if (varType == TYPE_FLOAT_VEC2)
662 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
663 else if (varType == TYPE_FLOAT_VEC3)
664 params.insert(pair<string, string>("PADDING", ", 1.0"));
666 params.insert(pair<string, string>("PADDING", ""));
668 StringTemplate vertTemplate(vtx.str());
669 StringTemplate fragTemplate(frag.str());
670 string vertexShaderSource = vertTemplate.specialize(params);
671 string fragmentShaderSource = fragTemplate.specialize(params);
673 ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
674 return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
679 void evalSubscriptVec2 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y()); }
680 void evalSubscriptVec3 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y() + 0.25f*c.coords.z()); }
681 void evalSubscriptVec4 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y() + 0.25f*c.coords.z() + 0.125f*c.coords.w()); }
683 static ShaderEvalFunc getVectorSubscriptEvalFunc (DataType dataType)
685 if (dataType == TYPE_FLOAT_VEC2) return evalSubscriptVec2;
686 else if (dataType == TYPE_FLOAT_VEC3) return evalSubscriptVec3;
687 else if (dataType == TYPE_FLOAT_VEC4) return evalSubscriptVec4;
689 DE_FATAL("Invalid data type.");
693 static de::MovePtr<ShaderIndexingCase> createVectorSubscriptCase (tcu::TestContext& context,
694 const std::string& caseName,
695 const std::string& description,
698 VectorAccessType writeAccess,
699 VectorAccessType readAccess)
701 std::ostringstream vtx;
702 std::ostringstream frag;
703 std::ostringstream& op = isVertexCase ? vtx : frag;
705 int vecLen = getDataTypeScalarSize(varType);
706 const char* vecLenName = getIntUniformName(vecLen);
708 vtx << "#version 310 es\n";
709 vtx << "#extension GL_ARB_separate_shader_objects : enable\n";
710 vtx << "#extension GL_ARB_shading_language_420pack : enable\n";
711 frag << "#version 310 es\n";
712 frag << "#extension GL_ARB_separate_shader_objects : enable\n";
713 frag << "#extension GL_ARB_shading_language_420pack : enable\n";
715 vtx << "layout(location = 0) in highp vec4 a_position;\n";
716 vtx << "layout(location = 1) in highp vec4 a_coords;\n";
717 frag << "layout(location = 0) out mediump vec4 o_color;\n";
721 vtx << "layout(location = 0) out mediump vec3 v_color;\n";
722 frag << "layout(location = 0) in mediump vec3 v_color;\n";
726 vtx << "layout(location = 0) out mediump vec4 v_coords;\n";
727 frag << "layout(location = 0) in mediump vec4 v_coords;\n";
730 if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC)
732 op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
733 if (vecLen >= 2) op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
734 if (vecLen >= 3) op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
735 if (vecLen >= 4) op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
738 if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP)
739 op << "layout(std140, binding = " << vecLen << ") uniform something" << vecLen << " { mediump int " << vecLenName << "; };\n";
742 vtx << "void main()\n";
744 vtx << " gl_Position = a_position;\n";
747 frag << "void main()\n";
752 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
754 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
756 op << " ${PRECISION} ${VAR_TYPE} tmp;\n";
757 if (writeAccess == DIRECT)
758 op << " tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n";
759 else if (writeAccess == COMPONENT)
761 op << " tmp.x = coords.x;\n";
762 if (vecLen >= 2) op << " tmp.y = coords.y * 0.5;\n";
763 if (vecLen >= 3) op << " tmp.z = coords.z * 0.25;\n";
764 if (vecLen >= 4) op << " tmp.w = coords.w * 0.125;\n";
766 else if (writeAccess == SUBSCRIPT_STATIC)
768 op << " tmp[0] = coords.x;\n";
769 if (vecLen >= 2) op << " tmp[1] = coords.y * 0.5;\n";
770 if (vecLen >= 3) op << " tmp[2] = coords.z * 0.25;\n";
771 if (vecLen >= 4) op << " tmp[3] = coords.w * 0.125;\n";
773 else if (writeAccess == SUBSCRIPT_DYNAMIC)
775 op << " tmp[ui_zero] = coords.x;\n";
776 if (vecLen >= 2) op << " tmp[ui_one] = coords.y * 0.5;\n";
777 if (vecLen >= 3) op << " tmp[ui_two] = coords.z * 0.25;\n";
778 if (vecLen >= 4) op << " tmp[ui_three] = coords.w * 0.125;\n";
780 else if (writeAccess == SUBSCRIPT_STATIC_LOOP)
782 op << " for (int i = 0; i < " << vecLen << "; i++)\n";
784 op << " tmp[i] = coords.x;\n";
785 op << " coords = coords.${ROT_SWIZZLE} * 0.5;\n";
790 DE_ASSERT(writeAccess == SUBSCRIPT_DYNAMIC_LOOP);
791 op << " for (int i = 0; i < " << vecLenName << "; i++)\n";
793 op << " tmp[i] = coords.x;\n";
794 op << " coords = coords.${ROT_SWIZZLE} * 0.5;\n";
799 op << " ${PRECISION} float res = 0.0;\n";
800 if (readAccess == DIRECT)
801 op << " res = dot(tmp, ${VAR_TYPE}(1.0));\n";
802 else if (readAccess == COMPONENT)
804 op << " res += tmp.x;\n";
805 if (vecLen >= 2) op << " res += tmp.y;\n";
806 if (vecLen >= 3) op << " res += tmp.z;\n";
807 if (vecLen >= 4) op << " res += tmp.w;\n";
809 else if (readAccess == SUBSCRIPT_STATIC)
811 op << " res += tmp[0];\n";
812 if (vecLen >= 2) op << " res += tmp[1];\n";
813 if (vecLen >= 3) op << " res += tmp[2];\n";
814 if (vecLen >= 4) op << " res += tmp[3];\n";
816 else if (readAccess == SUBSCRIPT_DYNAMIC)
818 op << " res += tmp[ui_zero];\n";
819 if (vecLen >= 2) op << " res += tmp[ui_one];\n";
820 if (vecLen >= 3) op << " res += tmp[ui_two];\n";
821 if (vecLen >= 4) op << " res += tmp[ui_three];\n";
823 else if (readAccess == SUBSCRIPT_STATIC_LOOP)
825 op << " for (int i = 0; i < " << vecLen << "; i++)\n";
826 op << " res += tmp[i];\n";
830 DE_ASSERT(readAccess == SUBSCRIPT_DYNAMIC_LOOP);
831 op << " for (int i = 0; i < " << vecLenName << "; i++)\n";
832 op << " res += tmp[i];\n";
837 vtx << " v_color = vec3(res);\n";
838 frag << " o_color = vec4(v_color.rgb, 1.0);\n";
842 vtx << " v_coords = a_coords;\n";
843 frag << " o_color = vec4(vec3(res), 1.0);\n";
849 // Fill in shader templates.
850 static const char* s_swizzles[5] = { "", "x", "xy", "xyz", "xyzw" };
851 static const char* s_rotSwizzles[5] = { "", "x", "yx", "yzx", "yzwx" };
853 map<string, string> params;
854 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
855 params.insert(pair<string, string>("PRECISION", "mediump"));
856 params.insert(pair<string, string>("SWIZZLE", s_swizzles[vecLen]));
857 params.insert(pair<string, string>("ROT_SWIZZLE", s_rotSwizzles[vecLen]));
859 StringTemplate vertTemplate(vtx.str());
860 StringTemplate fragTemplate(frag.str());
861 string vertexShaderSource = vertTemplate.specialize(params);
862 string fragmentShaderSource = fragTemplate.specialize(params);
864 ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType);
865 return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
870 void evalSubscriptMat2 (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2); }
871 void evalSubscriptMat2x3 (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3); }
872 void evalSubscriptMat2x4 (ShaderEvalContext& c) { c.color = c.coords.swizzle(0,1,2,3) + 0.5f*c.coords.swizzle(1,2,3,0); }
874 void evalSubscriptMat3x2 (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2) + 0.25f*c.coords.swizzle(2,3); }
875 void evalSubscriptMat3 (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3) + 0.25f*c.coords.swizzle(2,3,0); }
876 void evalSubscriptMat3x4 (ShaderEvalContext& c) { c.color = c.coords.swizzle(0,1,2,3) + 0.5f*c.coords.swizzle(1,2,3,0) + 0.25f*c.coords.swizzle(2,3,0,1); }
878 void evalSubscriptMat4x2 (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2) + 0.25f*c.coords.swizzle(2,3) + 0.125f*c.coords.swizzle(3,0); }
879 void evalSubscriptMat4x3 (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3) + 0.25f*c.coords.swizzle(2,3,0) + 0.125f*c.coords.swizzle(3,0,1); }
880 void evalSubscriptMat4 (ShaderEvalContext& c) { c.color = c.coords + 0.5f*c.coords.swizzle(1,2,3,0) + 0.25f*c.coords.swizzle(2,3,0,1) + 0.125f*c.coords.swizzle(3,0,1,2); }
882 static ShaderEvalFunc getMatrixSubscriptEvalFunc (DataType dataType)
886 case TYPE_FLOAT_MAT2: return evalSubscriptMat2;
887 case TYPE_FLOAT_MAT2X3: return evalSubscriptMat2x3;
888 case TYPE_FLOAT_MAT2X4: return evalSubscriptMat2x4;
889 case TYPE_FLOAT_MAT3X2: return evalSubscriptMat3x2;
890 case TYPE_FLOAT_MAT3: return evalSubscriptMat3;
891 case TYPE_FLOAT_MAT3X4: return evalSubscriptMat3x4;
892 case TYPE_FLOAT_MAT4X2: return evalSubscriptMat4x2;
893 case TYPE_FLOAT_MAT4X3: return evalSubscriptMat4x3;
894 case TYPE_FLOAT_MAT4: return evalSubscriptMat4;
897 DE_FATAL("Invalid data type.");
902 static de::MovePtr<ShaderIndexingCase> createMatrixSubscriptCase (tcu::TestContext& context,
903 const std::string& caseName,
904 const std::string& description,
907 IndexAccessType writeAccess,
908 IndexAccessType readAccess)
910 std::ostringstream vtx;
911 std::ostringstream frag;
912 std::ostringstream& op = isVertexCase ? vtx : frag;
914 int numCols = getDataTypeMatrixNumColumns(varType);
915 int numRows = getDataTypeMatrixNumRows(varType);
916 const char* matSizeName = getIntUniformName(numCols);
917 DataType vecType = getDataTypeFloatVec(numRows);
919 vtx << "#version 310 es\n";
920 vtx << "#extension GL_ARB_separate_shader_objects : enable\n";
921 vtx << "#extension GL_ARB_shading_language_420pack : enable\n";
922 frag << "#version 310 es\n";
923 frag << "#extension GL_ARB_separate_shader_objects : enable\n";
924 frag << "#extension GL_ARB_shading_language_420pack : enable\n";
926 vtx << "layout(location = 0) in highp vec4 a_position;\n";
927 vtx << "layout(location = 1) in highp vec4 a_coords;\n";
928 frag << "layout(location = 0) out mediump vec4 o_color;\n";
932 vtx << "layout(location = 0) out mediump vec4 v_color;\n";
933 frag << "layout(location = 0) in mediump vec4 v_color;\n";
937 vtx << "layout(location = 0) out mediump vec4 v_coords;\n";
938 frag << "layout(location = 0) in mediump vec4 v_coords;\n";
941 if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
943 op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
944 if (numCols >= 2) op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
945 if (numCols >= 3) op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
946 if (numCols >= 4) op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
949 if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
950 op << "layout(std140, binding = " << numCols << ") uniform something" << numCols << " { mediump int " << matSizeName << "; };\n";
953 vtx << "void main()\n";
955 vtx << " gl_Position = a_position;\n";
958 frag << "void main()\n";
963 op << " ${PRECISION} vec4 coords = a_coords;\n";
965 op << " ${PRECISION} vec4 coords = v_coords;\n";
967 op << " ${PRECISION} ${MAT_TYPE} tmp;\n";
968 if (writeAccess == INDEXACCESS_STATIC)
970 op << " tmp[0] = ${VEC_TYPE}(coords);\n";
971 if (numCols >= 2) op << " tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
972 if (numCols >= 3) op << " tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
973 if (numCols >= 4) op << " tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
975 else if (writeAccess == INDEXACCESS_DYNAMIC)
977 op << " tmp[ui_zero] = ${VEC_TYPE}(coords);\n";
978 if (numCols >= 2) op << " tmp[ui_one] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
979 if (numCols >= 3) op << " tmp[ui_two] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
980 if (numCols >= 4) op << " tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
982 else if (writeAccess == INDEXACCESS_STATIC_LOOP)
984 op << " for (int i = 0; i < " << numCols << "; i++)\n";
986 op << " tmp[i] = ${VEC_TYPE}(coords);\n";
987 op << " coords = coords.yzwx * 0.5;\n";
992 DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
993 op << " for (int i = 0; i < " << matSizeName << "; i++)\n";
995 op << " tmp[i] = ${VEC_TYPE}(coords);\n";
996 op << " coords = coords.yzwx * 0.5;\n";
1001 op << " ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n";
1002 if (readAccess == INDEXACCESS_STATIC)
1004 op << " res += tmp[0];\n";
1005 if (numCols >= 2) op << " res += tmp[1];\n";
1006 if (numCols >= 3) op << " res += tmp[2];\n";
1007 if (numCols >= 4) op << " res += tmp[3];\n";
1009 else if (readAccess == INDEXACCESS_DYNAMIC)
1011 op << " res += tmp[ui_zero];\n";
1012 if (numCols >= 2) op << " res += tmp[ui_one];\n";
1013 if (numCols >= 3) op << " res += tmp[ui_two];\n";
1014 if (numCols >= 4) op << " res += tmp[ui_three];\n";
1016 else if (readAccess == INDEXACCESS_STATIC_LOOP)
1018 op << " for (int i = 0; i < " << numCols << "; i++)\n";
1019 op << " res += tmp[i];\n";
1023 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
1024 op << " for (int i = 0; i < " << matSizeName << "; i++)\n";
1025 op << " res += tmp[i];\n";
1030 vtx << " v_color = vec4(res${PADDING});\n";
1031 frag << " o_color = v_color;\n";
1035 vtx << " v_coords = a_coords;\n";
1036 frag << " o_color = vec4(res${PADDING});\n";
1042 // Fill in shader templates.
1043 map<string, string> params;
1044 params.insert(pair<string, string>("MAT_TYPE", getDataTypeName(varType)));
1045 params.insert(pair<string, string>("VEC_TYPE", getDataTypeName(vecType)));
1046 params.insert(pair<string, string>("PRECISION", "mediump"));
1049 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
1050 else if (numRows == 3)
1051 params.insert(pair<string, string>("PADDING", ", 1.0"));
1053 params.insert(pair<string, string>("PADDING", ""));
1055 StringTemplate vertTemplate(vtx.str());
1056 StringTemplate fragTemplate(frag.str());
1057 string vertexShaderSource = vertTemplate.specialize(params);
1058 string fragmentShaderSource = fragTemplate.specialize(params);
1060 ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType);
1061 return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
1064 // ShaderIndexingTests.
1066 class ShaderIndexingTests : public tcu::TestCaseGroup
1069 ShaderIndexingTests (tcu::TestContext& context);
1070 virtual ~ShaderIndexingTests (void);
1072 virtual void init (void);
1075 ShaderIndexingTests (const ShaderIndexingTests&); // not allowed!
1076 ShaderIndexingTests& operator= (const ShaderIndexingTests&); // not allowed!
1079 ShaderIndexingTests::ShaderIndexingTests(tcu::TestContext& context)
1080 : TestCaseGroup(context, "indexing", "Indexing Tests")
1084 ShaderIndexingTests::~ShaderIndexingTests (void)
1088 void ShaderIndexingTests::init (void)
1090 static const ShaderType s_shaderTypes[] =
1096 static const DataType s_floatAndVecTypes[] =
1104 // Varying array access cases.
1106 de::MovePtr<TestCaseGroup> varyingGroup(new TestCaseGroup(m_testCtx, "varying_array", "Varying array access tests."));
1108 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1110 DataType varType = s_floatAndVecTypes[typeNdx];
1111 for (int vertAccess = 0; vertAccess < INDEXACCESS_LAST; vertAccess++)
1113 for (int fragAccess = 0; fragAccess < INDEXACCESS_LAST; fragAccess++)
1115 const char* vertAccessName = getIndexAccessTypeName((IndexAccessType)vertAccess);
1116 const char* fragAccessName = getIndexAccessTypeName((IndexAccessType)fragAccess);
1117 string name = string(getDataTypeName(varType)) + "_" + vertAccessName + "_write_" + fragAccessName + "_read";
1118 string desc = string("Varying array with ") + vertAccessName + " write in vertex shader and " + fragAccessName + " read in fragment shader.";
1119 de::MovePtr<ShaderIndexingCase> testCase(createVaryingArrayCase(m_testCtx, name, desc, varType, (IndexAccessType)vertAccess, (IndexAccessType)fragAccess));
1120 varyingGroup->addChild(testCase.release());
1125 addChild(varyingGroup.release());
1128 // Uniform array access cases.
1130 de::MovePtr<TestCaseGroup> uniformGroup(new TestCaseGroup(m_testCtx, "uniform_array", "Uniform array access tests."));
1132 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1134 DataType varType = s_floatAndVecTypes[typeNdx];
1135 for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
1137 const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
1138 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1140 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1141 const char* shaderTypeName = getShaderTypeName(shaderType);
1142 string name = string(getDataTypeName(varType)) + "_" + readAccessName + "_read_" + shaderTypeName;
1143 string desc = string("Uniform array with ") + readAccessName + " read in " + shaderTypeName + " shader.";
1144 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1145 de::MovePtr<ShaderIndexingCase> testCase(createUniformArrayCase(m_testCtx, name, desc, isVertexCase, varType, (IndexAccessType)readAccess));
1146 uniformGroup->addChild(testCase.release());
1151 addChild(uniformGroup.release());
1154 // Temporary array access cases.
1156 de::MovePtr<TestCaseGroup> tmpGroup(new TestCaseGroup(m_testCtx, "tmp_array", "Temporary array access tests."));
1158 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1160 DataType varType = s_floatAndVecTypes[typeNdx];
1161 for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
1163 for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
1165 const char* writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
1166 const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
1168 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1170 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1171 const char* shaderTypeName = getShaderTypeName(shaderType);
1172 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
1173 string desc = string("Temporary array with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
1174 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1175 de::MovePtr<ShaderIndexingCase> testCase(createTmpArrayCase(m_testCtx, name, desc, isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
1176 tmpGroup->addChild(testCase.release());
1182 addChild(tmpGroup.release());
1185 // Vector indexing with subscripts.
1187 de::MovePtr<TestCaseGroup> vecGroup(new TestCaseGroup(m_testCtx, "vector_subscript", "Vector subscript indexing."));
1189 static const DataType s_vectorTypes[] =
1196 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_vectorTypes); typeNdx++)
1198 DataType varType = s_vectorTypes[typeNdx];
1199 for (int writeAccess = 0; writeAccess < VECTORACCESS_LAST; writeAccess++)
1201 for (int readAccess = 0; readAccess < VECTORACCESS_LAST; readAccess++)
1203 const char* writeAccessName = getVectorAccessTypeName((VectorAccessType)writeAccess);
1204 const char* readAccessName = getVectorAccessTypeName((VectorAccessType)readAccess);
1206 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1208 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1209 const char* shaderTypeName = getShaderTypeName(shaderType);
1210 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
1211 string desc = string("Vector subscript access with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
1212 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1213 de::MovePtr<ShaderIndexingCase> testCase(createVectorSubscriptCase(m_testCtx, name.c_str(), desc.c_str(), isVertexCase, varType, (VectorAccessType)writeAccess, (VectorAccessType)readAccess));
1214 vecGroup->addChild(testCase.release());
1220 addChild(vecGroup.release());
1223 // Matrix indexing with subscripts.
1225 de::MovePtr<TestCaseGroup> matGroup(new TestCaseGroup(m_testCtx, "matrix_subscript", "Matrix subscript indexing."));
1227 static const DataType s_matrixTypes[] =
1240 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_matrixTypes); typeNdx++)
1242 DataType varType = s_matrixTypes[typeNdx];
1243 for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
1245 for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
1247 const char* writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
1248 const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
1250 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1252 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1253 const char* shaderTypeName = getShaderTypeName(shaderType);
1254 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
1255 string desc = string("Vector subscript access with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
1256 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1257 de::MovePtr<ShaderIndexingCase> testCase(createMatrixSubscriptCase(m_testCtx, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
1258 matGroup->addChild(testCase.release());
1264 addChild(matGroup.release());
1270 tcu::TestCaseGroup* createIndexingTests (tcu::TestContext& testCtx)
1272 return new ShaderIndexingTests(testCtx);