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