1import sys 2import random 3import operator 4import itertools 5 6from genutil import * 7 8random.seed(1234567) 9indices = xrange(sys.maxint) 10 11# Swizzles: 12# - vector components 13# * int, float, bool vectors 14# * .xyzw, .rgba, .stpq 15# * illegal to mix 16# * not allowed for scalar types 17# * legal to chain: vec4.rgba.xyzw.stpq 18# * illegal to select more than 4 components 19# 20# Subscripts: 21# - array-like indexing with [] operator 22# * vectors, matrices 23# - read & write 24# - vectors components 25# * [] accessor 26# - matrix columns 27# * [] accessor 28# * note: mat4[0].x = 1.0; vs mat4[0][0] = 1.0; ?? 29# * out-of-bounds accesses 30 31# 32# - vector swizzles 33# * all vector types (bvec2..4, ivec2..4, vec2..4) 34# * all precisions (lowp, mediump, highp) 35# * all component names (xyzw, rgba, stpq) 36# * broadcast each, reverse, N random 37# - component-masked writes 38# * all vector types (bvec2..4, ivec2..4, vec2..4) 39# * all precisions (lowp, mediump, highp) 40# * all component names (xyzw, rgba, stpq) 41# * all possible subsets 42# * all input types (attribute, varying, uniform, tmp) 43# -> a few hundred cases 44# - concatenated swizzles 45 46# 47VECTOR_TYPES = [ "vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4", "bvec2", "bvec3", "bvec4" ] 48PRECISION_TYPES = [ "lowp", "mediump", "highp" ] 49INPUT_TYPES = [ "uniform", "varying", "attribute", "tmp" ] 50SWIZZLE_NAMES = [ "xyzw", "stpq", "rgba" ] 51 52def getDataTypeScalarSize (dt): 53 return { 54 "float": 1, 55 "vec2": 2, 56 "vec3": 3, 57 "vec4": 4, 58 "int": 1, 59 "ivec2": 2, 60 "ivec3": 3, 61 "ivec4": 4, 62 "bool": 1, 63 "bvec2": 2, 64 "bvec3": 3, 65 "bvec4": 4, 66 "mat2": 4, 67 "mat3": 9, 68 "mat4": 16 69 }[dt] 70 71if False: 72 class Combinations: 73 def __init__(self, *args): 74 self.lists = list(args) 75 self.numLists = len(args) 76 self.numCombinations = reduce(operator.mul, map(len, self.lists), 1) 77 print self.lists 78 print self.numCombinations 79 80 def iterate(self): 81 return [tuple(map(lambda x: x[0], self.lists))] 82 83 combinations = Combinations(INPUT_TYPES, VECTOR_TYPES, PRECISION_TYPES) 84 print combinations.iterate() 85 for (inputType, dataType, precision) in combinations.iterate(): 86 scalarSize = getDataTypeScalarSize(dataType) 87 print inputType, precision, dataType 88 89def getSwizzlesForWidth(width): 90 if (width == 2): 91 return [(0,), (0,0), (0,1), (1,0), (1,0,1), (0,1,0,0), (1,1,1,1)] 92 elif (width == 3): 93 return [(0,), (2,), (0,2), (2,2), (0,1,2), (2,1,0), (0,0,0), (2,2,2), (2,2,1), (1,0,1), (0,2,0), (0,1,1,0), (2,2,2,2)] 94 elif (width == 4): 95 return [(0,), (3,), (3,0), (3,2), (3,3,3), (1,1,3), (3,2,1), (0,1,2,3), (3,2,1,0), (0,0,0,0), (1,1,1,1), (3,3,3,3), (3,2,2,3), (3,3,3,1), (0,1,0,0), (2,2,3,2)] 96 else: 97 assert False 98 99# Templates. 100 101s_swizzleCaseTemplate = """ 102case ${{NAME}} 103 version 300 104 values 105 { 106 ${{VALUES}} 107 } 108 109 both "" 110 #version 300 es 111 precision mediump float; 112 113 ${DECLARATIONS} 114 115 void main() 116 { 117 ${SETUP} 118 ${{OP}} 119 ${OUTPUT} 120 } 121 "" 122end 123"""[1:] 124 125s_simpleIllegalCaseTemplate = """ 126case ${{NAME}} 127 version 300 128 expect compile_fail 129 values {} 130 131 both "" 132 #version 300 es 133 precision mediump float; 134 precision mediump int; 135 136 ${DECLARATIONS} 137 138 void main() 139 { 140 ${SETUP} 141 ${{OP}} 142 ${OUTPUT} 143 } 144 "" 145end 146"""[1:] 147 148class SwizzleCase(ShaderCase): 149 def __init__(self, name, precision, dataType, swizzle, inputs, outputs): 150 self.name = name 151 self.precision = precision 152 self.dataType = dataType 153 self.swizzle = swizzle 154 self.inputs = inputs 155 self.outputs = outputs 156 self.op = "out0 = in0.%s;" % swizzle 157 158 def __str__(self): 159 params = { 160 "NAME": self.name, 161 "VALUES": genValues(self.inputs, self.outputs), 162 "OP": self.op 163 } 164 return fillTemplate(s_swizzleCaseTemplate, params) 165 166# CASE DECLARATIONS 167 168inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]] 169inInt = [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]] 170inBool = [Scalar(x) for x in [True, False]] 171 172inVec4 = [Vec4(0.0, 0.5, 0.75, 0.825), Vec4(1.0, 1.25, 1.125, 1.75), 173 Vec4(-0.5, -2.25, -4.875, 9.0), Vec4(-32.0, 64.0, -51.0, 24.0), 174 Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0)] 175inVec3 = toVec3(inVec4) 176inVec2 = toVec2(inVec4) 177inIVec4 = toIVec4(inVec4) 178inIVec3 = toIVec3(inVec4) 179inIVec2 = toIVec2(inVec4) 180inBVec4 = [Vec4(True, False, False, True), Vec4(False, False, False, True), Vec4(False, True, False, False), Vec4(True, True, True, True), Vec4(False, False, False, False)] 181inBVec3 = toBVec3(inBVec4) 182inBVec2 = toBVec2(inBVec4) 183 184# \todo [petri] Enable large values when epsilon adapts to the values. 185inMat4 = [Mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), 186 Mat4(6.5, 12.5, -0.75, 9.975, 32.0, 1.0/48.0, -8.425, -6.542, 1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0, -6.725, -0.5, -0.0125, 9.975), 187 #Mat4(128.0, 256.0, -512.0, -1024.0, 2048.0, -4096.0, 8192.0, -8192.0, 192.0, -384.0, 768.0, -1536.0, 8192.0, -8192.0, 6144.0, -6144.0) 188 ] 189inMat3 = [Mat3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0), 190 Mat3(6.5, 12.5, -0.75, 32.0, 1.0/32.0, 1.0/64.0, 1.0/8.0, 1.0/16.0, 1.0/32.0), 191 #Mat3(-18.725, -0.5, -0.0125, 19.975, -0.25, -17.75, 9.25, 65.125, -21.425), 192 #Mat3(128.0, -4096.0, -8192.0, 192.0, 768.0, -1536.0, 8192.0, 6144.0, -6144.0) 193 ] 194inMat2 = [Mat2(1.0, 0.0, 0.0, 1.0), 195 Mat2(6.5, 12.5, -0.75, 9.975), 196 Mat2(6.5, 12.5, -0.75, 9.975), 197 Mat2(8.0, 16.0, -24.0, -16.0), 198 Mat2(1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0), 199 Mat2(-18.725, -0.5, -0.0125, 19.975), 200 #Mat2(128.0, -4096.0, 192.0, -1536.0), 201 #Mat2(-1536.0, 8192.0, 6144.0, -6144.0) 202 ] 203 204INPUTS = { 205 "float": inFloat, 206 "vec2": inVec2, 207 "vec3": inVec3, 208 "vec4": inVec4, 209 "int": inInt, 210 "ivec2": inIVec2, 211 "ivec3": inIVec3, 212 "ivec4": inIVec4, 213 "bool": inBool, 214 "bvec2": inBVec2, 215 "bvec3": inBVec3, 216 "bvec4": inBVec4, 217 "mat2": inMat2, 218 "mat3": inMat3, 219 "mat4": inMat4 220} 221 222def genConversionCases(inValueList, convFuncList): 223 combinations = list(itertools.product(inValueList, convFuncList)) 224 return [ConversionCase(inValues, convFunc) for (inValues, convFunc) in combinations] 225 226allCases = [] 227 228# Vector swizzles. 229 230vectorSwizzleCases = [] 231 232# \todo [petri] Uses fixed precision. 233for dataType in VECTOR_TYPES: 234 scalarSize = getDataTypeScalarSize(dataType) 235 precision = "mediump" 236 for swizzleComponents in SWIZZLE_NAMES: 237 for swizzleIndices in getSwizzlesForWidth(scalarSize): 238 swizzle = "".join(map(lambda x: swizzleComponents[x], swizzleIndices)) 239 #print "%s %s .%s" % (precision, dataType, swizzle) 240 caseName = "%s_%s_%s" % (precision, dataType, swizzle) 241 inputs = INPUTS[dataType] 242 outputs = map(lambda x: x.swizzle(swizzleIndices), inputs) 243 outType = outputs[0].typeString() 244 vectorSwizzleCases.append(SwizzleCase(caseName, precision, dataType, swizzle, [("%s in0" % dataType, inputs)], [("%s out0" % outType, outputs)])) 245 246# ?? 247#for dataType in VECTOR_TYPES: 248# scalarSize = getDataTypeScalarSize(dataType) 249# for precision in PRECISION_TYPES: 250# for swizzleIndices in getSwizzlesForWidth(scalarSize): 251# swizzle = "".join(map(lambda x: "xyzw"[x], swizzleIndices)) 252# #print "%s %s .%s" % (precision, dataType, swizzle) 253# caseName = "%s_%s_%s" % (precision, dataType, swizzle) 254# inputs = INPUTS[dataType] 255# outputs = map(lambda x: x.swizzle(swizzleIndices), inputs) 256# vectorSwizzleCases.append(SwizzleCase(caseName, precision, dataType, swizzle, [("in0", inputs)], [("out0", outputs)])) 257 258allCases.append(CaseGroup("vector_swizzles", "Vector Swizzles", vectorSwizzleCases)) 259 260# Swizzles: 261# - vector components 262# * int, float, bool vectors 263# * .xyzw, .rgba, .stpq 264# * illegal to mix 265# * not allowed for scalar types 266# * legal to chain: vec4.rgba.xyzw.stpq 267# * illegal to select more than 4 components 268 269# TODO: precisions!! 270 271#allCases.append(CaseGroup("vector_swizzles", "Vector Swizzles", 272# genSwizzleCase([inVec2, inVec3, inVec4], 273 274# Main program. 275 276if __name__ == "__main__": 277 print "Generating shader case files." 278 writeAllCases("swizzles.test", allCases) 279