1# -*- coding: utf-8 -*- 2 3#------------------------------------------------------------------------- 4# drawElements Quality Program utilities 5# -------------------------------------- 6# 7# Copyright 2015 The Android Open Source Project 8# 9# Licensed under the Apache License, Version 2.0 (the "License"); 10# you may not use this file except in compliance with the License. 11# You may obtain a copy of the License at 12# 13# http://www.apache.org/licenses/LICENSE-2.0 14# 15# Unless required by applicable law or agreed to in writing, software 16# distributed under the License is distributed on an "AS IS" BASIS, 17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18# See the License for the specific language governing permissions and 19# limitations under the License. 20# 21#------------------------------------------------------------------------- 22 23import sys 24import itertools 25import operator 26 27import genutil 28 29from genutil import Scalar, Vec2, Vec3, Vec4, Uint, UVec2, UVec3, UVec4, CaseGroup 30 31 32# Templates 33 34ARTIHMETIC_CASE_TEMPLATE = """ 35case ${{NAME}} 36 version 310 es 37 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 38 values 39 { 40 ${{VALUES}} 41 } 42 43 both "" 44 #version 310 es 45 precision highp float; 46 ${DECLARATIONS} 47 48 void main() 49 { 50 ${SETUP} 51 out0 = ${{EXPR}}; 52 ${OUTPUT} 53 } 54 "" 55end 56""".strip() 57 58FUNCTIONS_CASE_TEMPLATE = """ 59case ${{NAME}} 60 version 310 es 61 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 62 values 63 { 64 ${{VALUES}} 65 } 66 67 both "" 68 #version 310 es 69 precision highp float; 70 ${DECLARATIONS} 71 72 ${{OUTTYPE}} func (${{OUTTYPE}} a) 73 { 74 return a * ${{OUTTYPE}}(2); 75 } 76 77 void main() 78 { 79 ${SETUP} 80 out0 = func(in0); 81 ${OUTPUT} 82 } 83 "" 84end 85""".strip() 86 87ARRAY_CASE_TEMPLATE = """ 88case ${{NAME}} 89 version 310 es 90 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 91 values 92 { 93 ${{VALUES}} 94 } 95 96 both "" 97 #version 310 es 98 precision highp float; 99 ${DECLARATIONS} 100 101 void main() 102 { 103 ${SETUP} 104 ${{ARRAYTYPE}}[] x = ${{ARRAYTYPE}}[] (${{ARRAYVALUES}}); 105 out0 = ${{EXPR}}; 106 ${OUTPUT} 107 } 108 "" 109end 110""".strip() 111 112STRUCT_CASE_TEMPLATE = """ 113case ${{NAME}} 114 version 310 es 115 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 116 values 117 { 118 ${{VALUES}} 119 } 120 121 both "" 122 #version 310 es 123 precision highp float; 124 ${DECLARATIONS} 125 126 void main() 127 { 128 ${SETUP} 129 struct { 130 ${{OUTTYPE}} val; 131 } x; 132 133 x.val = ${{STRUCTVALUE}}; 134 135 out0 = ${{EXPR}}; 136 ${OUTPUT} 137 } 138 "" 139end 140""".strip() 141 142INVALID_CASE_TEMPLATE = """ 143case ${{NAME}} 144 expect compile_fail 145 version 310 es 146 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 147 values 148 { 149 ${{VALUES}} 150 } 151 152 both "" 153 #version 310 es 154 precision highp float; 155 ${DECLARATIONS} 156 157 void main() 158 { 159 ${SETUP} 160 out0 = in0 + ${{OPERAND}}; 161 ${OUTPUT} 162 } 163 "" 164end 165""".strip() 166 167INVALID_ARRAY_CASE_TEMPLATE = """ 168case ${{NAME}} 169 expect compile_fail 170 version 310 es 171 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 172 values {} 173 174 both "" 175 #version 310 es 176 precision highp float; 177 ${DECLARATIONS} 178 179 void main() 180 { 181 ${SETUP} 182 ${{EXPR}} 183 ${OUTPUT} 184 } 185 "" 186end 187""".strip() 188 189INVALID_STRUCT_CASE_TEMPLATE = """ 190case ${{NAME}} 191 expect compile_fail 192 version 310 es 193 require extension { "GL_EXT_shader_implicit_conversions" } in { vertex, fragment } 194 values {} 195 196 both "" 197 #version 310 es 198 precision highp float; 199 ${DECLARATIONS} 200 201 void main() 202 { 203 ${SETUP} 204 struct { ${{INTYPE}} value; } a; 205 struct { ${{OUTTYPE}} value; } b; 206 a = ${{INVALUE}}; 207 b = a; 208 ${OUTPUT} 209 } 210 "" 211end 212""".strip() 213 214 215# Input values 216 217IN_ISCALAR = [ 2, 1, 1, 3, 5 ] 218IN_USCALAR = [ 1, 3, 4, 7, 11 ] 219 220IN_IVECTOR = [ 221 ( 1, 2, 3, 4), 222 ( 2, 1, 2, 6), 223 ( 3, 7, 2, 5), 224] 225 226IN_UVECTOR = [ 227 ( 2, 3, 5, 8), 228 ( 4, 6, 2, 9), 229 ( 1, 13, 7, 4), 230] 231 232IN_VALUES = { 233 "int": [Scalar(x) for x in IN_ISCALAR], 234 "uint": [Scalar(x) for x in IN_USCALAR], 235 "ivec2": [Vec2(x[0], x[1]) for x in IN_IVECTOR], 236 "uvec2": [Vec2(x[0], x[1]) for x in IN_UVECTOR], 237 "ivec3": [Vec3(x[0], x[1], x[2]) for x in IN_IVECTOR], 238 "uvec3": [Vec3(x[0], x[1], x[2]) for x in IN_UVECTOR], 239 "ivec4": [Vec4(x[0], x[1], x[2], x[3]) for x in IN_IVECTOR], 240 "uvec4": [Vec4(x[0], x[1], x[2], x[3]) for x in IN_UVECTOR], 241 "float": [Scalar(x).toFloat() for x in IN_ISCALAR], 242 "vec2": [Vec2(x[0], x[1]).toFloat() for x in IN_IVECTOR], 243 "vec3": [Vec3(x[0], x[1], x[2]).toFloat() for x in IN_IVECTOR], 244 "vec4": [Vec4(x[0], x[1], x[2], x[3]).toFloat() for x in IN_IVECTOR], 245} 246 247VALID_CONVERSIONS = { 248 "int": ["float", "uint"], 249 "uint": ["float"], 250 "ivec2": ["uvec2", "vec2"], 251 "uvec2": ["vec2"], 252 "ivec3": ["uvec3", "vec3"], 253 "uvec3": ["vec3"], 254 "ivec4": ["uvec4", "vec4"], 255 "uvec4": ["vec4"] 256} 257 258SCALAR_TO_VECTOR_CONVERSIONS = { 259 "int": ["vec2", "vec3", "vec4", "uvec2", "uvec3", "uvec4"], 260 "uint": ["vec2", "vec3", "vec4"] 261} 262 263VALID_ASSIGNMENTS = { 264 "int": ["ivec2", "ivec3", "ivec4"], 265 "uint": ["uvec2", "uvec3", "uvec4"], 266 "ivec2": ["int", "float"], 267 "ivec3": ["int", "float"], 268 "ivec4": ["int", "float"], 269 "uvec2": ["uint", "float"], 270 "uvec3": ["uint", "float"], 271 "uvec4": ["uint", "float"], 272 "float": ["vec2", "vec3", "vec4"], 273 "vec2": ["float"], 274 "vec3": ["float"], 275 "vec4": ["float"] 276} 277 278IN_TYPE_ORDER = [ 279 "int", "uint", 280 "ivec2", "uvec2", "ivec3", 281 "uvec3", "ivec4", "uvec4", 282 283 "float", 284 "vec2", "vec3", "vec4" 285] 286 287def isScalarTypeName (name): 288 return name in ["float", "int", "uint"] 289 290def isVec2TypeName (name): 291 return name in ["vec2", "ivec2", "uvec2"] 292 293def isVec3TypeName (name): 294 return name in ["vec3", "ivec3", "uvec3"] 295 296def isVec4TypeName (name): 297 return name in ["vec4", "ivec4", "uvec4"] 298 299# Utilities 300 301def scalarToVector(a, b): 302 if isinstance(a, Scalar) and isinstance(b, Vec2): 303 a = a.toVec2() 304 elif isinstance(a, Scalar) and isinstance(b, Vec3): 305 a = a.toVec3() 306 elif isinstance(a, Scalar) and isinstance(b, Vec4): 307 a = a.toVec4() 308 return a 309 310def isUintTypeName (type_name): 311 return type_name in ["uint", "uvec2", "uvec3", "uvec4"] 312 313def convLiteral (type, value): 314 if isUintTypeName(type): 315 return int(value) 316 else: 317 return value 318 319def valueToStr(value_type, value): 320 if isinstance(value, Scalar): 321 return str(value) 322 else: 323 assert isinstance(value, genutil.Vec) 324 out = value_type + "(" 325 out += ", ".join([str(convLiteral(value_type, x)) for x in value.getScalars()]) 326 out += ")" 327 return out 328 329 330def valuesToStr(prefix, value_type, values): 331 def gen_value_strs(value_list, value_type): 332 for value in value_list: 333 yield valueToStr(value_type, value) 334 return "%s = [ %s ];" % (prefix, " | ".join(gen_value_strs(values, value_type))) 335 336 337# Test cases 338 339class ArithmeticCase(genutil.ShaderCase): 340 def __init__(self, name, op, in_type, out_type, reverse=False): 341 self.op_func = { 342 "+": operator.add, 343 "-": operator.sub, 344 "*": operator.mul, 345 "/": operator.div, 346 } 347 self.name = name 348 self.op = op 349 self.in_type = in_type 350 self.out_type = out_type 351 self.reverse = reverse 352 353 def __str__(self): 354 params = { 355 "NAME": self.name, 356 "EXPR": self.get_expr(), 357 "VALUES": self.gen_values(), 358 } 359 return genutil.fillTemplate(ARTIHMETIC_CASE_TEMPLATE, params) 360 361 def apply(self, a, b): 362 assert(self.op in self.op_func) 363 a = scalarToVector(a, b) 364 365 if self.reverse: 366 b, a = a, b 367 368 return self.op_func[self.op](a, b) 369 370 def get_expr(self): 371 expr = ["in0", self.op, str(self.get_operand())] 372 373 if self.reverse: 374 expr.reverse() 375 376 return " ".join(expr) 377 378 def get_operand(self): 379 operands = { 380 "float": Scalar(2.0), 381 "vec2": Vec2(1.0, 2.0), 382 "vec3": Vec3(1.0, 2.0, 3.0), 383 "vec4": Vec4(1.0, 2.0, 3.0, 4.0), 384 "uint": Uint(2), 385 "uvec2": UVec2(1, 2), 386 "uvec3": UVec3(1, 2, 3), 387 "uvec4": UVec4(1, 2, 3, 4), 388 } 389 assert self.out_type in operands 390 return operands[self.out_type] 391 392 def gen_values(self): 393 in_values = IN_VALUES[self.in_type] 394 395 y = self.get_operand() 396 out_values = [self.apply(x, y) for x in in_values] 397 398 out = [] 399 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 400 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 401 402 return "\n".join(out) 403 404 405class ComparisonsCase(ArithmeticCase): 406 def __init__(self, name, op, in_type, out_type, reverse=False): 407 super(ComparisonsCase, self).__init__(name, op, in_type, out_type, reverse) 408 409 self.op_func = { 410 "==": operator.eq, 411 "!=": operator.ne, 412 "<": operator.lt, 413 ">": operator.gt, 414 "<=": operator.le, 415 ">=": operator.ge, 416 } 417 418 def apply(self, a, b): 419 assert(self.op in self.op_func) 420 421 if isinstance(a, Scalar) and isinstance(b, Scalar): 422 a, b = float(a), float(b) 423 424 if self.reverse: 425 b, a = a, b 426 427 return Scalar(self.op_func[self.op](a, b)) 428 429 def gen_values(self): 430 in_values = IN_VALUES[self.in_type] 431 432 y = self.get_operand() 433 out_values = [self.apply(x, y) for x in in_values] 434 435 out = [] 436 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 437 out.append(valuesToStr("output bool out0", "bool", out_values)) 438 439 return "\n".join(out) 440 441 442class ParenthesizedCase(genutil.ShaderCase): 443 def __init__(self, name, in_type, out_type, reverse=False, input_in_parens=False): 444 self.name = name 445 self.in_type = in_type 446 self.out_type = out_type 447 self.reverse = reverse 448 self.input_in_parens = input_in_parens 449 450 def __str__(self): 451 params = { 452 "NAME": self.name, 453 "EXPR": self.get_expr(), 454 "VALUES": self.gen_values(), 455 } 456 return genutil.fillTemplate(ARTIHMETIC_CASE_TEMPLATE, params) 457 458 def apply(self, a): 459 b, c = self.get_operand(0), self.get_operand(1) 460 a = scalarToVector(a, b) 461 462 if self.input_in_parens: 463 return b*(a+c) 464 else: 465 return a*(b+c) 466 467 def get_expr(self): 468 def make_paren_expr(): 469 out = [ 470 "in0" if self.input_in_parens else self.get_operand(0), 471 "+", 472 self.get_operand(1) 473 ] 474 return "(%s)" % (" ".join([str(x) for x in out])) 475 476 expr = [ 477 "in0" if not self.input_in_parens else self.get_operand(0), 478 "*", 479 make_paren_expr() 480 ] 481 482 if self.reverse: 483 expr.reverse() 484 485 return " ".join([str(x) for x in expr]) 486 487 def get_operand(self, ndx=0): 488 return IN_VALUES[self.out_type][ndx] 489 490 def gen_values(self): 491 in_values = IN_VALUES[self.in_type] 492 493 out_values = [self.apply(x) for x in in_values] 494 495 out = [] 496 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 497 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 498 499 return "\n".join(out) 500 501 502class FunctionsCase(genutil.ShaderCase): 503 def __init__(self, name, in_type, out_type): 504 self.name = name 505 self.in_type = in_type 506 self.out_type = out_type 507 508 def __str__(self): 509 params = { 510 "NAME": self.name, 511 "OUTTYPE": self.out_type, 512 "VALUES": self.gen_values(), 513 } 514 return genutil.fillTemplate(FUNCTIONS_CASE_TEMPLATE, params) 515 516 def apply(self, a): 517 if isUintTypeName(self.out_type): 518 return a.toUint() * Uint(2) 519 else: 520 return a.toFloat() * Scalar(2.0) 521 522 def gen_values(self): 523 in_values = IN_VALUES[self.in_type] 524 out_values = [self.apply(x) for x in in_values] 525 526 out = [] 527 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 528 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 529 530 return "\n".join(out) 531 532 533class ArrayCase(genutil.ShaderCase): 534 def __init__(self, name, in_type, out_type, reverse=False): 535 self.name = name 536 self.in_type = in_type 537 self.out_type = out_type 538 self.reverse = reverse 539 540 def __str__(self): 541 params = { 542 "NAME": self.name, 543 "VALUES": self.gen_values(), 544 "ARRAYTYPE": self.out_type, 545 "ARRAYVALUES": self.gen_array_values(), 546 "EXPR": self.get_expr(), 547 } 548 return genutil.fillTemplate(ARRAY_CASE_TEMPLATE, params) 549 550 def apply(self, a): 551 b = IN_VALUES[self.out_type][1] 552 a = scalarToVector(a, b) 553 554 return a + b 555 556 def get_expr(self): 557 if not self.reverse: 558 return "in0 + x[1]" 559 else: 560 return "x[1] + in0" 561 562 def gen_values(self): 563 in_values = IN_VALUES[self.in_type] 564 out_values = [self.apply(x) for x in in_values] 565 566 out = [] 567 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 568 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 569 570 return "\n".join(out) 571 572 def gen_array_values(self): 573 out = [valueToStr(self.out_type, x) for x in IN_VALUES[self.out_type]] 574 return ", ".join(out) 575 576 577class ArrayUnpackCase(genutil.ShaderCase): 578 def __init__(self, name, in_type, out_type): 579 self.name = name 580 self.in_type = in_type 581 self.out_type = out_type 582 583 def __str__(self): 584 params = { 585 "NAME": self.name, 586 "VALUES": self.gen_values(), 587 "ARRAYTYPE": "float", 588 "ARRAYVALUES": self.gen_array_values(), 589 "EXPR": self.get_expr(), 590 } 591 return genutil.fillTemplate(ARRAY_CASE_TEMPLATE, params) 592 593 def apply(self, a): 594 if isinstance(a, Scalar) and isVec2TypeName(self.out_type): 595 a = a.toVec2() 596 elif isinstance(a, Scalar) and isVec3TypeName(self.out_type): 597 a = a.toVec3() 598 elif isinstance(a, Scalar) and isVec4TypeName(self.out_type): 599 a = a.toVec4() 600 601 b = IN_VALUES["float"] 602 603 out = [Scalar(x)+y for x, y in zip(a.getScalars(), b)] 604 605 if self.out_type == "float": 606 return out[0].toFloat() 607 elif self.out_type == "uint": 608 return out[0].toUint() 609 elif self.out_type == "vec2": 610 return Vec2(out[0], out[1]).toFloat() 611 elif self.out_type == "uvec2": 612 return Vec2(out[0], out[1]).toUint() 613 elif self.out_type == "vec3": 614 return Vec3(out[0], out[1], out[2]).toFloat() 615 elif self.out_type == "uvec3": 616 return Vec3(out[0], out[1], out[2]).toUint() 617 elif self.out_type == "vec4": 618 return Vec4(out[0], out[1], out[2], out[3]).toFloat() 619 elif self.out_type == "uvec4": 620 return Vec4(out[0], out[1], out[2], out[3]).toUint() 621 622 def get_expr(self): 623 def num_scalars(typename): 624 return IN_VALUES[typename][0].getNumScalars() 625 626 def gen_sums(): 627 in_scalars = num_scalars(self.in_type) 628 out_scalars = num_scalars(self.out_type) 629 630 for ndx in range(out_scalars): 631 if in_scalars > 1: 632 yield "in0[%i] + x[%i]" % (ndx, ndx) 633 else: 634 yield "in0 + x[%i]" % (ndx) 635 636 return "%s(%s)" % (self.out_type, ", ".join(gen_sums())) 637 638 def gen_values(self): 639 in_values = IN_VALUES[self.in_type] 640 out_values = [self.apply(x) for x in in_values] 641 642 out = [] 643 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 644 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 645 646 return "\n".join(out) 647 648 def gen_array_values(self): 649 out = [valueToStr(self.out_type, x) for x in IN_VALUES["float"]] 650 return ", ".join(out) 651 652 653class StructCase(genutil.ShaderCase): 654 def __init__(self, name, in_type, out_type, reverse=False): 655 self.name = name 656 self.in_type = in_type 657 self.out_type = out_type 658 self.reverse = reverse 659 660 def __str__(self): 661 params = { 662 "NAME": self.name, 663 "VALUES": self.gen_values(), 664 "OUTTYPE": self.out_type, 665 "STRUCTVALUE": self.get_struct_value(), 666 "EXPR": self.get_expr(), 667 } 668 return genutil.fillTemplate(STRUCT_CASE_TEMPLATE, params) 669 670 def apply(self, a): 671 if isinstance(a, Scalar) and isVec2TypeName(self.out_type): 672 a = a.toVec2() 673 elif isinstance(a, Scalar) and isVec3TypeName(self.out_type): 674 a = a.toVec3() 675 elif isinstance(a, Scalar) and isVec4TypeName(self.out_type): 676 a = a.toVec4() 677 678 b = IN_VALUES[self.out_type][0] 679 680 return a + b 681 682 def get_expr(self): 683 if not self.reverse: 684 return "in0 + x.val" 685 else: 686 return "x.val + in0" 687 688 def gen_values(self): 689 in_values = IN_VALUES[self.in_type] 690 out_values = [self.apply(x) for x in in_values] 691 692 out = [] 693 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 694 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 695 696 return "\n".join(out) 697 698 def get_struct_value(self): 699 return valueToStr(self.out_type, IN_VALUES[self.out_type][0]) 700 701 702class InvalidCase(genutil.ShaderCase): 703 def __init__(self, name, in_type, out_type): 704 self.name = name 705 self.in_type = in_type 706 self.out_type = out_type 707 708 def __str__(self): 709 params = { 710 "NAME": self.name, 711 "OPERAND": str(self.get_operand()), 712 "VALUES": self.gen_values(), 713 } 714 return genutil.fillTemplate(INVALID_CASE_TEMPLATE, params) 715 716 def apply(self, a, b): 717 return b 718 719 def get_operand(self): 720 return IN_VALUES[self.out_type][0] 721 722 def gen_values(self): 723 in_values = IN_VALUES[self.in_type] 724 725 y = self.get_operand() 726 out_values = [self.apply(x, y) for x in in_values] 727 728 out = [] 729 out.append(valuesToStr("input %s in0" % (self.in_type), self.in_type, in_values)) 730 out.append(valuesToStr("output %s out0" % (self.out_type), self.out_type, out_values)) 731 732 return "\n".join(out) 733 734 735class InvalidArrayCase(genutil.ShaderCase): 736 def __init__(self, name, in_type, out_type): 737 self.name = name 738 self.in_type = in_type 739 self.out_type = out_type 740 741 def __str__(self): 742 params = { 743 "NAME": self.name, 744 "EXPR": self.gen_expr(), 745 } 746 return genutil.fillTemplate(INVALID_ARRAY_CASE_TEMPLATE, params) 747 748 def gen_expr(self): 749 in_values = [valueToStr(self.out_type, x) for x in IN_VALUES[self.in_type]] 750 751 out = "%s a[] = %s[] (%s);" % (self.out_type, self.in_type, ", ".join(in_values)) 752 753 return out 754 755 756class InvalidStructCase(genutil.ShaderCase): 757 def __init__(self, name, in_type, out_type): 758 self.name = name 759 self.in_type = in_type 760 self.out_type = out_type 761 762 def __str__(self): 763 params = { 764 "NAME": self.name, 765 "INTYPE": self.in_type, 766 "OUTTYPE": self.out_type, 767 "INVALUE": self.get_value(), 768 } 769 return genutil.fillTemplate(INVALID_STRUCT_CASE_TEMPLATE, params) 770 771 def get_value(self): 772 return valueToStr(self.in_type, IN_VALUES[self.in_type][0]) 773 774 775# Case file generation 776 777def genConversionPairs(order=IN_TYPE_ORDER, scalar_to_vector=True, additional={}): 778 def gen_order(conversions): 779 key_set = set(conversions.iterkeys()) 780 for typename in order: 781 if typename in key_set: 782 yield typename 783 conversions = {} 784 785 for in_type in VALID_CONVERSIONS: 786 conversions[in_type] = [] + VALID_CONVERSIONS[in_type] 787 if in_type in SCALAR_TO_VECTOR_CONVERSIONS and scalar_to_vector: 788 conversions[in_type] += SCALAR_TO_VECTOR_CONVERSIONS[in_type] 789 790 for key in additional.iterkeys(): 791 value = conversions.get(key, []) 792 conversions[key] = value + additional[key] 793 794 for in_type in gen_order(conversions): 795 for out_type in conversions[in_type]: 796 yield (in_type, out_type) 797 798 799def genInvalidConversions(): 800 types = IN_TYPE_ORDER 801 valid_pairs = set(genConversionPairs(additional=VALID_ASSIGNMENTS)) 802 803 for pair in itertools.permutations(types, 2): 804 if pair not in valid_pairs: 805 yield pair 806 807 808def genArithmeticCases(reverse=False): 809 op_names = [ 810 ("add", "Addition", "+"), 811 ("sub", "Subtraction", "-"), 812 ("mul", "Multiplication", "*"), 813 ("div", "Division", "/") 814 ] 815 816 for name, desc, op in op_names: 817 casegroup = CaseGroup(name, desc, []) 818 for in_type, out_type in genConversionPairs(): 819 if op == "-" and isUintTypeName(out_type): 820 continue # Can't handle at the moment 821 name = in_type + "_to_" + out_type 822 casegroup.children.append(ArithmeticCase(name, op, in_type, out_type, reverse)) 823 yield casegroup 824 825 826def genComparisonCases(reverse=False): 827 op_names = [ 828 ("equal", "Equal", "=="), 829 ("not_equal", "Not equal", "!="), 830 ("less", "Less than", "<"), 831 ("greater", "Greater than", ">"), 832 ("less_or_equal", "Less than or equal", "<="), 833 ("greater_or_equal", "Greater than or equal", ">="), 834 ] 835 836 for name, desc, op in op_names: 837 casegroup = CaseGroup(name, desc, []) 838 type_order = IN_TYPE_ORDER if name in ["equal", "not_equal"] else ["int", "uint"] 839 840 for in_type, out_type in genConversionPairs(order=type_order, scalar_to_vector=False): 841 name = in_type + "_to_" + out_type 842 casegroup.children.append(ComparisonsCase(name, op, in_type, out_type, reverse)) 843 yield casegroup 844 845 846def genParenthesizedCases(): 847 for reverse in [True, False]: 848 if reverse: 849 name = "paren_expr_before_literal" 850 desc = "Parenthesized expression before literal" 851 else: 852 name = "literal_before_paren_expr" 853 desc = "Literal before parenthesized expression" 854 reversegroup = CaseGroup(name, desc, []) 855 856 for input_in_parens in [True, False]: 857 if input_in_parens: 858 name = "input_in_parens" 859 desc = "Input variable in parenthesized expression" 860 else: 861 name = "input_outside_parens" 862 desc = "Input variable outside parenthesized expression" 863 casegroup = CaseGroup(name, desc, []) 864 865 for in_type, out_type in genConversionPairs(): 866 name = in_type + "_to_" + out_type 867 casegroup.children.append( 868 ParenthesizedCase(name, in_type, out_type, reverse, input_in_parens) 869 ) 870 reversegroup.children.append(casegroup) 871 yield reversegroup 872 873 874def genArrayCases(reverse=False): 875 for in_type, out_type in genConversionPairs(): 876 name = in_type + "_to_" + out_type 877 yield ArrayCase(name, in_type, out_type, reverse) 878 879 880def genArrayUnpackCases(reverse=False): 881 for in_type, out_type in genConversionPairs(): 882 name = in_type + "_to_" + out_type 883 yield ArrayUnpackCase(name, in_type, out_type) 884 885 886def genFunctionsCases(): 887 for in_type, out_type in genConversionPairs(scalar_to_vector=False): 888 name = in_type + "_to_" + out_type 889 yield FunctionsCase(name, in_type, out_type) 890 891 892def genStructCases(reverse=False): 893 for in_type, out_type in genConversionPairs(): 894 name = in_type + "_to_" + out_type 895 yield StructCase(name, in_type, out_type, reverse) 896 897 898def genInvalidCases(reverse=False): 899 for in_type, out_type in genInvalidConversions(): 900 name = in_type + "_to_" + out_type 901 yield InvalidCase(name, in_type, out_type) 902 903 904def genInvalidArrayCases(): 905 for in_type, out_type in genConversionPairs(scalar_to_vector=False): 906 name = in_type + "_to_" + out_type 907 yield InvalidArrayCase(name, in_type, out_type) 908 909 910def genInvalidStructCases(): 911 for in_type, out_type in genConversionPairs(scalar_to_vector=False): 912 name = in_type + "_to_" + out_type 913 yield InvalidStructCase(name, in_type, out_type) 914 915 916def genAllCases(): 917 yield CaseGroup( 918 "arithmetic", "Arithmetic operations", 919 [ 920 CaseGroup("input_before_literal", "Input before literal", 921 genArithmeticCases(reverse=False)), 922 CaseGroup("literal_before_input", "Literal before input", 923 genArithmeticCases(reverse=True)), 924 ] 925 ) 926 927 yield CaseGroup( 928 "comparisons", "Comparisons", 929 [ 930 CaseGroup("input_before_literal", "Input before literal", 931 genComparisonCases(reverse=False)), 932 CaseGroup("literal_before_input", "Literal before input", 933 genComparisonCases(reverse=True)), 934 ] 935 ) 936 937 yield CaseGroup( 938 "array_subscripts", "Array subscripts", 939 [ 940 CaseGroup("input_before_subscript", "Input before subscript", 941 genArrayCases(reverse=False)), 942 CaseGroup("subscript_before_input", "Subscript before input", 943 genArrayCases(reverse=True)), 944 # CaseGroup("unpack", "Unpack array and repack as value", 945 # genArrayUnpackCases()), 946 ] 947 ) 948 949 yield CaseGroup("functions", "Function calls", 950 genFunctionsCases()) 951 952 yield CaseGroup("struct_fields", "Struct field selectors", 953 [ 954 CaseGroup("input_before_field", "Input before field", 955 genStructCases(reverse=False)), 956 CaseGroup("field_before_input", "Field before input", 957 genStructCases(reverse=True)), 958 ] 959 ) 960 961 yield CaseGroup("parenthesized_expressions", "Parenthesized expressions", 962 genParenthesizedCases()) 963 964 yield CaseGroup( 965 "invalid", "Invalid conversions", 966 [ 967 CaseGroup("variables", "Single variables", 968 genInvalidCases()), 969 CaseGroup("arrays", "Arrays", 970 genInvalidArrayCases()), 971 CaseGroup("structs", "Structs", 972 genInvalidStructCases()), 973 ] 974 ) 975 976 977if __name__ == "__main__": 978 print("Generating shader case files.") 979 genutil.writeAllCases("implicit_conversions.test", genAllCases()) 980