1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2016 Google Inc.
6 * Copyright (c) 2016 The Khronos Group Inc.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Shader indexing (arrays, vector, matrices) tests.
23 */ /*-------------------------------------------------------------------*/
25 #include "glcShaderIndexingTests.hpp"
26 #include "glcShaderRenderCase.hpp"
27 #include "gluShaderUtil.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "tcuStringTemplate.hpp"
47 INDEXACCESS_STATIC = 0,
49 INDEXACCESS_STATIC_LOOP,
50 INDEXACCESS_DYNAMIC_LOOP,
55 static const char* getIndexAccessTypeName(IndexAccessType accessType)
57 static const char* s_names[INDEXACCESS_LAST] = { "static", "dynamic", "static_loop", "dynamic_loop" };
59 DE_ASSERT(deInBounds32((int)accessType, 0, INDEXACCESS_LAST));
60 return s_names[(int)accessType];
69 SUBSCRIPT_STATIC_LOOP,
70 SUBSCRIPT_DYNAMIC_LOOP,
75 static const char* getVectorAccessTypeName(VectorAccessType accessType)
77 static const char* s_names[VECTORACCESS_LAST] = { "direct",
81 "static_loop_subscript",
82 "dynamic_loop_subscript" };
84 DE_ASSERT(deInBounds32((int)accessType, 0, VECTORACCESS_LAST));
85 return s_names[(int)accessType];
88 void evalArrayCoordsFloat(ShaderEvalContext& c)
90 c.color.x() = 1.875f * c.coords.x();
92 void evalArrayCoordsVec2(ShaderEvalContext& c)
94 c.color.xy() = 1.875f * c.coords.swizzle(0, 1);
96 void evalArrayCoordsVec3(ShaderEvalContext& c)
98 c.color.xyz() = 1.875f * c.coords.swizzle(0, 1, 2);
100 void evalArrayCoordsVec4(ShaderEvalContext& c)
102 c.color = 1.875f * c.coords;
105 static ShaderEvalFunc getArrayCoordsEvalFunc(DataType dataType)
107 if (dataType == TYPE_FLOAT)
108 return evalArrayCoordsFloat;
109 else if (dataType == TYPE_FLOAT_VEC2)
110 return evalArrayCoordsVec2;
111 else if (dataType == TYPE_FLOAT_VEC3)
112 return evalArrayCoordsVec3;
113 else if (dataType == TYPE_FLOAT_VEC4)
114 return evalArrayCoordsVec4;
116 DE_ASSERT(DE_FALSE && "Invalid data type.");
120 void evalArrayUniformFloat(ShaderEvalContext& c)
122 c.color.x() = 1.875f * c.constCoords.x();
124 void evalArrayUniformVec2(ShaderEvalContext& c)
126 c.color.xy() = 1.875f * c.constCoords.swizzle(0, 1);
128 void evalArrayUniformVec3(ShaderEvalContext& c)
130 c.color.xyz() = 1.875f * c.constCoords.swizzle(0, 1, 2);
132 void evalArrayUniformVec4(ShaderEvalContext& c)
134 c.color = 1.875f * c.constCoords;
137 static ShaderEvalFunc getArrayUniformEvalFunc(DataType dataType)
139 if (dataType == TYPE_FLOAT)
140 return evalArrayUniformFloat;
141 else if (dataType == TYPE_FLOAT_VEC2)
142 return evalArrayUniformVec2;
143 else if (dataType == TYPE_FLOAT_VEC3)
144 return evalArrayUniformVec3;
145 else if (dataType == TYPE_FLOAT_VEC4)
146 return evalArrayUniformVec4;
148 DE_ASSERT(DE_FALSE && "Invalid data type.");
152 // ShaderIndexingCase
154 class ShaderIndexingCase : public ShaderRenderCase
157 ShaderIndexingCase(Context& context, const char* name, const char* description, bool isVertexCase, DataType varType,
158 ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
159 virtual ~ShaderIndexingCase(void);
162 ShaderIndexingCase(const ShaderIndexingCase&); // not allowed!
163 ShaderIndexingCase& operator=(const ShaderIndexingCase&); // not allowed!
165 virtual void setup(deUint32 programID);
166 virtual void setupUniforms(deUint32 programID, const Vec4& constCoords);
171 ShaderIndexingCase::ShaderIndexingCase(Context& context, const char* name, const char* description, bool isVertexCase,
172 DataType varType, ShaderEvalFunc evalFunc, const char* vertShaderSource,
173 const char* fragShaderSource)
174 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
175 description, isVertexCase, evalFunc)
178 m_vertShaderSource = vertShaderSource;
179 m_fragShaderSource = fragShaderSource;
182 ShaderIndexingCase::~ShaderIndexingCase(void)
186 void ShaderIndexingCase::setup(deUint32 programID)
191 void ShaderIndexingCase::setupUniforms(deUint32 programID, const Vec4& constCoords)
193 const glw::Functions& gl = m_renderCtx.getFunctions();
195 DE_UNREF(constCoords);
197 int arrLoc = gl.getUniformLocation(programID, "u_arr");
200 //int scalarSize = getDataTypeScalarSize(m_varType);
201 if (m_varType == TYPE_FLOAT)
204 arr[0] = constCoords.x();
205 arr[1] = constCoords.x() * 0.5f;
206 arr[2] = constCoords.x() * 0.25f;
207 arr[3] = constCoords.x() * 0.125f;
208 gl.uniform1fv(arrLoc, 4, &arr[0]);
210 else if (m_varType == TYPE_FLOAT_VEC2)
213 arr[0] = constCoords.swizzle(0, 1);
214 arr[1] = constCoords.swizzle(0, 1) * 0.5f;
215 arr[2] = constCoords.swizzle(0, 1) * 0.25f;
216 arr[3] = constCoords.swizzle(0, 1) * 0.125f;
217 gl.uniform2fv(arrLoc, 4, arr[0].getPtr());
219 else if (m_varType == TYPE_FLOAT_VEC3)
222 arr[0] = constCoords.swizzle(0, 1, 2);
223 arr[1] = constCoords.swizzle(0, 1, 2) * 0.5f;
224 arr[2] = constCoords.swizzle(0, 1, 2) * 0.25f;
225 arr[3] = constCoords.swizzle(0, 1, 2) * 0.125f;
226 gl.uniform3fv(arrLoc, 4, arr[0].getPtr());
228 else if (m_varType == TYPE_FLOAT_VEC4)
231 arr[0] = constCoords.swizzle(0, 1, 2, 3);
232 arr[1] = constCoords.swizzle(0, 1, 2, 3) * 0.5f;
233 arr[2] = constCoords.swizzle(0, 1, 2, 3) * 0.25f;
234 arr[3] = constCoords.swizzle(0, 1, 2, 3) * 0.125f;
235 gl.uniform4fv(arrLoc, 4, arr[0].getPtr());
238 DE_TEST_ASSERT(false);
244 static ShaderIndexingCase* createVaryingArrayCase(Context& context, const char* caseName, const char* description,
245 glu::GLSLVersion glslVersion, DataType varType,
246 IndexAccessType vertAccess, IndexAccessType fragAccess)
248 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
249 glslVersion >= glu::GLSL_VERSION_330);
251 std::ostringstream vtx;
252 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
253 vtx << "in highp vec4 a_position;\n";
254 vtx << "in highp vec4 a_coords;\n";
255 if (vertAccess == INDEXACCESS_DYNAMIC)
256 vtx << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
257 else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
258 vtx << "uniform mediump int ui_four;\n";
259 vtx << "out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
261 vtx << "void main()\n";
263 vtx << " gl_Position = a_position;\n";
264 if (vertAccess == INDEXACCESS_STATIC)
266 vtx << " var[0] = ${VAR_TYPE}(a_coords);\n";
267 vtx << " var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n";
268 vtx << " var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n";
269 vtx << " var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n";
271 else if (vertAccess == INDEXACCESS_DYNAMIC)
273 vtx << " var[ui_zero] = ${VAR_TYPE}(a_coords);\n";
274 vtx << " var[ui_one] = ${VAR_TYPE}(a_coords) * 0.5;\n";
275 vtx << " var[ui_two] = ${VAR_TYPE}(a_coords) * 0.25;\n";
276 vtx << " var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n";
278 else if (vertAccess == INDEXACCESS_STATIC_LOOP)
280 vtx << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
281 vtx << " for (int i = 0; i < 4; i++)\n";
283 vtx << " var[i] = ${VAR_TYPE}(coords);\n";
284 vtx << " coords = coords * 0.5;\n";
289 DE_ASSERT(vertAccess == INDEXACCESS_DYNAMIC_LOOP);
290 vtx << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
291 vtx << " for (int i = 0; i < ui_four; i++)\n";
293 vtx << " var[i] = ${VAR_TYPE}(coords);\n";
294 vtx << " coords = coords * 0.5;\n";
299 std::ostringstream frag;
300 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
301 frag << "precision mediump int;\n";
302 frag << "layout(location = 0) out mediump vec4 o_color;\n";
303 if (fragAccess == INDEXACCESS_DYNAMIC)
304 frag << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
305 else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
306 frag << "uniform int ui_four;\n";
307 frag << "in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
309 frag << "void main()\n";
311 frag << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
312 if (fragAccess == INDEXACCESS_STATIC)
314 frag << " res += var[0];\n";
315 frag << " res += var[1];\n";
316 frag << " res += var[2];\n";
317 frag << " res += var[3];\n";
319 else if (fragAccess == INDEXACCESS_DYNAMIC)
321 frag << " res += var[ui_zero];\n";
322 frag << " res += var[ui_one];\n";
323 frag << " res += var[ui_two];\n";
324 frag << " res += var[ui_three];\n";
326 else if (fragAccess == INDEXACCESS_STATIC_LOOP)
328 frag << " for (int i = 0; i < 4; i++)\n";
329 frag << " res += var[i];\n";
333 DE_ASSERT(fragAccess == INDEXACCESS_DYNAMIC_LOOP);
334 frag << " for (int i = 0; i < ui_four; i++)\n";
335 frag << " res += var[i];\n";
337 frag << " o_color = vec4(res${PADDING});\n";
340 // Fill in shader templates.
341 map<string, string> params;
342 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
343 params.insert(pair<string, string>("ARRAY_LEN", "4"));
344 params.insert(pair<string, string>("PRECISION", "mediump"));
346 if (varType == TYPE_FLOAT)
347 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
348 else if (varType == TYPE_FLOAT_VEC2)
349 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
350 else if (varType == TYPE_FLOAT_VEC3)
351 params.insert(pair<string, string>("PADDING", ", 1.0"));
353 params.insert(pair<string, string>("PADDING", ""));
355 StringTemplate vertTemplate(vtx.str().c_str());
356 StringTemplate fragTemplate(frag.str().c_str());
357 string vertexShaderSource = vertTemplate.specialize(params);
358 string fragmentShaderSource = fragTemplate.specialize(params);
360 ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
361 return new ShaderIndexingCase(context, caseName, description, true, varType, evalFunc, vertexShaderSource.c_str(),
362 fragmentShaderSource.c_str());
365 static ShaderIndexingCase* createUniformArrayCase(Context& context, const char* caseName, const char* description,
366 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
367 IndexAccessType readAccess)
369 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
370 glslVersion >= glu::GLSL_VERSION_330);
372 std::ostringstream vtx;
373 std::ostringstream frag;
374 std::ostringstream& op = isVertexCase ? vtx : frag;
376 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
377 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
379 vtx << "in highp vec4 a_position;\n";
380 vtx << "in highp vec4 a_coords;\n";
381 frag << "layout(location = 0) out mediump vec4 o_color;\n";
385 vtx << "out mediump vec4 v_color;\n";
386 frag << "in mediump vec4 v_color;\n";
390 vtx << "out mediump vec4 v_coords;\n";
391 frag << "in mediump vec4 v_coords;\n";
394 if (readAccess == INDEXACCESS_DYNAMIC)
395 op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
396 else if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
397 op << "uniform mediump int ui_four;\n";
399 op << "uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n";
402 vtx << "void main()\n";
404 vtx << " gl_Position = a_position;\n";
407 frag << "void main()\n";
411 op << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
412 if (readAccess == INDEXACCESS_STATIC)
414 op << " res += u_arr[0];\n";
415 op << " res += u_arr[1];\n";
416 op << " res += u_arr[2];\n";
417 op << " res += u_arr[3];\n";
419 else if (readAccess == INDEXACCESS_DYNAMIC)
421 op << " res += u_arr[ui_zero];\n";
422 op << " res += u_arr[ui_one];\n";
423 op << " res += u_arr[ui_two];\n";
424 op << " res += u_arr[ui_three];\n";
426 else if (readAccess == INDEXACCESS_STATIC_LOOP)
428 op << " for (int i = 0; i < 4; i++)\n";
429 op << " res += u_arr[i];\n";
433 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
434 op << " for (int i = 0; i < ui_four; i++)\n";
435 op << " res += u_arr[i];\n";
440 vtx << " v_color = vec4(res${PADDING});\n";
441 frag << " o_color = v_color;\n";
445 vtx << " v_coords = a_coords;\n";
446 frag << " o_color = vec4(res${PADDING});\n";
452 // Fill in shader templates.
453 map<string, string> params;
454 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
455 params.insert(pair<string, string>("ARRAY_LEN", "4"));
456 params.insert(pair<string, string>("PRECISION", "mediump"));
458 if (varType == TYPE_FLOAT)
459 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
460 else if (varType == TYPE_FLOAT_VEC2)
461 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
462 else if (varType == TYPE_FLOAT_VEC3)
463 params.insert(pair<string, string>("PADDING", ", 1.0"));
465 params.insert(pair<string, string>("PADDING", ""));
467 StringTemplate vertTemplate(vtx.str().c_str());
468 StringTemplate fragTemplate(frag.str().c_str());
469 string vertexShaderSource = vertTemplate.specialize(params);
470 string fragmentShaderSource = fragTemplate.specialize(params);
472 ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType);
473 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc,
474 vertexShaderSource.c_str(), fragmentShaderSource.c_str());
477 static ShaderIndexingCase* createTmpArrayCase(Context& context, const char* caseName, const char* description,
478 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
479 IndexAccessType writeAccess, IndexAccessType readAccess)
481 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
482 glslVersion >= glu::GLSL_VERSION_330);
484 std::ostringstream vtx;
485 std::ostringstream frag;
486 std::ostringstream& op = isVertexCase ? vtx : frag;
488 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
489 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
491 vtx << "in highp vec4 a_position;\n";
492 vtx << "in highp vec4 a_coords;\n";
493 frag << "layout(location = 0) out mediump vec4 o_color;\n";
497 vtx << "out mediump vec4 v_color;\n";
498 frag << "in mediump vec4 v_color;\n";
502 vtx << "out mediump vec4 v_coords;\n";
503 frag << "in mediump vec4 v_coords;\n";
506 if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
507 op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
509 if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
510 op << "uniform mediump int ui_four;\n";
513 vtx << "void main()\n";
515 vtx << " gl_Position = a_position;\n";
518 frag << "void main()\n";
523 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
525 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
527 op << " ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n";
528 if (writeAccess == INDEXACCESS_STATIC)
530 op << " arr[0] = ${VAR_TYPE}(coords);\n";
531 op << " arr[1] = ${VAR_TYPE}(coords) * 0.5;\n";
532 op << " arr[2] = ${VAR_TYPE}(coords) * 0.25;\n";
533 op << " arr[3] = ${VAR_TYPE}(coords) * 0.125;\n";
535 else if (writeAccess == INDEXACCESS_DYNAMIC)
537 op << " arr[ui_zero] = ${VAR_TYPE}(coords);\n";
538 op << " arr[ui_one] = ${VAR_TYPE}(coords) * 0.5;\n";
539 op << " arr[ui_two] = ${VAR_TYPE}(coords) * 0.25;\n";
540 op << " arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n";
542 else if (writeAccess == INDEXACCESS_STATIC_LOOP)
544 op << " for (int i = 0; i < 4; i++)\n";
546 op << " arr[i] = ${VAR_TYPE}(coords);\n";
547 op << " coords = coords * 0.5;\n";
552 DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
553 op << " for (int i = 0; i < ui_four; i++)\n";
555 op << " arr[i] = ${VAR_TYPE}(coords);\n";
556 op << " coords = coords * 0.5;\n";
561 op << " ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
562 if (readAccess == INDEXACCESS_STATIC)
564 op << " res += arr[0];\n";
565 op << " res += arr[1];\n";
566 op << " res += arr[2];\n";
567 op << " res += arr[3];\n";
569 else if (readAccess == INDEXACCESS_DYNAMIC)
571 op << " res += arr[ui_zero];\n";
572 op << " res += arr[ui_one];\n";
573 op << " res += arr[ui_two];\n";
574 op << " res += arr[ui_three];\n";
576 else if (readAccess == INDEXACCESS_STATIC_LOOP)
578 op << " for (int i = 0; i < 4; i++)\n";
579 op << " res += arr[i];\n";
583 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
584 op << " for (int i = 0; i < ui_four; i++)\n";
585 op << " res += arr[i];\n";
590 vtx << " v_color = vec4(res${PADDING});\n";
591 frag << " o_color = v_color;\n";
595 vtx << " v_coords = a_coords;\n";
596 frag << " o_color = vec4(res${PADDING});\n";
602 // Fill in shader templates.
603 map<string, string> params;
604 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
605 params.insert(pair<string, string>("ARRAY_LEN", "4"));
606 params.insert(pair<string, string>("PRECISION", "mediump"));
608 if (varType == TYPE_FLOAT)
609 params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
610 else if (varType == TYPE_FLOAT_VEC2)
611 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
612 else if (varType == TYPE_FLOAT_VEC3)
613 params.insert(pair<string, string>("PADDING", ", 1.0"));
615 params.insert(pair<string, string>("PADDING", ""));
617 StringTemplate vertTemplate(vtx.str().c_str());
618 StringTemplate fragTemplate(frag.str().c_str());
619 string vertexShaderSource = vertTemplate.specialize(params);
620 string fragmentShaderSource = fragTemplate.specialize(params);
622 ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
623 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc,
624 vertexShaderSource.c_str(), fragmentShaderSource.c_str());
629 void evalSubscriptVec2(ShaderEvalContext& c)
631 c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y());
633 void evalSubscriptVec3(ShaderEvalContext& c)
635 c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y() + 0.25f * c.coords.z());
637 void evalSubscriptVec4(ShaderEvalContext& c)
639 c.color.xyz() = Vec3(c.coords.x() + 0.5f * c.coords.y() + 0.25f * c.coords.z() + 0.125f * c.coords.w());
642 static ShaderEvalFunc getVectorSubscriptEvalFunc(DataType dataType)
644 if (dataType == TYPE_FLOAT_VEC2)
645 return evalSubscriptVec2;
646 else if (dataType == TYPE_FLOAT_VEC3)
647 return evalSubscriptVec3;
648 else if (dataType == TYPE_FLOAT_VEC4)
649 return evalSubscriptVec4;
651 DE_ASSERT(DE_FALSE && "Invalid data type.");
655 static ShaderIndexingCase* createVectorSubscriptCase(Context& context, const char* caseName, const char* description,
656 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
657 VectorAccessType writeAccess, VectorAccessType readAccess)
659 std::ostringstream vtx;
660 std::ostringstream frag;
661 std::ostringstream& op = isVertexCase ? vtx : frag;
663 int vecLen = getDataTypeScalarSize(varType);
664 const char* vecLenName = getIntUniformName(vecLen);
666 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
667 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
669 vtx << "in highp vec4 a_position;\n";
670 vtx << "in highp vec4 a_coords;\n";
671 frag << "layout(location = 0) out mediump vec4 o_color;\n";
675 vtx << "out mediump vec3 v_color;\n";
676 frag << "in mediump vec3 v_color;\n";
680 vtx << "out mediump vec4 v_coords;\n";
681 frag << "in mediump vec4 v_coords;\n";
684 if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC)
686 op << "uniform mediump int ui_zero";
696 if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP)
697 op << "uniform mediump int " << vecLenName << ";\n";
700 vtx << "void main()\n";
702 vtx << " gl_Position = a_position;\n";
705 frag << "void main()\n";
710 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
712 op << " ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
714 op << " ${PRECISION} ${VAR_TYPE} tmp;\n";
715 if (writeAccess == DIRECT)
716 op << " tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n";
717 else if (writeAccess == COMPONENT)
719 op << " tmp.x = coords.x;\n";
721 op << " tmp.y = coords.y * 0.5;\n";
723 op << " tmp.z = coords.z * 0.25;\n";
725 op << " tmp.w = coords.w * 0.125;\n";
727 else if (writeAccess == SUBSCRIPT_STATIC)
729 op << " tmp[0] = coords.x;\n";
731 op << " tmp[1] = coords.y * 0.5;\n";
733 op << " tmp[2] = coords.z * 0.25;\n";
735 op << " tmp[3] = coords.w * 0.125;\n";
737 else if (writeAccess == SUBSCRIPT_DYNAMIC)
739 op << " tmp[ui_zero] = coords.x;\n";
741 op << " tmp[ui_one] = coords.y * 0.5;\n";
743 op << " tmp[ui_two] = coords.z * 0.25;\n";
745 op << " tmp[ui_three] = coords.w * 0.125;\n";
747 else if (writeAccess == SUBSCRIPT_STATIC_LOOP)
749 op << " for (int i = 0; i < " << vecLen << "; i++)\n";
751 op << " tmp[i] = coords.x;\n";
752 op << " coords = coords.${ROT_SWIZZLE} * 0.5;\n";
757 DE_ASSERT(writeAccess == SUBSCRIPT_DYNAMIC_LOOP);
758 op << " for (int i = 0; i < " << vecLenName << "; i++)\n";
760 op << " tmp[i] = coords.x;\n";
761 op << " coords = coords.${ROT_SWIZZLE} * 0.5;\n";
766 op << " ${PRECISION} float res = 0.0;\n";
767 if (readAccess == DIRECT)
768 op << " res = dot(tmp, ${VAR_TYPE}(1.0));\n";
769 else if (readAccess == COMPONENT)
771 op << " res += tmp.x;\n";
773 op << " res += tmp.y;\n";
775 op << " res += tmp.z;\n";
777 op << " res += tmp.w;\n";
779 else if (readAccess == SUBSCRIPT_STATIC)
781 op << " res += tmp[0];\n";
783 op << " res += tmp[1];\n";
785 op << " res += tmp[2];\n";
787 op << " res += tmp[3];\n";
789 else if (readAccess == SUBSCRIPT_DYNAMIC)
791 op << " res += tmp[ui_zero];\n";
793 op << " res += tmp[ui_one];\n";
795 op << " res += tmp[ui_two];\n";
797 op << " res += tmp[ui_three];\n";
799 else if (readAccess == SUBSCRIPT_STATIC_LOOP)
801 op << " for (int i = 0; i < " << vecLen << "; i++)\n";
802 op << " res += tmp[i];\n";
806 DE_ASSERT(readAccess == SUBSCRIPT_DYNAMIC_LOOP);
807 op << " for (int i = 0; i < " << vecLenName << "; i++)\n";
808 op << " res += tmp[i];\n";
813 vtx << " v_color = vec3(res);\n";
814 frag << " o_color = vec4(v_color.rgb, 1.0);\n";
818 vtx << " v_coords = a_coords;\n";
819 frag << " o_color = vec4(vec3(res), 1.0);\n";
825 // Fill in shader templates.
826 static const char* s_swizzles[5] = { "", "x", "xy", "xyz", "xyzw" };
827 static const char* s_rotSwizzles[5] = { "", "x", "yx", "yzx", "yzwx" };
829 map<string, string> params;
830 params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
831 params.insert(pair<string, string>("PRECISION", "mediump"));
832 params.insert(pair<string, string>("SWIZZLE", s_swizzles[vecLen]));
833 params.insert(pair<string, string>("ROT_SWIZZLE", s_rotSwizzles[vecLen]));
835 StringTemplate vertTemplate(vtx.str().c_str());
836 StringTemplate fragTemplate(frag.str().c_str());
837 string vertexShaderSource = vertTemplate.specialize(params);
838 string fragmentShaderSource = fragTemplate.specialize(params);
840 ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType);
841 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc,
842 vertexShaderSource.c_str(), fragmentShaderSource.c_str());
847 void evalSubscriptMat2(ShaderEvalContext& c)
849 c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2);
851 void evalSubscriptMat2x3(ShaderEvalContext& c)
853 c.color.xyz() = c.coords.swizzle(0, 1, 2) + 0.5f * c.coords.swizzle(1, 2, 3);
855 void evalSubscriptMat2x4(ShaderEvalContext& c)
857 c.color = c.coords.swizzle(0, 1, 2, 3) + 0.5f * c.coords.swizzle(1, 2, 3, 0);
860 void evalSubscriptMat3x2(ShaderEvalContext& c)
862 c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2) + 0.25f * c.coords.swizzle(2, 3);
864 void evalSubscriptMat3(ShaderEvalContext& c)
866 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);
868 void evalSubscriptMat3x4(ShaderEvalContext& c)
870 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);
873 void evalSubscriptMat4x2(ShaderEvalContext& c)
875 c.color.xy() = c.coords.swizzle(0, 1) + 0.5f * c.coords.swizzle(1, 2) + 0.25f * c.coords.swizzle(2, 3) +
876 0.125f * c.coords.swizzle(3, 0);
878 void evalSubscriptMat4x3(ShaderEvalContext& c)
880 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) +
881 0.125f * c.coords.swizzle(3, 0, 1);
883 void evalSubscriptMat4(ShaderEvalContext& c)
885 c.color = c.coords + 0.5f * c.coords.swizzle(1, 2, 3, 0) + 0.25f * c.coords.swizzle(2, 3, 0, 1) +
886 0.125f * c.coords.swizzle(3, 0, 1, 2);
889 static ShaderEvalFunc getMatrixSubscriptEvalFunc(DataType dataType)
893 case TYPE_FLOAT_MAT2:
894 return evalSubscriptMat2;
895 case TYPE_FLOAT_MAT2X3:
896 return evalSubscriptMat2x3;
897 case TYPE_FLOAT_MAT2X4:
898 return evalSubscriptMat2x4;
899 case TYPE_FLOAT_MAT3X2:
900 return evalSubscriptMat3x2;
901 case TYPE_FLOAT_MAT3:
902 return evalSubscriptMat3;
903 case TYPE_FLOAT_MAT3X4:
904 return evalSubscriptMat3x4;
905 case TYPE_FLOAT_MAT4X2:
906 return evalSubscriptMat4x2;
907 case TYPE_FLOAT_MAT4X3:
908 return evalSubscriptMat4x3;
909 case TYPE_FLOAT_MAT4:
910 return evalSubscriptMat4;
913 DE_ASSERT(DE_FALSE && "Invalid data type.");
918 static ShaderIndexingCase* createMatrixSubscriptCase(Context& context, const char* caseName, const char* description,
919 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
920 IndexAccessType writeAccess, IndexAccessType readAccess)
922 DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
923 glslVersion >= glu::GLSL_VERSION_330);
925 std::ostringstream vtx;
926 std::ostringstream frag;
927 std::ostringstream& op = isVertexCase ? vtx : frag;
929 int numCols = getDataTypeMatrixNumColumns(varType);
930 int numRows = getDataTypeMatrixNumRows(varType);
931 const char* matSizeName = getIntUniformName(numCols);
932 DataType vecType = getDataTypeFloatVec(numRows);
934 vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
935 frag << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
937 vtx << "in highp vec4 a_position;\n";
938 vtx << "in highp vec4 a_coords;\n";
939 frag << "layout(location = 0) out mediump vec4 o_color;\n";
943 vtx << "out mediump vec4 v_color;\n";
944 frag << "in mediump vec4 v_color;\n";
948 vtx << "out mediump vec4 v_coords;\n";
949 frag << "in mediump vec4 v_coords;\n";
952 if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
954 op << "uniform mediump int ui_zero";
964 if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
965 op << "uniform mediump int " << matSizeName << ";\n";
968 vtx << "void main()\n";
970 vtx << " gl_Position = a_position;\n";
973 frag << "void main()\n";
978 op << " ${PRECISION} vec4 coords = a_coords;\n";
980 op << " ${PRECISION} vec4 coords = v_coords;\n";
982 op << " ${PRECISION} ${MAT_TYPE} tmp;\n";
983 if (writeAccess == INDEXACCESS_STATIC)
985 op << " tmp[0] = ${VEC_TYPE}(coords);\n";
987 op << " tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
989 op << " tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
991 op << " tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
993 else if (writeAccess == INDEXACCESS_DYNAMIC)
995 op << " tmp[ui_zero] = ${VEC_TYPE}(coords);\n";
997 op << " tmp[ui_one] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
999 op << " tmp[ui_two] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
1001 op << " tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
1003 else if (writeAccess == INDEXACCESS_STATIC_LOOP)
1005 op << " for (int i = 0; i < " << numCols << "; i++)\n";
1007 op << " tmp[i] = ${VEC_TYPE}(coords);\n";
1008 op << " coords = coords.yzwx * 0.5;\n";
1013 DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
1014 op << " for (int i = 0; i < " << matSizeName << "; i++)\n";
1016 op << " tmp[i] = ${VEC_TYPE}(coords);\n";
1017 op << " coords = coords.yzwx * 0.5;\n";
1022 op << " ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n";
1023 if (readAccess == INDEXACCESS_STATIC)
1025 op << " res += tmp[0];\n";
1027 op << " res += tmp[1];\n";
1029 op << " res += tmp[2];\n";
1031 op << " res += tmp[3];\n";
1033 else if (readAccess == INDEXACCESS_DYNAMIC)
1035 op << " res += tmp[ui_zero];\n";
1037 op << " res += tmp[ui_one];\n";
1039 op << " res += tmp[ui_two];\n";
1041 op << " res += tmp[ui_three];\n";
1043 else if (readAccess == INDEXACCESS_STATIC_LOOP)
1045 op << " for (int i = 0; i < " << numCols << "; i++)\n";
1046 op << " res += tmp[i];\n";
1050 DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
1051 op << " for (int i = 0; i < " << matSizeName << "; i++)\n";
1052 op << " res += tmp[i];\n";
1057 vtx << " v_color = vec4(res${PADDING});\n";
1058 frag << " o_color = v_color;\n";
1062 vtx << " v_coords = a_coords;\n";
1063 frag << " o_color = vec4(res${PADDING});\n";
1069 // Fill in shader templates.
1070 map<string, string> params;
1071 params.insert(pair<string, string>("MAT_TYPE", getDataTypeName(varType)));
1072 params.insert(pair<string, string>("VEC_TYPE", getDataTypeName(vecType)));
1073 params.insert(pair<string, string>("PRECISION", "mediump"));
1076 params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
1077 else if (numRows == 3)
1078 params.insert(pair<string, string>("PADDING", ", 1.0"));
1080 params.insert(pair<string, string>("PADDING", ""));
1082 StringTemplate vertTemplate(vtx.str().c_str());
1083 StringTemplate fragTemplate(frag.str().c_str());
1084 string vertexShaderSource = vertTemplate.specialize(params);
1085 string fragmentShaderSource = fragTemplate.specialize(params);
1087 ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType);
1088 return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc,
1089 vertexShaderSource.c_str(), fragmentShaderSource.c_str());
1092 // ShaderIndexingTests.
1094 ShaderIndexingTests::ShaderIndexingTests(Context& context, glu::GLSLVersion glslVersion)
1095 : TestCaseGroup(context, "indexing", "Indexing Tests"), m_glslVersion(glslVersion)
1099 ShaderIndexingTests::~ShaderIndexingTests(void)
1103 void ShaderIndexingTests::init(void)
1105 static const DataType s_floatAndVecTypes[] = { TYPE_FLOAT, TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4 };
1107 static const ShaderType s_shaderTypes[] = { SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT };
1109 // Varying array access cases.
1111 TestCaseGroup* varyingGroup = new TestCaseGroup(m_context, "varying_array", "Varying array access tests.");
1112 addChild(varyingGroup);
1114 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1116 DataType varType = s_floatAndVecTypes[typeNdx];
1117 for (int vertAccess = 0; vertAccess < INDEXACCESS_LAST; vertAccess++)
1119 for (int fragAccess = 0; fragAccess < INDEXACCESS_LAST; fragAccess++)
1121 if (vertAccess == INDEXACCESS_STATIC && fragAccess == INDEXACCESS_STATIC)
1124 const char* vertAccessName = getIndexAccessTypeName((IndexAccessType)vertAccess);
1125 const char* fragAccessName = getIndexAccessTypeName((IndexAccessType)fragAccess);
1127 string(getDataTypeName(varType)) + "_" + vertAccessName + "_write_" + fragAccessName + "_read";
1128 string desc = string("Varying array with ") + vertAccessName + " write in vertex shader and " +
1129 fragAccessName + " read in fragment shader.";
1130 varyingGroup->addChild(createVaryingArrayCase(m_context, name.c_str(), desc.c_str(), m_glslVersion,
1131 varType, (IndexAccessType)vertAccess,
1132 (IndexAccessType)fragAccess));
1138 // Uniform array access cases.
1140 TestCaseGroup* uniformGroup = new TestCaseGroup(m_context, "uniform_array", "Uniform array access tests.");
1141 addChild(uniformGroup);
1143 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1145 DataType varType = s_floatAndVecTypes[typeNdx];
1146 for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
1148 const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
1149 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1151 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1152 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType);
1153 string name = string(getDataTypeName(varType)) + "_" + readAccessName + "_read_" + shaderTypeName;
1155 string("Uniform array with ") + readAccessName + " read in " + shaderTypeName + " shader.";
1156 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1157 uniformGroup->addChild(createUniformArrayCase(m_context, name.c_str(), desc.c_str(), m_glslVersion,
1158 isVertexCase, varType, (IndexAccessType)readAccess));
1164 // Temporary array access cases.
1166 TestCaseGroup* tmpGroup = new TestCaseGroup(m_context, "tmp_array", "Temporary array access tests.");
1169 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
1171 DataType varType = s_floatAndVecTypes[typeNdx];
1172 for (int isReadStatic = 0; isReadStatic < 2; isReadStatic++)
1174 for (int access = INDEXACCESS_STATIC + 1; access < INDEXACCESS_LAST; access++)
1176 IndexAccessType readAccess = isReadStatic ? INDEXACCESS_STATIC : (IndexAccessType)access;
1177 IndexAccessType writeAccess = isReadStatic ? (IndexAccessType)access : INDEXACCESS_STATIC;
1179 const char* writeAccessName = getIndexAccessTypeName(writeAccess);
1180 const char* readAccessName = getIndexAccessTypeName(readAccess);
1182 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1184 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1185 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType);
1186 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" +
1187 readAccessName + "_read_" + shaderTypeName;
1188 string desc = string("Temporary array with ") + writeAccessName + " write and " +
1189 readAccessName + " read in " + shaderTypeName + " shader.";
1190 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1191 tmpGroup->addChild(createTmpArrayCase(m_context, name.c_str(), desc.c_str(), m_glslVersion,
1192 isVertexCase, varType, (IndexAccessType)writeAccess,
1193 (IndexAccessType)readAccess));
1200 // Vector indexing with subscripts.
1202 TestCaseGroup* vecGroup = new TestCaseGroup(m_context, "vector_subscript", "Vector subscript indexing.");
1205 static const DataType s_vectorTypes[] = { TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4 };
1207 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_vectorTypes); typeNdx++)
1209 DataType varType = s_vectorTypes[typeNdx];
1210 for (int isReadDirect = 0; isReadDirect < 2; isReadDirect++)
1212 for (int access = SUBSCRIPT_STATIC; access < VECTORACCESS_LAST; access++)
1214 VectorAccessType readAccess = isReadDirect ? DIRECT : (VectorAccessType)access;
1215 VectorAccessType writeAccess = isReadDirect ? (VectorAccessType)access : DIRECT;
1217 const char* writeAccessName = getVectorAccessTypeName(writeAccess);
1218 const char* readAccessName = getVectorAccessTypeName(readAccess);
1220 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1222 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1223 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType);
1224 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" +
1225 readAccessName + "_read_" + shaderTypeName;
1226 string desc = string("Vector subscript access with ") + writeAccessName + " write and " +
1227 readAccessName + " read in " + shaderTypeName + " shader.";
1228 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1229 vecGroup->addChild(createVectorSubscriptCase(
1230 m_context, name.c_str(), desc.c_str(), m_glslVersion, isVertexCase, varType,
1231 (VectorAccessType)writeAccess, (VectorAccessType)readAccess));
1238 // Matrix indexing with subscripts.
1240 TestCaseGroup* matGroup = new TestCaseGroup(m_context, "matrix_subscript", "Matrix subscript indexing.");
1243 static const DataType s_matrixTypes[] = { TYPE_FLOAT_MAT2, TYPE_FLOAT_MAT2X3, TYPE_FLOAT_MAT2X4,
1244 TYPE_FLOAT_MAT3X2, TYPE_FLOAT_MAT3, TYPE_FLOAT_MAT3X4,
1245 TYPE_FLOAT_MAT4X2, TYPE_FLOAT_MAT4X3, TYPE_FLOAT_MAT4 };
1247 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_matrixTypes); typeNdx++)
1249 DataType varType = s_matrixTypes[typeNdx];
1250 for (int isReadStatic = 0; isReadStatic < 2; isReadStatic++)
1252 for (int access = INDEXACCESS_STATIC + 1; access < INDEXACCESS_LAST; access++)
1254 IndexAccessType readAccess = isReadStatic ? INDEXACCESS_STATIC : (IndexAccessType)access;
1255 IndexAccessType writeAccess = isReadStatic ? (IndexAccessType)access : INDEXACCESS_STATIC;
1257 const char* writeAccessName = getIndexAccessTypeName(writeAccess);
1258 const char* readAccessName = getIndexAccessTypeName(readAccess);
1260 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
1262 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
1263 const char* shaderTypeName = getShaderTypeName((ShaderType)shaderType);
1264 string name = string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" +
1265 readAccessName + "_read_" + shaderTypeName;
1266 string desc = string("Vector subscript access with ") + writeAccessName + " write and " +
1267 readAccessName + " read in " + shaderTypeName + " shader.";
1268 bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
1269 matGroup->addChild(createMatrixSubscriptCase(
1270 m_context, name.c_str(), desc.c_str(), m_glslVersion, isVertexCase, varType,
1271 (IndexAccessType)writeAccess, (IndexAccessType)readAccess));