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