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