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