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 }; /* NOLINT(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 { \ 1195 static void setUniforms (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY /* NOLINT(SET_UNIFORMS_BODY) */ \ 1196 }; \ 1197 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ 1198 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ 1199 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \ 1200 } while (deGetFalse()) 1201 1202 UNIFORM_STRUCT_CASE(basic, "Basic struct usage", false, 1203 LineStream() 1204 << "${HEADER}" 1205 << "uniform int ui_one;" 1206 << "" 1207 << "struct S {" 1208 << " mediump float a;" 1209 << " mediump vec3 b;" 1210 << " int c;" 1211 << "};" 1212 << "uniform S s;" 1213 << "" 1214 << "void main (void)" 1215 << "{" 1216 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);" 1217 << " ${ASSIGN_POS}" 1218 << "}", 1219 { 1220 setUniform(gl, programID, "s.a", constCoords.x()); 1221 setUniform(gl, programID, "s.b", constCoords.swizzle(1, 2, 3)); 1222 setUniform(gl, programID, "s.c", 1); 1223 }, 1224 { 1225 c.color.xyz() = c.constCoords.swizzle(0,1,2); 1226 }); 1227 1228 UNIFORM_STRUCT_CASE(nested, "Nested struct", false, 1229 LineStream() 1230 << "${HEADER}" 1231 << "uniform int ui_zero;" 1232 << "uniform int ui_one;" 1233 << "" 1234 << "struct T {" 1235 << " int a;" 1236 << " mediump vec2 b;" 1237 << "};" 1238 << "struct S {" 1239 << " mediump float a;" 1240 << " T b;" 1241 << " int c;" 1242 << "};" 1243 << "uniform S s;" 1244 << "" 1245 << "void main (void)" 1246 << "{" 1247 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);" 1248 << " ${ASSIGN_POS}" 1249 << "}", 1250 { 1251 setUniform(gl, programID, "s.a", constCoords.x()); 1252 setUniform(gl, programID, "s.b.a", 0); 1253 setUniform(gl, programID, "s.b.b", constCoords.swizzle(1,2)); 1254 setUniform(gl, programID, "s.c", 1); 1255 }, 1256 { 1257 c.color.xyz() = c.constCoords.swizzle(0,1,2); 1258 }); 1259 1260 UNIFORM_STRUCT_CASE(array_member, "Struct with array member", false, 1261 LineStream() 1262 << "${HEADER}" 1263 << "uniform int ui_one;" 1264 << "" 1265 << "struct S {" 1266 << " mediump float a;" 1267 << " mediump float b[3];" 1268 << " int c;" 1269 << "};" 1270 << "uniform S s;" 1271 << "" 1272 << "void main (void)" 1273 << "{" 1274 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);" 1275 << " ${ASSIGN_POS}" 1276 << "}", 1277 { 1278 setUniform(gl, programID, "s.a", constCoords.w()); 1279 setUniform(gl, programID, "s.c", 1); 1280 1281 float b[3]; 1282 b[0] = constCoords.z(); 1283 b[1] = constCoords.y(); 1284 b[2] = constCoords.x(); 1285 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b)); 1286 }, 1287 { 1288 c.color.xyz() = c.constCoords.swizzle(3,2,1); 1289 }); 1290 1291 UNIFORM_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing", false, 1292 LineStream() 1293 << "${HEADER}" 1294 << "uniform int ui_zero;" 1295 << "uniform int ui_one;" 1296 << "uniform int ui_two;" 1297 << "" 1298 << "struct S {" 1299 << " mediump float a;" 1300 << " mediump float b[3];" 1301 << " int c;" 1302 << "};" 1303 << "uniform S s;" 1304 << "" 1305 << "void main (void)" 1306 << "{" 1307 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);" 1308 << " ${ASSIGN_POS}" 1309 << "}", 1310 { 1311 setUniform(gl, programID, "s.a", constCoords.w()); 1312 setUniform(gl, programID, "s.c", 1); 1313 1314 float b[3]; 1315 b[0] = constCoords.z(); 1316 b[1] = constCoords.y(); 1317 b[2] = constCoords.x(); 1318 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b)); 1319 }, 1320 { 1321 c.color.xyz() = c.constCoords.swizzle(1,2,0); 1322 }); 1323 1324 UNIFORM_STRUCT_CASE(struct_array, "Struct array", false, 1325 LineStream() 1326 << "${HEADER}" 1327 << "uniform int ui_zero;" 1328 << "uniform int ui_one;" 1329 << "uniform int ui_two;" 1330 << "" 1331 << "struct S {" 1332 << " mediump float a;" 1333 << " mediump int b;" 1334 << "};" 1335 << "uniform S s[3];" 1336 << "" 1337 << "void main (void)" 1338 << "{" 1339 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);" 1340 << " ${ASSIGN_POS}" 1341 << "}", 1342 { 1343 setUniform(gl, programID, "s[0].a", constCoords.x()); 1344 setUniform(gl, programID, "s[0].b", 0); 1345 setUniform(gl, programID, "s[1].a", constCoords.y()); 1346 setUniform(gl, programID, "s[1].b", 1); 1347 setUniform(gl, programID, "s[2].a", constCoords.z()); 1348 setUniform(gl, programID, "s[2].b", 2); 1349 }, 1350 { 1351 c.color.xyz() = c.constCoords.swizzle(2,1,0); 1352 }); 1353 1354 UNIFORM_STRUCT_CASE(struct_array_dynamic_index, "Struct array with dynamic indexing", false, 1355 LineStream() 1356 << "${HEADER}" 1357 << "uniform int ui_zero;" 1358 << "uniform int ui_one;" 1359 << "uniform int ui_two;" 1360 << "" 1361 << "struct S {" 1362 << " mediump float a;" 1363 << " mediump int b;" 1364 << "};" 1365 << "uniform S s[3];" 1366 << "" 1367 << "void main (void)" 1368 << "{" 1369 << " ${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);" 1370 << " ${ASSIGN_POS}" 1371 << "}", 1372 { 1373 setUniform(gl, programID, "s[0].a", constCoords.x()); 1374 setUniform(gl, programID, "s[0].b", 0); 1375 setUniform(gl, programID, "s[1].a", constCoords.y()); 1376 setUniform(gl, programID, "s[1].b", 1); 1377 setUniform(gl, programID, "s[2].a", constCoords.z()); 1378 setUniform(gl, programID, "s[2].b", 2); 1379 }, 1380 { 1381 c.color.xyz() = c.constCoords.swizzle(2,1,0); 1382 }); 1383 1384 UNIFORM_STRUCT_CASE(nested_struct_array, "Nested struct array", false, 1385 LineStream() 1386 << "${HEADER}" 1387 << "struct T {" 1388 << " mediump float a;" 1389 << " mediump vec2 b[2];" 1390 << "};" 1391 << "struct S {" 1392 << " mediump float a;" 1393 << " T b[3];" 1394 << " int c;" 1395 << "};" 1396 << "uniform S s[2];" 1397 << "" 1398 << "void main (void)" 1399 << "{" 1400 << " 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" 1401 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4" 1402 << " 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" 1403 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0" 1404 << " ${DST} = vec4(r, g, b, a);" 1405 << " ${ASSIGN_POS}" 1406 << "}", 1407 { 1408 tcu::Vec2 arr[2]; 1409 1410 setUniform(gl, programID, "s[0].a", constCoords.x()); 1411 arr[0] = constCoords.swizzle(0,1); 1412 arr[1] = constCoords.swizzle(2,3); 1413 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1414 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1415 arr[0] = constCoords.swizzle(2,3); 1416 arr[1] = constCoords.swizzle(0,1); 1417 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f); 1418 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1419 arr[0] = constCoords.swizzle(0,2); 1420 arr[1] = constCoords.swizzle(1,3); 1421 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f); 1422 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1423 setUniform(gl, programID, "s[0].c", 0); 1424 1425 setUniform(gl, programID, "s[1].a", constCoords.w()); 1426 arr[0] = constCoords.swizzle(0,0); 1427 arr[1] = constCoords.swizzle(1,1); 1428 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1429 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1430 arr[0] = constCoords.swizzle(2,2); 1431 arr[1] = constCoords.swizzle(3,3); 1432 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1433 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1434 arr[0] = constCoords.swizzle(1,0); 1435 arr[1] = constCoords.swizzle(3,2); 1436 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1437 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1438 setUniform(gl, programID, "s[1].c", 1); 1439 }, 1440 { 1441 c.color.xyz() = c.constCoords.swizzle(2,0,3); 1442 }); 1443 1444 UNIFORM_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing", false, 1445 LineStream() 1446 << "${HEADER}" 1447 << "uniform int ui_zero;" 1448 << "uniform int ui_one;" 1449 << "uniform int ui_two;" 1450 << "" 1451 << "struct T {" 1452 << " mediump float a;" 1453 << " mediump vec2 b[2];" 1454 << "};" 1455 << "struct S {" 1456 << " mediump float a;" 1457 << " T b[3];" 1458 << " int c;" 1459 << "};" 1460 << "uniform S s[2];" 1461 << "" 1462 << "void main (void)" 1463 << "{" 1464 << " 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" 1465 << " 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" 1466 << " 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" 1467 << " 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" 1468 << " ${DST} = vec4(r, g, b, a);" 1469 << " ${ASSIGN_POS}" 1470 << "}", 1471 { 1472 tcu::Vec2 arr[2]; 1473 1474 setUniform(gl, programID, "s[0].a", constCoords.x()); 1475 arr[0] = constCoords.swizzle(0,1); 1476 arr[1] = constCoords.swizzle(2,3); 1477 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1478 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1479 arr[0] = constCoords.swizzle(2,3); 1480 arr[1] = constCoords.swizzle(0,1); 1481 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f); 1482 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1483 arr[0] = constCoords.swizzle(0,2); 1484 arr[1] = constCoords.swizzle(1,3); 1485 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f); 1486 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1487 setUniform(gl, programID, "s[0].c", 0); 1488 1489 setUniform(gl, programID, "s[1].a", constCoords.w()); 1490 arr[0] = constCoords.swizzle(0,0); 1491 arr[1] = constCoords.swizzle(1,1); 1492 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1493 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1494 arr[0] = constCoords.swizzle(2,2); 1495 arr[1] = constCoords.swizzle(3,3); 1496 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1497 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1498 arr[0] = constCoords.swizzle(1,0); 1499 arr[1] = constCoords.swizzle(3,2); 1500 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1501 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1502 setUniform(gl, programID, "s[1].c", 1); 1503 }, 1504 { 1505 c.color.xyz() = c.constCoords.swizzle(2,0,3); 1506 }); 1507 1508 UNIFORM_STRUCT_CASE(loop_struct_array, "Struct array usage in loop", false, 1509 LineStream() 1510 << "${HEADER}" 1511 << "uniform int ui_zero;" 1512 << "uniform int ui_one;" 1513 << "uniform int ui_two;" 1514 << "" 1515 << "struct S {" 1516 << " mediump float a;" 1517 << " mediump int b;" 1518 << "};" 1519 << "uniform S s[3];" 1520 << "" 1521 << "void main (void)" 1522 << "{" 1523 << " mediump float rgb[3];" 1524 << " int alpha = 0;" 1525 << " for (int i = 0; i < 3; i++)" 1526 << " {" 1527 << " rgb[i] = s[2-i].a;" 1528 << " alpha += s[i].b;" 1529 << " }" 1530 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);" 1531 << " ${ASSIGN_POS}" 1532 << "}", 1533 { 1534 setUniform(gl, programID, "s[0].a", constCoords.x()); 1535 setUniform(gl, programID, "s[0].b", 0); 1536 setUniform(gl, programID, "s[1].a", constCoords.y()); 1537 setUniform(gl, programID, "s[1].b", -1); 1538 setUniform(gl, programID, "s[2].a", constCoords.z()); 1539 setUniform(gl, programID, "s[2].b", 2); 1540 }, 1541 { 1542 c.color.xyz() = c.constCoords.swizzle(2,1,0); 1543 }); 1544 1545 UNIFORM_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop", false, 1546 LineStream() 1547 << "${HEADER}" 1548 << "uniform int ui_zero;" 1549 << "uniform int ui_one;" 1550 << "uniform int ui_two;" 1551 << "uniform mediump float uf_two;" 1552 << "uniform mediump float uf_three;" 1553 << "uniform mediump float uf_four;" 1554 << "uniform mediump float uf_half;" 1555 << "uniform mediump float uf_third;" 1556 << "uniform mediump float uf_fourth;" 1557 << "uniform mediump float uf_sixth;" 1558 << "" 1559 << "struct T {" 1560 << " mediump float a;" 1561 << " mediump vec2 b[2];" 1562 << "};" 1563 << "struct S {" 1564 << " mediump float a;" 1565 << " T b[3];" 1566 << " int c;" 1567 << "};" 1568 << "uniform S s[2];" 1569 << "" 1570 << "void main (void)" 1571 << "{" 1572 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0" 1573 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0" 1574 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0" 1575 << " mediump float a = 1.0;" 1576 << " for (int i = 0; i < 2; i++)" 1577 << " {" 1578 << " for (int j = 0; j < 3; j++)" 1579 << " {" 1580 << " r += s[0].b[j].b[i].y;" 1581 << " g += s[i].b[j].b[0].x;" 1582 << " b += s[i].b[j].b[1].x;" 1583 << " a *= s[i].b[j].a;" 1584 << " }" 1585 << " }" 1586 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);" 1587 << " ${ASSIGN_POS}" 1588 << "}", 1589 { 1590 tcu::Vec2 arr[2]; 1591 1592 setUniform(gl, programID, "s[0].a", constCoords.x()); 1593 arr[0] = constCoords.swizzle(1,0); 1594 arr[1] = constCoords.swizzle(2,0); 1595 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1596 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1597 arr[0] = constCoords.swizzle(1,1); 1598 arr[1] = constCoords.swizzle(3,1); 1599 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f); 1600 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1601 arr[0] = constCoords.swizzle(2,1); 1602 arr[1] = constCoords.swizzle(2,1); 1603 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f); 1604 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1605 setUniform(gl, programID, "s[0].c", 0); 1606 1607 setUniform(gl, programID, "s[1].a", constCoords.w()); 1608 arr[0] = constCoords.swizzle(2,0); 1609 arr[1] = constCoords.swizzle(2,1); 1610 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1611 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1612 arr[0] = constCoords.swizzle(2,2); 1613 arr[1] = constCoords.swizzle(3,3); 1614 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1615 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1616 arr[0] = constCoords.swizzle(1,0); 1617 arr[1] = constCoords.swizzle(3,2); 1618 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1619 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1620 setUniform(gl, programID, "s[1].c", 1); 1621 }, 1622 { 1623 c.color.xyz() = (c.constCoords.swizzle(0,1,2) + c.constCoords.swizzle(1,2,3)) * 0.5f; 1624 }); 1625 1626 UNIFORM_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop", false, 1627 LineStream() 1628 << "${HEADER}" 1629 << "uniform int ui_zero;" 1630 << "uniform int ui_one;" 1631 << "uniform int ui_two;" 1632 << "uniform int ui_three;" 1633 << "" 1634 << "struct S {" 1635 << " mediump float a;" 1636 << " mediump int b;" 1637 << "};" 1638 << "uniform S s[3];" 1639 << "" 1640 << "void main (void)" 1641 << "{" 1642 << " mediump float rgb[3];" 1643 << " int alpha = 0;" 1644 << " for (int i = 0; i < ui_three; i++)" 1645 << " {" 1646 << " rgb[i] = s[2-i].a;" 1647 << " alpha += s[i].b;" 1648 << " }" 1649 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);" 1650 << " ${ASSIGN_POS}" 1651 << "}", 1652 { 1653 setUniform(gl, programID, "s[0].a", constCoords.x()); 1654 setUniform(gl, programID, "s[0].b", 0); 1655 setUniform(gl, programID, "s[1].a", constCoords.y()); 1656 setUniform(gl, programID, "s[1].b", -1); 1657 setUniform(gl, programID, "s[2].a", constCoords.z()); 1658 setUniform(gl, programID, "s[2].b", 2); 1659 }, 1660 { 1661 c.color.xyz() = c.constCoords.swizzle(2,1,0); 1662 }); 1663 1664 UNIFORM_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop", false, 1665 LineStream() 1666 << "${HEADER}" 1667 << "uniform int ui_zero;" 1668 << "uniform int ui_one;" 1669 << "uniform int ui_two;" 1670 << "uniform int ui_three;" 1671 << "uniform mediump float uf_two;" 1672 << "uniform mediump float uf_three;" 1673 << "uniform mediump float uf_four;" 1674 << "uniform mediump float uf_half;" 1675 << "uniform mediump float uf_third;" 1676 << "uniform mediump float uf_fourth;" 1677 << "uniform mediump float uf_sixth;" 1678 << "" 1679 << "struct T {" 1680 << " mediump float a;" 1681 << " mediump vec2 b[2];" 1682 << "};" 1683 << "struct S {" 1684 << " mediump float a;" 1685 << " T b[3];" 1686 << " int c;" 1687 << "};" 1688 << "uniform S s[2];" 1689 << "" 1690 << "void main (void)" 1691 << "{" 1692 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0" 1693 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0" 1694 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0" 1695 << " mediump float a = 1.0;" 1696 << " for (int i = 0; i < ui_two; i++)" 1697 << " {" 1698 << " for (int j = 0; j < ui_three; j++)" 1699 << " {" 1700 << " r += s[0].b[j].b[i].y;" 1701 << " g += s[i].b[j].b[0].x;" 1702 << " b += s[i].b[j].b[1].x;" 1703 << " a *= s[i].b[j].a;" 1704 << " }" 1705 << " }" 1706 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);" 1707 << " ${ASSIGN_POS}" 1708 << "}", 1709 { 1710 tcu::Vec2 arr[2]; 1711 1712 setUniform(gl, programID, "s[0].a", constCoords.x()); 1713 arr[0] = constCoords.swizzle(1,0); 1714 arr[1] = constCoords.swizzle(2,0); 1715 setUniform(gl, programID, "s[0].b[0].a", 0.5f); 1716 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1717 arr[0] = constCoords.swizzle(1,1); 1718 arr[1] = constCoords.swizzle(3,1); 1719 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f); 1720 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1721 arr[0] = constCoords.swizzle(2,1); 1722 arr[1] = constCoords.swizzle(2,1); 1723 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f); 1724 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1725 setUniform(gl, programID, "s[0].c", 0); 1726 1727 setUniform(gl, programID, "s[1].a", constCoords.w()); 1728 arr[0] = constCoords.swizzle(2,0); 1729 arr[1] = constCoords.swizzle(2,1); 1730 setUniform(gl, programID, "s[1].b[0].a", 2.0f); 1731 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1732 arr[0] = constCoords.swizzle(2,2); 1733 arr[1] = constCoords.swizzle(3,3); 1734 setUniform(gl, programID, "s[1].b[1].a", 3.0f); 1735 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1736 arr[0] = constCoords.swizzle(1,0); 1737 arr[1] = constCoords.swizzle(3,2); 1738 setUniform(gl, programID, "s[1].b[2].a", 4.0f); 1739 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr)); 1740 setUniform(gl, programID, "s[1].c", 1); 1741 }, 1742 { 1743 c.color.xyz() = (c.constCoords.swizzle(0,1,2) + c.constCoords.swizzle(1,2,3)) * 0.5f; 1744 }); 1745 1746 UNIFORM_STRUCT_CASE(sampler, "Sampler in struct", true, 1747 LineStream() 1748 << "${HEADER}" 1749 << "uniform int ui_one;" 1750 << "" 1751 << "struct S {" 1752 << " mediump float a;" 1753 << " mediump vec3 b;" 1754 << " sampler2D c;" 1755 << "};" 1756 << "uniform S s;" 1757 << "" 1758 << "void main (void)" 1759 << "{" 1760 << " ${DST} = vec4(texture(s.c, ${COORDS}.xy * s.b.xy + s.b.z).rgb, s.a);" 1761 << " ${ASSIGN_POS}" 1762 << "}", 1763 { 1764 DE_UNREF(constCoords); 1765 setUniform(gl, programID, "s.a", 1.0f); 1766 setUniform(gl, programID, "s.b", tcu::Vec3(0.25f, 0.25f, 0.5f)); 1767 setUniform(gl, programID, "s.c", 0); 1768 }, 1769 { 1770 c.color.xyz() = c.texture2D(TEXTURE_BRICK, c.coords.swizzle(0,1) * 0.25f + 0.5f).swizzle(0,1,2); 1771 }); 1772 1773 UNIFORM_STRUCT_CASE(sampler_nested, "Sampler in nested struct", true, 1774 LineStream() 1775 << "${HEADER}" 1776 << "uniform int ui_zero;" 1777 << "uniform int ui_one;" 1778 << "" 1779 << "struct T {" 1780 << " sampler2D a;" 1781 << " mediump vec2 b;" 1782 << "};" 1783 << "struct S {" 1784 << " mediump float a;" 1785 << " T b;" 1786 << " int c;" 1787 << "};" 1788 << "uniform S s;" 1789 << "" 1790 << "void main (void)" 1791 << "{" 1792 << " ${DST} = vec4(texture(s.b.a, ${COORDS}.xy * s.b.b + s.a).rgb, s.c);" 1793 << " ${ASSIGN_POS}" 1794 << "}", 1795 { 1796 DE_UNREF(constCoords); 1797 setUniform(gl, programID, "s.a", 0.5f); 1798 setUniform(gl, programID, "s.b.a", 0); 1799 setUniform(gl, programID, "s.b.b", tcu::Vec2(0.25f, 0.25f)); 1800 setUniform(gl, programID, "s.c", 1); 1801 }, 1802 { 1803 c.color.xyz() = c.texture2D(TEXTURE_BRICK, c.coords.swizzle(0,1) * 0.25f + 0.5f).swizzle(0,1,2); 1804 }); 1805 1806 UNIFORM_STRUCT_CASE(sampler_array, "Sampler in struct array", true, 1807 LineStream() 1808 << "${HEADER}" 1809 << "uniform int ui_one;" 1810 << "" 1811 << "struct S {" 1812 << " mediump float a;" 1813 << " mediump vec3 b;" 1814 << " sampler2D c;" 1815 << "};" 1816 << "uniform S s[2];" 1817 << "" 1818 << "void main (void)" 1819 << "{" 1820 << " ${DST} = vec4(texture(s[1].c, ${COORDS}.xy * s[0].b.xy + s[1].b.z).rgb, s[0].a);" 1821 << " ${ASSIGN_POS}" 1822 << "}", 1823 { 1824 DE_UNREF(constCoords); 1825 setUniform(gl, programID, "s[0].a", 1.0f); 1826 setUniform(gl, programID, "s[0].b", tcu::Vec3(0.25f, 0.25f, 0.25f)); 1827 setUniform(gl, programID, "s[0].c", 1); 1828 setUniform(gl, programID, "s[1].a", 0.0f); 1829 setUniform(gl, programID, "s[1].b", tcu::Vec3(0.5f, 0.5f, 0.5f)); 1830 setUniform(gl, programID, "s[1].c", 0); 1831 }, 1832 { 1833 c.color.xyz() = c.texture2D(TEXTURE_BRICK, c.coords.swizzle(0,1) * 0.25f + 0.5f).swizzle(0,1,2); 1834 }); 1835 1836 UNIFORM_STRUCT_CASE(equal, "Struct equality", false, 1837 LineStream() 1838 << "${HEADER}" 1839 << "uniform mediump float uf_one;" 1840 << "uniform int ui_two;" 1841 << "" 1842 << "struct S {" 1843 << " mediump float a;" 1844 << " mediump vec3 b;" 1845 << " int c;" 1846 << "};" 1847 << "uniform S a;" 1848 << "uniform S b;" 1849 << "uniform S c;" 1850 << "" 1851 << "void main (void)" 1852 << "{" 1853 << " S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);" 1854 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" 1855 << " if (a == b) ${DST}.x = 1.0;" 1856 << " if (a == c) ${DST}.y = 1.0;" 1857 << " if (a == d) ${DST}.z = 1.0;" 1858 << " ${ASSIGN_POS}" 1859 << "}", 1860 { 1861 DE_UNREF(constCoords); 1862 setUniform(gl, programID, "a.a", 1.0f); 1863 setUniform(gl, programID, "a.b", tcu::Vec3(0.0f, 1.0f, 2.0f)); 1864 setUniform(gl, programID, "a.c", 2); 1865 setUniform(gl, programID, "b.a", 1.0f); 1866 setUniform(gl, programID, "b.b", tcu::Vec3(0.0f, 1.0f, 2.0f)); 1867 setUniform(gl, programID, "b.c", 2); 1868 setUniform(gl, programID, "c.a", 1.0f); 1869 setUniform(gl, programID, "c.b", tcu::Vec3(0.0f, 1.1f, 2.0f)); 1870 setUniform(gl, programID, "c.c", 2); 1871 }, 1872 { 1873 c.color.xy() = tcu::Vec2(1.0f, 0.0f); 1874 if (deFloatFloor(c.coords[1]+1.0f) == deFloatFloor(1.1f)) 1875 c.color.z() = 1.0f; 1876 }); 1877 1878 UNIFORM_STRUCT_CASE(not_equal, "Struct equality", false, 1879 LineStream() 1880 << "${HEADER}" 1881 << "uniform mediump float uf_one;" 1882 << "uniform int ui_two;" 1883 << "" 1884 << "struct S {" 1885 << " mediump float a;" 1886 << " mediump vec3 b;" 1887 << " int c;" 1888 << "};" 1889 << "uniform S a;" 1890 << "uniform S b;" 1891 << "uniform S c;" 1892 << "" 1893 << "void main (void)" 1894 << "{" 1895 << " S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);" 1896 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);" 1897 << " if (a != b) ${DST}.x = 1.0;" 1898 << " if (a != c) ${DST}.y = 1.0;" 1899 << " if (a != d) ${DST}.z = 1.0;" 1900 << " ${ASSIGN_POS}" 1901 << "}", 1902 { 1903 DE_UNREF(constCoords); 1904 setUniform(gl, programID, "a.a", 1.0f); 1905 setUniform(gl, programID, "a.b", tcu::Vec3(0.0f, 1.0f, 2.0f)); 1906 setUniform(gl, programID, "a.c", 2); 1907 setUniform(gl, programID, "b.a", 1.0f); 1908 setUniform(gl, programID, "b.b", tcu::Vec3(0.0f, 1.0f, 2.0f)); 1909 setUniform(gl, programID, "b.c", 2); 1910 setUniform(gl, programID, "c.a", 1.0f); 1911 setUniform(gl, programID, "c.b", tcu::Vec3(0.0f, 1.1f, 2.0f)); 1912 setUniform(gl, programID, "c.c", 2); 1913 }, 1914 { 1915 c.color.xy() = tcu::Vec2(0.0f, 1.0f); 1916 if (deFloatFloor(c.coords[1]+1.0f) != deFloatFloor(1.1f)) 1917 c.color.z() = 1.0f; 1918 }); 1919} 1920 1921ShaderStructTests::ShaderStructTests (Context& context) 1922 : TestCaseGroup(context, "struct", "Struct Tests") 1923{ 1924} 1925 1926ShaderStructTests::~ShaderStructTests (void) 1927{ 1928} 1929 1930void ShaderStructTests::init (void) 1931{ 1932 addChild(new LocalStructTests(m_context)); 1933 addChild(new UniformStructTests(m_context)); 1934} 1935 1936} // Functional 1937} // gles3 1938} // deqp 1939