1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2016 Google Inc. 6 * Copyright (c) 2016 The Khronos Group Inc. 7 * 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 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 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. 19 * 20 */ /*! 21 * \file 22 * \brief Shader struct tests. 23 */ /*-------------------------------------------------------------------*/ 24 25#include "glcShaderStructTests.hpp" 26#include "glcShaderRenderCase.hpp" 27#include "gluTexture.hpp" 28#include "glwEnums.hpp" 29#include "glwFunctions.hpp" 30#include "tcuStringTemplate.hpp" 31#include "tcuTextureUtil.hpp" 32#include "deMath.h" 33 34using tcu::StringTemplate; 35 36using std::string; 37using std::vector; 38using std::ostringstream; 39 40using namespace glu; 41 42namespace deqp 43{ 44 45enum 46{ 47 TEXTURE_GRADIENT = 0 //!< Unit index for gradient texture 48}; 49 50typedef void (*SetupUniformsFunc)(const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords); 51 52class ShaderStructCase : public ShaderRenderCase 53{ 54public: 55 ShaderStructCase(Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, 56 ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, 57 const char* fragShaderSource); 58 ~ShaderStructCase(void); 59 60 void init(void); 61 void deinit(void); 62 63 virtual void setupUniforms(deUint32 programID, const tcu::Vec4& constCoords); 64 65private: 66 ShaderStructCase(const ShaderStructCase&); 67 ShaderStructCase& operator=(const ShaderStructCase&); 68 69 SetupUniformsFunc m_setupUniforms; 70 bool m_usesTexture; 71 72 glu::Texture2D* m_gradientTexture; 73}; 74 75ShaderStructCase::ShaderStructCase(Context& context, const char* name, const char* description, bool isVertexCase, 76 bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, 77 const char* vertShaderSource, const char* fragShaderSource) 78 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, 79 description, isVertexCase, evalFunc) 80 , m_setupUniforms(setupUniformsFunc) 81 , m_usesTexture(usesTextures) 82 , m_gradientTexture(DE_NULL) 83{ 84 m_vertShaderSource = vertShaderSource; 85 m_fragShaderSource = fragShaderSource; 86} 87 88ShaderStructCase::~ShaderStructCase(void) 89{ 90} 91 92void ShaderStructCase::init(void) 93{ 94 if (m_usesTexture) 95 { 96 m_gradientTexture = new glu::Texture2D(m_renderCtx, GL_RGBA8, 128, 128); 97 98 m_gradientTexture->getRefTexture().allocLevel(0); 99 tcu::fillWithComponentGradients(m_gradientTexture->getRefTexture().getLevel(0), tcu::Vec4(0.0f), 100 tcu::Vec4(1.0f)); 101 m_gradientTexture->upload(); 102 103 m_textures.push_back(TextureBinding( 104 m_gradientTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 105 tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR))); 106 DE_ASSERT(m_textures.size() == 1); 107 } 108 ShaderRenderCase::init(); 109} 110 111void ShaderStructCase::deinit(void) 112{ 113 if (m_usesTexture) 114 { 115 delete m_gradientTexture; 116 } 117 ShaderRenderCase::deinit(); 118} 119 120void ShaderStructCase::setupUniforms(deUint32 programID, const tcu::Vec4& constCoords) 121{ 122 ShaderRenderCase::setupUniforms(programID, constCoords); 123 if (m_setupUniforms) 124 m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords); 125} 126 127static ShaderStructCase* createStructCase(Context& context, const char* name, const char* description, 128 glu::GLSLVersion glslVersion, bool isVertexCase, bool usesTextures, 129 ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, 130 const LineStream& shaderSrc) 131{ 132 const std::string versionDecl = glu::getGLSLVersionDeclaration(glslVersion); 133 134 const std::string defaultVertSrc = versionDecl + "\n" 135 "in highp vec4 a_position;\n" 136 "in highp vec4 a_coords;\n" 137 "out mediump vec4 v_coords;\n\n" 138 "void main (void)\n" 139 "{\n" 140 " v_coords = a_coords;\n" 141 " gl_Position = a_position;\n" 142 "}\n"; 143 const std::string defaultFragSrc = versionDecl + "\n" 144 "in mediump vec4 v_color;\n" 145 "layout(location = 0) out mediump vec4 o_color;\n\n" 146 "void main (void)\n" 147 "{\n" 148 " o_color = v_color;\n" 149 "}\n"; 150 151 // Fill in specialization parameters. 152 std::map<std::string, std::string> spParams; 153 if (isVertexCase) 154 { 155 spParams["HEADER"] = versionDecl + "\n" 156 "in highp vec4 a_position;\n" 157 "in highp vec4 a_coords;\n" 158 "out mediump vec4 v_color;"; 159 spParams["COORDS"] = "a_coords"; 160 spParams["DST"] = "v_color"; 161 spParams["ASSIGN_POS"] = "gl_Position = a_position;"; 162 } 163 else 164 { 165 spParams["HEADER"] = versionDecl + "\n" 166 "in mediump vec4 v_coords;\n" 167 "layout(location = 0) out mediump vec4 o_color;"; 168 spParams["COORDS"] = "v_coords"; 169 spParams["DST"] = "o_color"; 170 spParams["ASSIGN_POS"] = ""; 171 } 172 173 if (isVertexCase) 174 return new ShaderStructCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, 175 StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), 176 defaultFragSrc.c_str()); 177 else 178 return new ShaderStructCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, 179 defaultVertSrc.c_str(), 180 StringTemplate(shaderSrc.str()).specialize(spParams).c_str()); 181} 182 183class LocalStructTests : public TestCaseGroup 184{ 185public: 186 LocalStructTests(Context& context, glu::GLSLVersion glslVersion) 187 : TestCaseGroup(context, "local", "Local structs"), m_glslVersion(glslVersion) 188 { 189 } 190 191 ~LocalStructTests(void) 192 { 193 } 194 195 virtual void init(void); 196 197private: 198 glu::GLSLVersion m_glslVersion; 199}; 200 201void LocalStructTests::init(void) 202{ 203#define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \ 204 do \ 205 { \ 206 struct Eval_##NAME \ 207 { \ 208 static void eval(ShaderEvalContext& c) EVAL_FUNC_BODY \ 209 }; \ 210 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, false, \ 211 &Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \ 212 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, false, \ 213 &Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \ 214 } while (deGetFalse()) 215 216 LOCAL_STRUCT_CASE(basic, "Basic struct usage", 217 LineStream() << "${HEADER}" 218 << "uniform int ui_one;" 219 << "" 220 << "struct S {" 221 << " mediump float a;" 222 << " mediump vec3 b;" 223 << " int c;" 224 << "};" 225 << "" 226 << "void main (void)" 227 << "{" 228 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);" 229 << " s.b = ${COORDS}.yzw;" 230 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);" 231 << " ${ASSIGN_POS}" 232 << "}", 233 { c.color.xyz() = c.coords.swizzle(0, 1, 2); }); 234 235 LOCAL_STRUCT_CASE(nested, "Nested struct", 236 LineStream() << "${HEADER}" 237 << "uniform int ui_zero;" 238 << "uniform int ui_one;" 239 << "" 240 << "struct T {" 241 << " int a;" 242 << " mediump vec2 b;" 243 << "};" 244 << "struct S {" 245 << " mediump float a;" 246 << " T b;" 247 << " int c;" 248 << "};" 249 << "" 250 << "void main (void)" 251 << "{" 252 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);" 253 << " s.b = T(ui_zero, ${COORDS}.yz);" 254 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);" 255 << " ${ASSIGN_POS}" 256 << "}", 257 { c.color.xyz() = c.coords.swizzle(0, 1, 2); }); 258 259 LOCAL_STRUCT_CASE(array_member, "Struct with array member", 260 LineStream() << "${HEADER}" 261 << "uniform int ui_one;" 262 << "" 263 << "struct S {" 264 << " mediump float a;" 265 << " mediump float b[3];" 266 << " int c;" 267 << "};" 268 << "" 269 << "void main (void)" 270 << "{" 271 << " S s;" 272 << " s.a = ${COORDS}.w;" 273 << " s.c = ui_one;" 274 << " s.b[0] = ${COORDS}.z;" 275 << " s.b[1] = ${COORDS}.y;" 276 << " s.b[2] = ${COORDS}.x;" 277 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);" 278 << " ${ASSIGN_POS}" 279 << "}", 280 { c.color.xyz() = c.coords.swizzle(3, 2, 1); }); 281 282 LOCAL_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing", 283 LineStream() << "${HEADER}" 284 << "uniform int ui_zero;" 285 << "uniform int ui_one;" 286 << "uniform int ui_two;" 287 << "" 288 << "struct S {" 289 << " mediump float a;" 290 << " mediump float b[3];" 291 << " int c;" 292 << "};" 293 << "" 294 << "void main (void)" 295 << "{" 296 << " S s;" 297 << " s.a = ${COORDS}.w;" 298 << " s.c = ui_one;" 299 << " s.b[0] = ${COORDS}.z;" 300 << " s.b[1] = ${COORDS}.y;" 301 << " s.b[2] = ${COORDS}.x;" 302 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);" 303 << " ${ASSIGN_POS}" 304 << "}", 305 { c.color.xyz() = c.coords.swizzle(1, 2, 0); }); 306 307 LOCAL_STRUCT_CASE(struct_array, "Struct array", 308 LineStream() << "${HEADER}" 309 << "uniform int ui_zero;" 310 << "uniform int ui_one;" 311 << "uniform int ui_two;" 312 << "" 313 << "struct S {" 314 << " mediump float a;" 315 << " mediump int b;" 316 << "};" 317 << "" 318 << "void main (void)" 319 << "{" 320 << " S s[3];" 321 << " s[0] = S(${COORDS}.x, ui_zero);" 322 << " s[1].a = ${COORDS}.y;" 323 << " s[1].b = ui_one;" 324 << " s[2] = S(${COORDS}.z, ui_two);" 325 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);" 326 << " ${ASSIGN_POS}" 327 << "}", 328 { c.color.xyz() = c.coords.swizzle(2, 1, 0); }); 329 330 LOCAL_STRUCT_CASE( 331 struct_array_dynamic_index, "Struct array with dynamic indexing", 332 LineStream() 333 << "${HEADER}" 334 << "uniform int ui_zero;" 335 << "uniform int ui_one;" 336 << "uniform int ui_two;" 337 << "" 338 << "struct S {" 339 << " mediump float a;" 340 << " mediump int b;" 341 << "};" 342 << "" 343 << "void main (void)" 344 << "{" 345 << " S s[3];" 346 << " s[0] = S(${COORDS}.x, ui_zero);" 347 << " s[1].a = ${COORDS}.y;" 348 << " s[1].b = ui_one;" 349 << " s[2] = S(${COORDS}.z, ui_two);" 350 << " ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);" 351 << " ${ASSIGN_POS}" 352 << "}", 353 { c.color.xyz() = c.coords.swizzle(2, 1, 0); }); 354 355 LOCAL_STRUCT_CASE( 356 nested_struct_array, "Nested struct array", 357 LineStream() << "${HEADER}" 358 << "uniform int ui_zero;" 359 << "uniform int ui_one;" 360 << "uniform int ui_two;" 361 << "uniform mediump float uf_two;" 362 << "uniform mediump float uf_three;" 363 << "uniform mediump float uf_four;" 364 << "uniform mediump float uf_half;" 365 << "uniform mediump float uf_third;" 366 << "uniform mediump float uf_fourth;" 367 << "" 368 << "struct T {" 369 << " mediump float a;" 370 << " mediump vec2 b[2];" 371 << "};" 372 << "struct S {" 373 << " mediump float a;" 374 << " T b[3];" 375 << " int c;" 376 << "};" 377 << "" 378 << "void main (void)" 379 << "{" 380 << " S s[2];" 381 << "" 382 << " // S[0]" 383 << " s[0].a = ${COORDS}.x;" 384 << " s[0].b[0].a = uf_half;" 385 << " s[0].b[0].b[0] = ${COORDS}.xy;" 386 << " s[0].b[0].b[1] = ${COORDS}.zw;" 387 << " s[0].b[1].a = uf_third;" 388 << " s[0].b[1].b[0] = ${COORDS}.zw;" 389 << " s[0].b[1].b[1] = ${COORDS}.xy;" 390 << " s[0].b[2].a = uf_fourth;" 391 << " s[0].b[2].b[0] = ${COORDS}.xz;" 392 << " s[0].b[2].b[1] = ${COORDS}.yw;" 393 << " s[0].c = ui_zero;" 394 << "" 395 << " // S[1]" 396 << " s[1].a = ${COORDS}.w;" 397 << " s[1].b[0].a = uf_two;" 398 << " s[1].b[0].b[0] = ${COORDS}.xx;" 399 << " s[1].b[0].b[1] = ${COORDS}.yy;" 400 << " s[1].b[1].a = uf_three;" 401 << " s[1].b[1].b[0] = ${COORDS}.zz;" 402 << " s[1].b[1].b[1] = ${COORDS}.ww;" 403 << " s[1].b[2].a = uf_four;" 404 << " s[1].b[2].b[0] = ${COORDS}.yx;" 405 << " s[1].b[2].b[1] = ${COORDS}.wz;" 406 << " s[1].c = ui_one;" 407 << "" 408 << " mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5" 409 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4" 410 << " mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w " 411 "+ w) * 0.333" 412 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0" 413 << " ${DST} = vec4(r, g, b, a);" 414 << " ${ASSIGN_POS}" 415 << "}", 416 { c.color.xyz() = c.coords.swizzle(2, 0, 3); }); 417 418 LOCAL_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing", 419 LineStream() << "${HEADER}" 420 << "uniform int ui_zero;" 421 << "uniform int ui_one;" 422 << "uniform int ui_two;" 423 << "uniform mediump float uf_two;" 424 << "uniform mediump float uf_three;" 425 << "uniform mediump float uf_four;" 426 << "uniform mediump float uf_half;" 427 << "uniform mediump float uf_third;" 428 << "uniform mediump float uf_fourth;" 429 << "" 430 << "struct T {" 431 << " mediump float a;" 432 << " mediump vec2 b[2];" 433 << "};" 434 << "struct S {" 435 << " mediump float a;" 436 << " T b[3];" 437 << " int c;" 438 << "};" 439 << "" 440 << "void main (void)" 441 << "{" 442 << " S s[2];" 443 << "" 444 << " // S[0]" 445 << " s[0].a = ${COORDS}.x;" 446 << " s[0].b[0].a = uf_half;" 447 << " s[0].b[0].b[0] = ${COORDS}.xy;" 448 << " s[0].b[0].b[1] = ${COORDS}.zw;" 449 << " s[0].b[1].a = uf_third;" 450 << " s[0].b[1].b[0] = ${COORDS}.zw;" 451 << " s[0].b[1].b[1] = ${COORDS}.xy;" 452 << " s[0].b[2].a = uf_fourth;" 453 << " s[0].b[2].b[0] = ${COORDS}.xz;" 454 << " s[0].b[2].b[1] = ${COORDS}.yw;" 455 << " s[0].c = ui_zero;" 456 << "" 457 << " // S[1]" 458 << " s[1].a = ${COORDS}.w;" 459 << " s[1].b[0].a = uf_two;" 460 << " s[1].b[0].b[0] = ${COORDS}.xx;" 461 << " s[1].b[0].b[1] = ${COORDS}.yy;" 462 << " s[1].b[1].a = uf_three;" 463 << " s[1].b[1].b[0] = ${COORDS}.zz;" 464 << " s[1].b[1].b[1] = ${COORDS}.ww;" 465 << " s[1].b[2].a = uf_four;" 466 << " s[1].b[2].b[0] = ${COORDS}.yx;" 467 << " s[1].b[2].b[1] = ${COORDS}.wz;" 468 << " s[1].c = ui_one;" 469 << "" 470 << " mediump float r = (s[0].b[ui_one].b[ui_one-1].x + " 471 "s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5" 472 << " mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a * " 473 "s[ui_one].b[2].a; // x * 0.25 * 4" 474 << " mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + " 475 "s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w + " 476 "w + w) * 0.333" 477 << " mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - " 478 "s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0" 479 << " ${DST} = vec4(r, g, b, a);" 480 << " ${ASSIGN_POS}" 481 << "}", 482 { c.color.xyz() = c.coords.swizzle(2, 0, 3); }); 483 484 LOCAL_STRUCT_CASE(parameter, "Struct as a function parameter", 485 LineStream() << "${HEADER}" 486 << "uniform int ui_one;" 487 << "" 488 << "struct S {" 489 << " mediump float a;" 490 << " mediump vec3 b;" 491 << " int c;" 492 << "};" 493 << "" 494 << "mediump vec4 myFunc (S s)" 495 << "{" 496 << " return vec4(s.a, s.b.x, s.b.y, s.c);" 497 << "}" 498 << "" 499 << "void main (void)" 500 << "{" 501 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);" 502 << " s.b = ${COORDS}.yzw;" 503 << " ${DST} = myFunc(s);" 504 << " ${ASSIGN_POS}" 505 << "}", 506 { c.color.xyz() = c.coords.swizzle(0, 1, 2); }); 507 508 LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter", 509 LineStream() << "${HEADER}" 510 << "uniform int ui_zero;" 511 << "uniform int ui_one;" 512 << "" 513 << "struct T {" 514 << " int a;" 515 << " mediump vec2 b;" 516 << "};" 517 << "struct S {" 518 << " mediump float a;" 519 << " T b;" 520 << " int c;" 521 << "};" 522 << "" 523 << "mediump vec4 myFunc (S s)" 524 << "{" 525 << " return vec4(s.a, s.b.b, s.b.a + s.c);" 526 << "}" 527 << "" 528 << "void main (void)" 529 << "{" 530 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);" 531 << " s.b = T(ui_zero, ${COORDS}.yz);" 532 << " ${DST} = myFunc(s);" 533 << " ${ASSIGN_POS}" 534 << "}", 535 { c.color.xyz() = c.coords.swizzle(0, 1, 2); }); 536 537 LOCAL_STRUCT_CASE(return, "Struct as a return value", 538 LineStream() << "${HEADER}" 539 << "uniform int ui_one;" 540 << "" 541 << "struct S {" 542 << " mediump float a;" 543 << " mediump vec3 b;" 544 << " int c;" 545 << "};" 546 << "" 547 << "S myFunc (void)" 548 << "{" 549 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);" 550 << " s.b = ${COORDS}.yzw;" 551 << " return s;" 552 << "}" 553 << "" 554 << "void main (void)" 555 << "{" 556 << " S s = myFunc();" 557 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);" 558 << " ${ASSIGN_POS}" 559 << "}", 560 { c.color.xyz() = c.coords.swizzle(0, 1, 2); }); 561 562 LOCAL_STRUCT_CASE(return_nested, "Nested struct", 563 LineStream() << "${HEADER}" 564 << "uniform int ui_zero;" 565 << "uniform int ui_one;" 566 << "" 567 << "struct T {" 568 << " int a;" 569 << " mediump vec2 b;" 570 << "};" 571 << "struct S {" 572 << " mediump float a;" 573 << " T b;" 574 << " int c;" 575 << "};" 576 << "" 577 << "S myFunc (void)" 578 << "{" 579 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);" 580 << " s.b = T(ui_zero, ${COORDS}.yz);" 581 << " return s;" 582 << "}" 583 << "" 584 << "void main (void)" 585 << "{" 586 << " S s = myFunc();" 587 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);" 588 << " ${ASSIGN_POS}" 589 << "}", 590 { c.color.xyz() = c.coords.swizzle(0, 1, 2); }); 591 592 LOCAL_STRUCT_CASE(conditional_assignment, "Conditional struct assignment", 593 LineStream() << "${HEADER}" 594 << "uniform int ui_zero;" 595 << "uniform int ui_one;" 596 << "uniform mediump float uf_one;" 597 << "" 598 << "struct S {" 599 << " mediump float a;" 600 << " mediump vec3 b;" 601 << " int c;" 602 << "};" 603 << "" 604 << "void main (void)" 605 << "{" 606 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);" 607 << " if (uf_one > 0.0)" 608 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);" 609 << " ${DST} = vec4(s.a, s.b.xy, s.c);" 610 << " ${ASSIGN_POS}" 611 << "}", 612 { c.color.xyz() = c.coords.swizzle(3, 2, 1); }); 613 614 LOCAL_STRUCT_CASE(loop_assignment, "Struct assignment in loop", 615 LineStream() << "${HEADER}" 616 << "uniform int ui_zero;" 617 << "uniform int ui_one;" 618 << "" 619 << "struct S {" 620 << " mediump float a;" 621 << " mediump vec3 b;" 622 << " int c;" 623 << "};" 624 << "" 625 << "void main (void)" 626 << "{" 627 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);" 628 << " for (int i = 0; i < 3; i++)" 629 << " {" 630 << " if (i == 1)" 631 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);" 632 << " }" 633 << " ${DST} = vec4(s.a, s.b.xy, s.c);" 634 << " ${ASSIGN_POS}" 635 << "}", 636 { c.color.xyz() = c.coords.swizzle(3, 2, 1); }); 637 638 LOCAL_STRUCT_CASE(dynamic_loop_assignment, "Struct assignment in loop", 639 LineStream() << "${HEADER}" 640 << "uniform int ui_zero;" 641 << "uniform int ui_one;" 642 << "uniform int ui_three;" 643 << "" 644 << "struct S {" 645 << " mediump float a;" 646 << " mediump vec3 b;" 647 << " int c;" 648 << "};" 649 << "" 650 << "void main (void)" 651 << "{" 652 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);" 653 << " for (int i = 0; i < ui_three; i++)" 654 << " {" 655 << " if (i == ui_one)" 656 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);" 657 << " }" 658 << " ${DST} = vec4(s.a, s.b.xy, s.c);" 659 << " ${ASSIGN_POS}" 660 << "}", 661 { c.color.xyz() = c.coords.swizzle(3, 2, 1); }); 662 663 LOCAL_STRUCT_CASE(nested_conditional_assignment, "Conditional assignment of nested struct", 664 LineStream() << "${HEADER}" 665 << "uniform int ui_zero;" 666 << "uniform int ui_one;" 667 << "uniform mediump float uf_one;" 668 << "" 669 << "struct T {" 670 << " int a;" 671 << " mediump vec2 b;" 672 << "};" 673 << "struct S {" 674 << " mediump float a;" 675 << " T b;" 676 << " int c;" 677 << "};" 678 << "" 679 << "void main (void)" 680 << "{" 681 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);" 682 << " if (uf_one > 0.0)" 683 << " s.b = T(ui_zero, ${COORDS}.zw);" 684 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);" 685 << " ${ASSIGN_POS}" 686 << "}", 687 { c.color.xyz() = c.coords.swizzle(0, 2, 3); }); 688 689 LOCAL_STRUCT_CASE(nested_loop_assignment, "Nested struct assignment in loop", 690 LineStream() << "${HEADER}" 691 << "uniform int ui_zero;" 692 << "uniform int ui_one;" 693 << "uniform mediump float uf_one;" 694 << "" 695 << "struct T {" 696 << " int a;" 697 << " mediump vec2 b;" 698 << "};" 699 << "struct S {" 700 << " mediump float a;" 701 << " T b;" 702 << " int c;" 703 << "};" 704 << "" 705 << "void main (void)" 706 << "{" 707 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);" 708 << " for (int i = 0; i < 3; i++)" 709 << " {" 710 << " if (i == 1)" 711 << " s.b = T(ui_zero, ${COORDS}.zw);" 712 << " }" 713 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);" 714 << " ${ASSIGN_POS}" 715 << "}", 716 { c.color.xyz() = c.coords.swizzle(0, 2, 3); }); 717 718 LOCAL_STRUCT_CASE(nested_dynamic_loop_assignment, "Nested struct assignment in dynamic loop", 719 LineStream() << "${HEADER}" 720 << "uniform int ui_zero;" 721 << "uniform int ui_one;" 722 << "uniform int ui_three;" 723 << "uniform mediump float uf_one;" 724 << "" 725 << "struct T {" 726 << " int a;" 727 << " mediump vec2 b;" 728 << "};" 729 << "struct S {" 730 << " mediump float a;" 731 << " T b;" 732 << " int c;" 733 << "};" 734 << "" 735 << "void main (void)" 736 << "{" 737 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);" 738 << " for (int i = 0; i < ui_three; i++)" 739 << " {" 740 << " if (i == ui_one)" 741 << " s.b = T(ui_zero, ${COORDS}.zw);" 742 << " }" 743 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);" 744 << " ${ASSIGN_POS}" 745 << "}", 746 { c.color.xyz() = c.coords.swizzle(0, 2, 3); }); 747 748 LOCAL_STRUCT_CASE(loop_struct_array, "Struct array usage in loop", 749 LineStream() << "${HEADER}" 750 << "uniform int ui_zero;" 751 << "uniform int ui_one;" 752 << "uniform int ui_two;" 753 << "" 754 << "struct S {" 755 << " mediump float a;" 756 << " mediump int b;" 757 << "};" 758 << "" 759 << "void main (void)" 760 << "{" 761 << " S s[3];" 762 << " s[0] = S(${COORDS}.x, ui_zero);" 763 << " s[1].a = ${COORDS}.y;" 764 << " s[1].b = -ui_one;" 765 << " s[2] = S(${COORDS}.z, ui_two);" 766 << "" 767 << " mediump float rgb[3];" 768 << " int alpha = 0;" 769 << " for (int i = 0; i < 3; i++)" 770 << " {" 771 << " rgb[i] = s[2-i].a;" 772 << " alpha += s[i].b;" 773 << " }" 774 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);" 775 << " ${ASSIGN_POS}" 776 << "}", 777 { c.color.xyz() = c.coords.swizzle(2, 1, 0); }); 778 779 LOCAL_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop", 780 LineStream() << "${HEADER}" 781 << "uniform int ui_zero;" 782 << "uniform int ui_one;" 783 << "uniform int ui_two;" 784 << "uniform mediump float uf_two;" 785 << "uniform mediump float uf_three;" 786 << "uniform mediump float uf_four;" 787 << "uniform mediump float uf_half;" 788 << "uniform mediump float uf_third;" 789 << "uniform mediump float uf_fourth;" 790 << "uniform mediump float uf_sixth;" 791 << "" 792 << "struct T {" 793 << " mediump float a;" 794 << " mediump vec2 b[2];" 795 << "};" 796 << "struct S {" 797 << " mediump float a;" 798 << " T b[3];" 799 << " int c;" 800 << "};" 801 << "" 802 << "void main (void)" 803 << "{" 804 << " S s[2];" 805 << "" 806 << " // S[0]" 807 << " s[0].a = ${COORDS}.x;" 808 << " s[0].b[0].a = uf_half;" 809 << " s[0].b[0].b[0] = ${COORDS}.yx;" 810 << " s[0].b[0].b[1] = ${COORDS}.zx;" 811 << " s[0].b[1].a = uf_third;" 812 << " s[0].b[1].b[0] = ${COORDS}.yy;" 813 << " s[0].b[1].b[1] = ${COORDS}.wy;" 814 << " s[0].b[2].a = uf_fourth;" 815 << " s[0].b[2].b[0] = ${COORDS}.zx;" 816 << " s[0].b[2].b[1] = ${COORDS}.zy;" 817 << " s[0].c = ui_zero;" 818 << "" 819 << " // S[1]" 820 << " s[1].a = ${COORDS}.w;" 821 << " s[1].b[0].a = uf_two;" 822 << " s[1].b[0].b[0] = ${COORDS}.zx;" 823 << " s[1].b[0].b[1] = ${COORDS}.zy;" 824 << " s[1].b[1].a = uf_three;" 825 << " s[1].b[1].b[0] = ${COORDS}.zz;" 826 << " s[1].b[1].b[1] = ${COORDS}.ww;" 827 << " s[1].b[2].a = uf_four;" 828 << " s[1].b[2].b[0] = ${COORDS}.yx;" 829 << " s[1].b[2].b[1] = ${COORDS}.wz;" 830 << " s[1].c = ui_one;" 831 << "" 832 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0" 833 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0" 834 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0" 835 << " mediump float a = 1.0;" 836 << " for (int i = 0; i < 2; i++)" 837 << " {" 838 << " for (int j = 0; j < 3; j++)" 839 << " {" 840 << " r += s[0].b[j].b[i].y;" 841 << " g += s[i].b[j].b[0].x;" 842 << " b += s[i].b[j].b[1].x;" 843 << " a *= s[i].b[j].a;" 844 << " }" 845 << " }" 846 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);" 847 << " ${ASSIGN_POS}" 848 << "}", 849 { c.color.xyz() = (c.coords.swizzle(0, 1, 2) + c.coords.swizzle(1, 2, 3)) * 0.5f; }); 850 851 LOCAL_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop", 852 LineStream() << "${HEADER}" 853 << "uniform int ui_zero;" 854 << "uniform int ui_one;" 855 << "uniform int ui_two;" 856 << "uniform int ui_three;" 857 << "" 858 << "struct S {" 859 << " mediump float a;" 860 << " mediump int b;" 861 << "};" 862 << "" 863 << "void main (void)" 864 << "{" 865 << " S s[3];" 866 << " s[0] = S(${COORDS}.x, ui_zero);" 867 << " s[1].a = ${COORDS}.y;" 868 << " s[1].b = -ui_one;" 869 << " s[2] = S(${COORDS}.z, ui_two);" 870 << "" 871 << " mediump float rgb[3];" 872 << " int alpha = 0;" 873 << " for (int i = 0; i < ui_three; i++)" 874 << " {" 875 << " rgb[i] = s[2-i].a;" 876 << " alpha += s[i].b;" 877 << " }" 878 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);" 879 << " ${ASSIGN_POS}" 880 << "}", 881 { c.color.xyz() = c.coords.swizzle(2, 1, 0); }); 882 883 LOCAL_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop", 884 LineStream() << "${HEADER}" 885 << "uniform int ui_zero;" 886 << "uniform int ui_one;" 887 << "uniform int ui_two;" 888 << "uniform int ui_three;" 889 << "uniform mediump float uf_two;" 890 << "uniform mediump float uf_three;" 891 << "uniform mediump float uf_four;" 892 << "uniform mediump float uf_half;" 893 << "uniform mediump float uf_third;" 894 << "uniform mediump float uf_fourth;" 895 << "uniform mediump float uf_sixth;" 896 << "" 897 << "struct T {" 898 << " mediump float a;" 899 << " mediump vec2 b[2];" 900 << "};" 901 << "struct S {" 902 << " mediump float a;" 903 << " T b[3];" 904 << " int c;" 905 << "};" 906 << "" 907 << "void main (void)" 908 << "{" 909 << " S s[2];" 910 << "" 911 << " // S[0]" 912 << " s[0].a = ${COORDS}.x;" 913 << " s[0].b[0].a = uf_half;" 914 << " s[0].b[0].b[0] = ${COORDS}.yx;" 915 << " s[0].b[0].b[1] = ${COORDS}.zx;" 916 << " s[0].b[1].a = uf_third;" 917 << " s[0].b[1].b[0] = ${COORDS}.yy;" 918 << " s[0].b[1].b[1] = ${COORDS}.wy;" 919 << " s[0].b[2].a = uf_fourth;" 920 << " s[0].b[2].b[0] = ${COORDS}.zx;" 921 << " s[0].b[2].b[1] = ${COORDS}.zy;" 922 << " s[0].c = ui_zero;" 923 << "" 924 << " // S[1]" 925 << " s[1].a = ${COORDS}.w;" 926 << " s[1].b[0].a = uf_two;" 927 << " s[1].b[0].b[0] = ${COORDS}.zx;" 928 << " s[1].b[0].b[1] = ${COORDS}.zy;" 929 << " s[1].b[1].a = uf_three;" 930 << " s[1].b[1].b[0] = ${COORDS}.zz;" 931 << " s[1].b[1].b[1] = ${COORDS}.ww;" 932 << " s[1].b[2].a = uf_four;" 933 << " s[1].b[2].b[0] = ${COORDS}.yx;" 934 << " s[1].b[2].b[1] = ${COORDS}.wz;" 935 << " s[1].c = ui_one;" 936 << "" 937 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0" 938 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0" 939 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0" 940 << " mediump float a = 1.0;" 941 << " for (int i = 0; i < ui_two; i++)" 942 << " {" 943 << " for (int j = 0; j < ui_three; j++)" 944 << " {" 945 << " r += s[0].b[j].b[i].y;" 946 << " g += s[i].b[j].b[0].x;" 947 << " b += s[i].b[j].b[1].x;" 948 << " a *= s[i].b[j].a;" 949 << " }" 950 << " }" 951 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);" 952 << " ${ASSIGN_POS}" 953 << "}", 954 { c.color.xyz() = (c.coords.swizzle(0, 1, 2) + c.coords.swizzle(1, 2, 3)) * 0.5f; }); 955 956 LOCAL_STRUCT_CASE(basic_equal, "Basic struct equality", 957 LineStream() 958 << "${HEADER}" 959 << "uniform int ui_one;" 960 << "uniform int ui_two;" 961 << "" 962 << "struct S {" 963 << " mediump float a;" 964 << " mediump vec3 b;" 965 << " int c;" 966 << "};" 967 << "" 968 << "void main (void)" 969 << "{" 970 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);" 971 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);" 972 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);" 973 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);" 974 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" 975 << " if (a == b) ${DST}.x = 1.0;" 976 << " if (a == c) ${DST}.y = 1.0;" 977 << " if (a == d) ${DST}.z = 1.0;" 978 << " ${ASSIGN_POS}" 979 << "}", 980 { 981 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0]+0.5f)) 982 c.color.x() = 1.0f; 983 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1]+0.5f)) 984 c.color.y() = 1.0f; 985 }); 986 987 LOCAL_STRUCT_CASE(basic_not_equal, "Basic struct equality", 988 LineStream() 989 << "${HEADER}" 990 << "uniform int ui_one;" 991 << "uniform int ui_two;" 992 << "" 993 << "struct S {" 994 << " mediump float a;" 995 << " mediump vec3 b;" 996 << " int c;" 997 << "};" 998 << "" 999 << "void main (void)" 1000 << "{" 1001 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);" 1002 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);" 1003 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);" 1004 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);" 1005 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" 1006 << " if (a != b) ${DST}.x = 1.0;" 1007 << " if (a != c) ${DST}.y = 1.0;" 1008 << " if (a != d) ${DST}.z = 1.0;" 1009 << " ${ASSIGN_POS}" 1010 << "}", 1011 { 1012 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0]+0.5f)) 1013 c.color.x() = 1.0f; 1014 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1]+0.5f)) 1015 c.color.y() = 1.0f; 1016 c.color.z() = 1.0f; 1017 }); 1018 1019 LOCAL_STRUCT_CASE(nested_equal, "Nested struct struct equality", 1020 LineStream() 1021 << "${HEADER}" 1022 << "uniform int ui_one;" 1023 << "uniform int ui_two;" 1024 << "" 1025 << "struct T {" 1026 << " mediump vec3 a;" 1027 << " int b;" 1028 << "};" 1029 << "struct S {" 1030 << " mediump float a;" 1031 << " T b;" 1032 << " int c;" 1033 << "};" 1034 << "" 1035 << "void main (void)" 1036 << "{" 1037 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);" 1038 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);" 1039 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);" 1040 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);" 1041 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" 1042 << " if (a == b) ${DST}.x = 1.0;" 1043 << " if (a == c) ${DST}.y = 1.0;" 1044 << " if (a == d) ${DST}.z = 1.0;" 1045 << " ${ASSIGN_POS}" 1046 << "}", 1047 { 1048 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0]+0.5f)) 1049 c.color.x() = 1.0f; 1050 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1]+0.5f)) 1051 c.color.y() = 1.0f; 1052 }); 1053 1054 LOCAL_STRUCT_CASE(nested_not_equal, "Nested struct struct equality", 1055 LineStream() 1056 << "${HEADER}" 1057 << "uniform int ui_one;" 1058 << "uniform int ui_two;" 1059 << "" 1060 << "struct T {" 1061 << " mediump vec3 a;" 1062 << " int b;" 1063 << "};" 1064 << "struct S {" 1065 << " mediump float a;" 1066 << " T b;" 1067 << " int c;" 1068 << "};" 1069 << "" 1070 << "void main (void)" 1071 << "{" 1072 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);" 1073 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);" 1074 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);" 1075 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);" 1076 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" 1077 << " if (a != b) ${DST}.x = 1.0;" 1078 << " if (a != c) ${DST}.y = 1.0;" 1079 << " if (a != d) ${DST}.z = 1.0;" 1080 << " ${ASSIGN_POS}" 1081 << "}", 1082 { 1083 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0]+0.5f)) 1084 c.color.x() = 1.0f; 1085 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1]+0.5f)) 1086 c.color.y() = 1.0f; 1087 c.color.z() = 1.0f; 1088 }); 1089 1090 LOCAL_STRUCT_CASE(array_member_equality, "Struct with array members equality", 1091 LineStream() 1092 << "${HEADER}" 1093 << "" 1094 << "struct S {" 1095 << " bool m[2];" 1096 << "};" 1097 << "" 1098 << "void main (void)" 1099 << "{" 1100 << " S a;" 1101 << " a.m[0] = true;" 1102 << " a.m[1] = false;" 1103 << "" 1104 << " S b;" 1105 << " b.m[0] = true;" 1106 << " b.m[1] = false;" 1107 << "" 1108 << " S c;" 1109 << " c.m[0] = true;" 1110 << " c.m[1] = true;" 1111 << "" 1112 << " ${DST} = vec4(0.0, 0.0, 1.0, 1.0);" 1113 << " if (a == b) ${DST}.x = 1.0;" 1114 << " if (a != c) ${DST}.y = 1.0;" 1115 << " ${ASSIGN_POS}" 1116 << "}", 1117 { 1118 c.color.x() = 1.0f; 1119 c.color.y() = 1.0f; 1120 c.color.z() = 1.0f; 1121 }); 1122} 1123 1124class UniformStructTests : public TestCaseGroup 1125{ 1126public: 1127 UniformStructTests(Context& context, glu::GLSLVersion glslVersion) 1128 : TestCaseGroup(context, "uniform", "Uniform structs"), m_glslVersion(glslVersion) 1129 { 1130 } 1131 1132 ~UniformStructTests(void) 1133 { 1134 } 1135 1136 virtual void init(void); 1137 1138private: 1139 glu::GLSLVersion m_glslVersion; 1140}; 1141 1142namespace 1143{ 1144 1145#define CHECK_SET_UNIFORM(NAME) GLU_EXPECT_NO_ERROR(gl.getError(), (string("Failed to set ") + NAME).c_str()) 1146 1147#define MAKE_SET_VEC_UNIFORM(VECTYPE, SETUNIFORM) \ 1148 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const tcu::VECTYPE& vec) \ 1149 { \ 1150 int loc = gl.getUniformLocation(programID, name); \ 1151 SETUNIFORM(loc, 1, vec.getPtr()); \ 1152 CHECK_SET_UNIFORM(name); \ 1153 } \ 1154 struct SetUniform##VECTYPE##Unused_s \ 1155 { \ 1156 int unused; \ 1157 } 1158 1159#define MAKE_SET_VEC_UNIFORM_PTR(VECTYPE, SETUNIFORM) \ 1160 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const tcu::VECTYPE* vec, \ 1161 int arraySize) \ 1162 { \ 1163 int loc = gl.getUniformLocation(programID, name); \ 1164 SETUNIFORM(loc, arraySize, vec->getPtr()); \ 1165 CHECK_SET_UNIFORM(name); \ 1166 } \ 1167 struct SetUniformPtr##VECTYPE##Unused_s \ 1168 { \ 1169 int unused; \ 1170 } 1171 1172MAKE_SET_VEC_UNIFORM(Vec2, gl.uniform2fv); 1173MAKE_SET_VEC_UNIFORM(Vec3, gl.uniform3fv); 1174MAKE_SET_VEC_UNIFORM_PTR(Vec2, gl.uniform2fv); 1175 1176void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, float value) 1177{ 1178 int loc = gl.getUniformLocation(programID, name); 1179 gl.uniform1f(loc, value); 1180 CHECK_SET_UNIFORM(name); 1181} 1182 1183void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, int value) 1184{ 1185 int loc = gl.getUniformLocation(programID, name); 1186 gl.uniform1i(loc, value); 1187 CHECK_SET_UNIFORM(name); 1188} 1189 1190void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const float* value, int arraySize) 1191{ 1192 int loc = gl.getUniformLocation(programID, name); 1193 gl.uniform1fv(loc, arraySize, value); 1194 CHECK_SET_UNIFORM(name); 1195} 1196 1197} // anonymous 1198 1199void UniformStructTests::init(void) 1200{ 1201#define UNIFORM_STRUCT_CASE(NAME, DESCRIPTION, TEXTURES, SHADER_SRC, SET_UNIFORMS_BODY, EVAL_FUNC_BODY) \ 1202 do \ 1203 { \ 1204 struct SetUniforms_##NAME \ 1205 { \ 1206 static void setUniforms(const glw::Functions& gl, deUint32 programID, \ 1207 const tcu::Vec4& constCoords) SET_UNIFORMS_BODY \ 1208 }; \ 1209 struct Eval_##NAME \ 1210 { \ 1211 static void eval(ShaderEvalContext& c) EVAL_FUNC_BODY \ 1212 }; \ 1213 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, TEXTURES, \ 1214 Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ 1215 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, TEXTURES, \ 1216 Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ 1217 } while (deGetFalse()) 1218 1219 UNIFORM_STRUCT_CASE(basic, "Basic struct usage", false, 1220 LineStream() << "${HEADER}" 1221 << "uniform int ui_one;" 1222 << "" 1223 << "struct S {" 1224 << " mediump float a;" 1225 << " mediump vec3 b;" 1226 << " int c;" 1227 << "};" 1228 << "uniform S s;" 1229 << "" 1230 << "void main (void)" 1231 << "{" 1232 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);" 1233 << " ${ASSIGN_POS}" 1234 << "}", 1235 { 1236 setUniform(gl, programID, "s.a", constCoords.x()); 1237 setUniform(gl, programID, "s.b", constCoords.swizzle(1, 2, 3)); 1238 setUniform(gl, programID, "s.c", 1); 1239 }, 1240 { c.color.xyz() = c.constCoords.swizzle(0, 1, 2); }); 1241 1242 UNIFORM_STRUCT_CASE(nested, "Nested struct", false, 1243 LineStream() << "${HEADER}" 1244 << "uniform int ui_zero;" 1245 << "uniform int ui_one;" 1246 << "" 1247 << "struct T {" 1248 << " int a;" 1249 << " mediump vec2 b;" 1250 << "};" 1251 << "struct S {" 1252 << " mediump float a;" 1253 << " T b;" 1254 << " int c;" 1255 << "};" 1256 << "uniform S s;" 1257 << "" 1258 << "void main (void)" 1259 << "{" 1260 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);" 1261 << " ${ASSIGN_POS}" 1262 << "}", 1263 { 1264 setUniform(gl, programID, "s.a", constCoords.x()); 1265 setUniform(gl, programID, "s.b.a", 0); 1266 setUniform(gl, programID, "s.b.b", constCoords.swizzle(1, 2)); 1267 setUniform(gl, programID, "s.c", 1); 1268 }, 1269 { c.color.xyz() = c.constCoords.swizzle(0, 1, 2); }); 1270 1271 UNIFORM_STRUCT_CASE(array_member, "Struct with array member", false, 1272 LineStream() << "${HEADER}" 1273 << "uniform int ui_one;" 1274 << "" 1275 << "struct S {" 1276 << " mediump float a;" 1277 << " mediump float b[3];" 1278 << " int c;" 1279 << "};" 1280 << "uniform S s;" 1281 << "" 1282 << "void main (void)" 1283 << "{" 1284 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);" 1285 << " ${ASSIGN_POS}" 1286 << "}", 1287 { 1288 setUniform(gl, programID, "s.a", constCoords.w()); 1289 setUniform(gl, programID, "s.c", 1); 1290 1291 float b[3]; 1292 b[0] = constCoords.z(); 1293 b[1] = constCoords.y(); 1294 b[2] = constCoords.x(); 1295 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b)); 1296 }, 1297 { c.color.xyz() = c.constCoords.swizzle(3, 2, 1); }); 1298 1299 UNIFORM_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing", false, 1300 LineStream() << "${HEADER}" 1301 << "uniform int ui_zero;" 1302 << "uniform int ui_one;" 1303 << "uniform int ui_two;" 1304 << "" 1305 << "struct S {" 1306 << " mediump float a;" 1307 << " mediump float b[3];" 1308 << " int c;" 1309 << "};" 1310 << "uniform S s;" 1311 << "" 1312 << "void main (void)" 1313 << "{" 1314 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);" 1315 << " ${ASSIGN_POS}" 1316 << "}", 1317 { 1318 setUniform(gl, programID, "s.a", constCoords.w()); 1319 setUniform(gl, programID, "s.c", 1); 1320 1321 float b[3]; 1322 b[0] = constCoords.z(); 1323 b[1] = constCoords.y(); 1324 b[2] = constCoords.x(); 1325 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b)); 1326 }, 1327 { c.color.xyz() = c.constCoords.swizzle(1, 2, 0); }); 1328 1329 UNIFORM_STRUCT_CASE(struct_array, "Struct array", false, 1330 LineStream() << "${HEADER}" 1331 << "uniform int ui_zero;" 1332 << "uniform int ui_one;" 1333 << "uniform int ui_two;" 1334 << "" 1335 << "struct S {" 1336 << " mediump float a;" 1337 << " mediump int b;" 1338 << "};" 1339 << "uniform S s[3];" 1340 << "" 1341 << "void main (void)" 1342 << "{" 1343 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);" 1344 << " ${ASSIGN_POS}" 1345 << "}", 1346 { 1347 setUniform(gl, programID, "s[0].a", constCoords.x()); 1348 setUniform(gl, programID, "s[0].b", 0); 1349 setUniform(gl, programID, "s[1].a", constCoords.y()); 1350 setUniform(gl, programID, "s[1].b", 1); 1351 setUniform(gl, programID, "s[2].a", constCoords.z()); 1352 setUniform(gl, programID, "s[2].b", 2); 1353 }, 1354 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); }); 1355 1356 UNIFORM_STRUCT_CASE( 1357 struct_array_dynamic_index, "Struct array with dynamic indexing", false, 1358 LineStream() 1359 << "${HEADER}" 1360 << "uniform int ui_zero;" 1361 << "uniform int ui_one;" 1362 << "uniform int ui_two;" 1363 << "" 1364 << "struct S {" 1365 << " mediump float a;" 1366 << " mediump int b;" 1367 << "};" 1368 << "uniform S s[3];" 1369 << "" 1370 << "void main (void)" 1371 << "{" 1372 << " ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);" 1373 << " ${ASSIGN_POS}" 1374 << "}", 1375 { 1376 setUniform(gl, programID, "s[0].a", constCoords.x()); 1377 setUniform(gl, programID, "s[0].b", 0); 1378 setUniform(gl, programID, "s[1].a", constCoords.y()); 1379 setUniform(gl, programID, "s[1].b", 1); 1380 setUniform(gl, programID, "s[2].a", constCoords.z()); 1381 setUniform(gl, programID, "s[2].b", 2); 1382 }, 1383 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); }); 1384 1385 UNIFORM_STRUCT_CASE( 1386 nested_struct_array, "Nested struct array", false, 1387 LineStream() << "${HEADER}" 1388 << "struct T {" 1389 << " mediump float a;" 1390 << " mediump vec2 b[2];" 1391 << "};" 1392 << "struct S {" 1393 << " mediump float a;" 1394 << " T b[3];" 1395 << " int c;" 1396 << "};" 1397 << "uniform S s[2];" 1398 << "" 1399 << "void main (void)" 1400 << "{" 1401 << " mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5" 1402 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4" 1403 << " mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w " 1404 "+ w) * 0.333" 1405 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0" 1406 << " ${DST} = vec4(r, g, b, a);" 1407 << " ${ASSIGN_POS}" 1408 << "}", 1409 { 1410 tcu::Vec2 arr[2]; 1411 1412 setUniform(gl, programID, "s[0].a", constCoords.x()); 1413 arr[0] = constCoords.swizzle(0, 1); 1414 arr[1] = constCoords.swizzle(2, 3); 1415 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1416 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1417 arr[0] = constCoords.swizzle(2, 3); 1418 arr[1] = constCoords.swizzle(0, 1); 1419 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f); 1420 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1421 arr[0] = constCoords.swizzle(0, 2); 1422 arr[1] = constCoords.swizzle(1, 3); 1423 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f); 1424 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1425 setUniform(gl, programID, "s[0].c", 0); 1426 1427 setUniform(gl, programID, "s[1].a", constCoords.w()); 1428 arr[0] = constCoords.swizzle(0, 0); 1429 arr[1] = constCoords.swizzle(1, 1); 1430 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1431 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1432 arr[0] = constCoords.swizzle(2, 2); 1433 arr[1] = constCoords.swizzle(3, 3); 1434 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1435 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1436 arr[0] = constCoords.swizzle(1, 0); 1437 arr[1] = constCoords.swizzle(3, 2); 1438 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1439 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1440 setUniform(gl, programID, "s[1].c", 1); 1441 }, 1442 { c.color.xyz() = c.constCoords.swizzle(2, 0, 3); }); 1443 1444 UNIFORM_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing", false, 1445 LineStream() << "${HEADER}" 1446 << "uniform int ui_zero;" 1447 << "uniform int ui_one;" 1448 << "uniform int ui_two;" 1449 << "" 1450 << "struct T {" 1451 << " mediump float a;" 1452 << " mediump vec2 b[2];" 1453 << "};" 1454 << "struct S {" 1455 << " mediump float a;" 1456 << " T b[3];" 1457 << " int c;" 1458 << "};" 1459 << "uniform S s[2];" 1460 << "" 1461 << "void main (void)" 1462 << "{" 1463 << " mediump float r = (s[0].b[ui_one].b[ui_one-1].x + " 1464 "s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5" 1465 << " mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a " 1466 "* s[ui_one].b[2].a; // x * 0.25 * 4" 1467 << " mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + " 1468 "s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w " 1469 "+ w + w) * 0.333" 1470 << " mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - " 1471 "s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0" 1472 << " ${DST} = vec4(r, g, b, a);" 1473 << " ${ASSIGN_POS}" 1474 << "}", 1475 { 1476 tcu::Vec2 arr[2]; 1477 1478 setUniform(gl, programID, "s[0].a", constCoords.x()); 1479 arr[0] = constCoords.swizzle(0, 1); 1480 arr[1] = constCoords.swizzle(2, 3); 1481 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1482 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1483 arr[0] = constCoords.swizzle(2, 3); 1484 arr[1] = constCoords.swizzle(0, 1); 1485 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f); 1486 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1487 arr[0] = constCoords.swizzle(0, 2); 1488 arr[1] = constCoords.swizzle(1, 3); 1489 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f); 1490 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1491 setUniform(gl, programID, "s[0].c", 0); 1492 1493 setUniform(gl, programID, "s[1].a", constCoords.w()); 1494 arr[0] = constCoords.swizzle(0, 0); 1495 arr[1] = constCoords.swizzle(1, 1); 1496 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1497 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1498 arr[0] = constCoords.swizzle(2, 2); 1499 arr[1] = constCoords.swizzle(3, 3); 1500 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1501 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1502 arr[0] = constCoords.swizzle(1, 0); 1503 arr[1] = constCoords.swizzle(3, 2); 1504 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1505 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1506 setUniform(gl, programID, "s[1].c", 1); 1507 }, 1508 { c.color.xyz() = c.constCoords.swizzle(2, 0, 3); }); 1509 1510 UNIFORM_STRUCT_CASE(loop_struct_array, "Struct array usage in loop", false, 1511 LineStream() << "${HEADER}" 1512 << "uniform int ui_zero;" 1513 << "uniform int ui_one;" 1514 << "uniform int ui_two;" 1515 << "" 1516 << "struct S {" 1517 << " mediump float a;" 1518 << " mediump int b;" 1519 << "};" 1520 << "uniform S s[3];" 1521 << "" 1522 << "void main (void)" 1523 << "{" 1524 << " mediump float rgb[3];" 1525 << " int alpha = 0;" 1526 << " for (int i = 0; i < 3; i++)" 1527 << " {" 1528 << " rgb[i] = s[2-i].a;" 1529 << " alpha += s[i].b;" 1530 << " }" 1531 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);" 1532 << " ${ASSIGN_POS}" 1533 << "}", 1534 { 1535 setUniform(gl, programID, "s[0].a", constCoords.x()); 1536 setUniform(gl, programID, "s[0].b", 0); 1537 setUniform(gl, programID, "s[1].a", constCoords.y()); 1538 setUniform(gl, programID, "s[1].b", -1); 1539 setUniform(gl, programID, "s[2].a", constCoords.z()); 1540 setUniform(gl, programID, "s[2].b", 2); 1541 }, 1542 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); }); 1543 1544 UNIFORM_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop", false, 1545 LineStream() << "${HEADER}" 1546 << "uniform int ui_zero;" 1547 << "uniform int ui_one;" 1548 << "uniform int ui_two;" 1549 << "uniform mediump float uf_two;" 1550 << "uniform mediump float uf_three;" 1551 << "uniform mediump float uf_four;" 1552 << "uniform mediump float uf_half;" 1553 << "uniform mediump float uf_third;" 1554 << "uniform mediump float uf_fourth;" 1555 << "uniform mediump float uf_sixth;" 1556 << "" 1557 << "struct T {" 1558 << " mediump float a;" 1559 << " mediump vec2 b[2];" 1560 << "};" 1561 << "struct S {" 1562 << " mediump float a;" 1563 << " T b[3];" 1564 << " int c;" 1565 << "};" 1566 << "uniform S s[2];" 1567 << "" 1568 << "void main (void)" 1569 << "{" 1570 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0" 1571 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0" 1572 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0" 1573 << " mediump float a = 1.0;" 1574 << " for (int i = 0; i < 2; i++)" 1575 << " {" 1576 << " for (int j = 0; j < 3; j++)" 1577 << " {" 1578 << " r += s[0].b[j].b[i].y;" 1579 << " g += s[i].b[j].b[0].x;" 1580 << " b += s[i].b[j].b[1].x;" 1581 << " a *= s[i].b[j].a;" 1582 << " }" 1583 << " }" 1584 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);" 1585 << " ${ASSIGN_POS}" 1586 << "}", 1587 { 1588 tcu::Vec2 arr[2]; 1589 1590 setUniform(gl, programID, "s[0].a", constCoords.x()); 1591 arr[0] = constCoords.swizzle(1, 0); 1592 arr[1] = constCoords.swizzle(2, 0); 1593 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1594 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1595 arr[0] = constCoords.swizzle(1, 1); 1596 arr[1] = constCoords.swizzle(3, 1); 1597 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f); 1598 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1599 arr[0] = constCoords.swizzle(2, 1); 1600 arr[1] = constCoords.swizzle(2, 1); 1601 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f); 1602 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1603 setUniform(gl, programID, "s[0].c", 0); 1604 1605 setUniform(gl, programID, "s[1].a", constCoords.w()); 1606 arr[0] = constCoords.swizzle(2, 0); 1607 arr[1] = constCoords.swizzle(2, 1); 1608 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1609 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1610 arr[0] = constCoords.swizzle(2, 2); 1611 arr[1] = constCoords.swizzle(3, 3); 1612 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1613 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1614 arr[0] = constCoords.swizzle(1, 0); 1615 arr[1] = constCoords.swizzle(3, 2); 1616 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1617 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1618 setUniform(gl, programID, "s[1].c", 1); 1619 }, 1620 { c.color.xyz() = (c.constCoords.swizzle(0, 1, 2) + c.constCoords.swizzle(1, 2, 3)) * 0.5f; }); 1621 1622 UNIFORM_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop", false, 1623 LineStream() << "${HEADER}" 1624 << "uniform int ui_zero;" 1625 << "uniform int ui_one;" 1626 << "uniform int ui_two;" 1627 << "uniform int ui_three;" 1628 << "" 1629 << "struct S {" 1630 << " mediump float a;" 1631 << " mediump int b;" 1632 << "};" 1633 << "uniform S s[3];" 1634 << "" 1635 << "void main (void)" 1636 << "{" 1637 << " mediump float rgb[3];" 1638 << " int alpha = 0;" 1639 << " for (int i = 0; i < ui_three; i++)" 1640 << " {" 1641 << " rgb[i] = s[2-i].a;" 1642 << " alpha += s[i].b;" 1643 << " }" 1644 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);" 1645 << " ${ASSIGN_POS}" 1646 << "}", 1647 { 1648 setUniform(gl, programID, "s[0].a", constCoords.x()); 1649 setUniform(gl, programID, "s[0].b", 0); 1650 setUniform(gl, programID, "s[1].a", constCoords.y()); 1651 setUniform(gl, programID, "s[1].b", -1); 1652 setUniform(gl, programID, "s[2].a", constCoords.z()); 1653 setUniform(gl, programID, "s[2].b", 2); 1654 }, 1655 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); }); 1656 1657 UNIFORM_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop", false, 1658 LineStream() << "${HEADER}" 1659 << "uniform int ui_zero;" 1660 << "uniform int ui_one;" 1661 << "uniform int ui_two;" 1662 << "uniform int ui_three;" 1663 << "uniform mediump float uf_two;" 1664 << "uniform mediump float uf_three;" 1665 << "uniform mediump float uf_four;" 1666 << "uniform mediump float uf_half;" 1667 << "uniform mediump float uf_third;" 1668 << "uniform mediump float uf_fourth;" 1669 << "uniform mediump float uf_sixth;" 1670 << "" 1671 << "struct T {" 1672 << " mediump float a;" 1673 << " mediump vec2 b[2];" 1674 << "};" 1675 << "struct S {" 1676 << " mediump float a;" 1677 << " T b[3];" 1678 << " int c;" 1679 << "};" 1680 << "uniform S s[2];" 1681 << "" 1682 << "void main (void)" 1683 << "{" 1684 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0" 1685 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0" 1686 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0" 1687 << " mediump float a = 1.0;" 1688 << " for (int i = 0; i < ui_two; i++)" 1689 << " {" 1690 << " for (int j = 0; j < ui_three; j++)" 1691 << " {" 1692 << " r += s[0].b[j].b[i].y;" 1693 << " g += s[i].b[j].b[0].x;" 1694 << " b += s[i].b[j].b[1].x;" 1695 << " a *= s[i].b[j].a;" 1696 << " }" 1697 << " }" 1698 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);" 1699 << " ${ASSIGN_POS}" 1700 << "}", 1701 { 1702 tcu::Vec2 arr[2]; 1703 1704 setUniform(gl, programID, "s[0].a", constCoords.x()); 1705 arr[0] = constCoords.swizzle(1, 0); 1706 arr[1] = constCoords.swizzle(2, 0); 1707 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1708 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1709 arr[0] = constCoords.swizzle(1, 1); 1710 arr[1] = constCoords.swizzle(3, 1); 1711 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f); 1712 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1713 arr[0] = constCoords.swizzle(2, 1); 1714 arr[1] = constCoords.swizzle(2, 1); 1715 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f); 1716 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1717 setUniform(gl, programID, "s[0].c", 0); 1718 1719 setUniform(gl, programID, "s[1].a", constCoords.w()); 1720 arr[0] = constCoords.swizzle(2, 0); 1721 arr[1] = constCoords.swizzle(2, 1); 1722 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1723 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1724 arr[0] = constCoords.swizzle(2, 2); 1725 arr[1] = constCoords.swizzle(3, 3); 1726 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1727 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1728 arr[0] = constCoords.swizzle(1, 0); 1729 arr[1] = constCoords.swizzle(3, 2); 1730 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1731 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1732 setUniform(gl, programID, "s[1].c", 1); 1733 }, 1734 { c.color.xyz() = (c.constCoords.swizzle(0, 1, 2) + c.constCoords.swizzle(1, 2, 3)) * 0.5f; }); 1735 1736 UNIFORM_STRUCT_CASE( 1737 sampler, "Sampler in struct", true, 1738 LineStream() << "${HEADER}" 1739 << "uniform int ui_one;" 1740 << "" 1741 << "struct S {" 1742 << " mediump float a;" 1743 << " mediump vec3 b;" 1744 << " sampler2D c;" 1745 << "};" 1746 << "uniform S s;" 1747 << "" 1748 << "void main (void)" 1749 << "{" 1750 << " ${DST} = vec4(texture(s.c, ${COORDS}.xy * s.b.xy + s.b.z).rgb, s.a);" 1751 << " ${ASSIGN_POS}" 1752 << "}", 1753 { 1754 DE_UNREF(constCoords); 1755 setUniform(gl, programID, "s.a", 1.0f); 1756 setUniform(gl, programID, "s.b", tcu::Vec3(0.75f, 0.75f, 0.1f)); 1757 setUniform(gl, programID, "s.c", TEXTURE_GRADIENT); 1758 }, 1759 { c.color.xyz() = c.texture2D(TEXTURE_GRADIENT, c.coords.swizzle(0, 1) * 0.75f + 0.1f).swizzle(0, 1, 2); }); 1760 1761 UNIFORM_STRUCT_CASE( 1762 sampler_nested, "Sampler in nested struct", true, 1763 LineStream() << "${HEADER}" 1764 << "uniform int ui_zero;" 1765 << "uniform int ui_one;" 1766 << "" 1767 << "struct T {" 1768 << " sampler2D a;" 1769 << " mediump vec2 b;" 1770 << "};" 1771 << "struct S {" 1772 << " mediump float a;" 1773 << " T b;" 1774 << " int c;" 1775 << "};" 1776 << "uniform S s;" 1777 << "" 1778 << "void main (void)" 1779 << "{" 1780 << " ${DST} = vec4(texture(s.b.a, ${COORDS}.xy * s.b.b + s.a).rgb, s.c);" 1781 << " ${ASSIGN_POS}" 1782 << "}", 1783 { 1784 DE_UNREF(constCoords); 1785 setUniform(gl, programID, "s.a", 0.1f); 1786 setUniform(gl, programID, "s.b.a", TEXTURE_GRADIENT); 1787 setUniform(gl, programID, "s.b.b", tcu::Vec2(0.75f, 0.75f)); 1788 setUniform(gl, programID, "s.c", 1); 1789 }, 1790 { c.color.xyz() = c.texture2D(TEXTURE_GRADIENT, c.coords.swizzle(0, 1) * 0.75f + 0.1f).swizzle(0, 1, 2); }); 1791 1792 UNIFORM_STRUCT_CASE( 1793 sampler_array, "Sampler in struct array", true, 1794 LineStream() << "${HEADER}" 1795 << "uniform int ui_one;" 1796 << "" 1797 << "struct S {" 1798 << " mediump float a;" 1799 << " mediump vec3 b;" 1800 << " sampler2D c;" 1801 << "};" 1802 << "uniform S s[2];" 1803 << "" 1804 << "void main (void)" 1805 << "{" 1806 << " ${DST} = vec4(texture(s[1].c, ${COORDS}.xy * s[0].b.xy + s[1].b.z).rgb, s[0].a);" 1807 << " ${ASSIGN_POS}" 1808 << "}", 1809 { 1810 DE_UNREF(constCoords); 1811 setUniform(gl, programID, "s[0].a", 1.0f); 1812 setUniform(gl, programID, "s[0].b", tcu::Vec3(0.75f, 0.75f, 0.25f)); 1813 setUniform(gl, programID, "s[0].c", 1); 1814 setUniform(gl, programID, "s[1].a", 0.0f); 1815 setUniform(gl, programID, "s[1].b", tcu::Vec3(0.5f, 0.5f, 0.1f)); 1816 setUniform(gl, programID, "s[1].c", TEXTURE_GRADIENT); 1817 }, 1818 { c.color.xyz() = c.texture2D(TEXTURE_GRADIENT, c.coords.swizzle(0, 1) * 0.75f + 0.1f).swizzle(0, 1, 2); }); 1819} 1820 1821ShaderStructTests::ShaderStructTests(Context& context, glu::GLSLVersion glslVersion) 1822 : TestCaseGroup(context, "struct", "Struct Tests"), m_glslVersion(glslVersion) 1823{ 1824} 1825 1826ShaderStructTests::~ShaderStructTests(void) 1827{ 1828} 1829 1830void ShaderStructTests::init(void) 1831{ 1832 addChild(new LocalStructTests(m_context, m_glslVersion)); 1833 addChild(new UniformStructTests(m_context, m_glslVersion)); 1834} 1835 1836} // deqp 1837