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