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 values 104 { 105 ${{VALUES}} 106 } 107 108 both "" 109 precision mediump float; 110 111 ${DECLARATIONS} 112 113 void main() 114 { 115 ${SETUP} 116 ${{OP}} 117 ${OUTPUT} 118 } 119 "" 120end 121"""[1:] 122 123s_simpleIllegalCaseTemplate = """ 124case ${{NAME}} 125 expect compile_fail 126 values {} 127 128 both "" 129 precision mediump float; 130 precision mediump int; 131 132 ${DECLARATIONS} 133 134 void main() 135 { 136 ${SETUP} 137 ${{OP}} 138 ${OUTPUT} 139 } 140 "" 141end 142"""[1:] 143 144class SwizzleCase(ShaderCase): 145 def __init__(self, name, precision, dataType, swizzle, inputs, outputs): 146 self.name = name 147 self.precision = precision 148 self.dataType = dataType 149 self.swizzle = swizzle 150 self.inputs = inputs 151 self.outputs = outputs 152 self.op = "out0 = in0.%s;" % swizzle 153 154 def __str__(self): 155 params = { 156 "NAME": self.name, 157 "VALUES": genValues(self.inputs, self.outputs), 158 "OP": self.op 159 } 160 return fillTemplate(s_swizzleCaseTemplate, params) 161 162# CASE DECLARATIONS 163 164inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]] 165inInt = [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]] 166inBool = [Scalar(x) for x in [True, False]] 167 168inVec4 = [Vec4(0.0, 0.5, 0.75, 0.825), Vec4(1.0, 1.25, 1.125, 1.75), 169 Vec4(-0.5, -2.25, -4.875, 9.0), Vec4(-32.0, 64.0, -51.0, 24.0), 170 Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0)] 171inVec3 = toVec3(inVec4) 172inVec2 = toVec2(inVec4) 173inIVec4 = toIVec4(inVec4) 174inIVec3 = toIVec3(inVec4) 175inIVec2 = toIVec2(inVec4) 176inBVec4 = [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)] 177inBVec3 = toBVec3(inBVec4) 178inBVec2 = toBVec2(inBVec4) 179 180# \todo [petri] Enable large values when epsilon adapts to the values. 181inMat4 = [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), 182 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), 183 #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) 184 ] 185inMat3 = [Mat3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0), 186 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), 187 #Mat3(-18.725, -0.5, -0.0125, 19.975, -0.25, -17.75, 9.25, 65.125, -21.425), 188 #Mat3(128.0, -4096.0, -8192.0, 192.0, 768.0, -1536.0, 8192.0, 6144.0, -6144.0) 189 ] 190inMat2 = [Mat2(1.0, 0.0, 0.0, 1.0), 191 Mat2(6.5, 12.5, -0.75, 9.975), 192 Mat2(6.5, 12.5, -0.75, 9.975), 193 Mat2(8.0, 16.0, -24.0, -16.0), 194 Mat2(1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0), 195 Mat2(-18.725, -0.5, -0.0125, 19.975), 196 #Mat2(128.0, -4096.0, 192.0, -1536.0), 197 #Mat2(-1536.0, 8192.0, 6144.0, -6144.0) 198 ] 199 200INPUTS = { 201 "float": inFloat, 202 "vec2": inVec2, 203 "vec3": inVec3, 204 "vec4": inVec4, 205 "int": inInt, 206 "ivec2": inIVec2, 207 "ivec3": inIVec3, 208 "ivec4": inIVec4, 209 "bool": inBool, 210 "bvec2": inBVec2, 211 "bvec3": inBVec3, 212 "bvec4": inBVec4, 213 "mat2": inMat2, 214 "mat3": inMat3, 215 "mat4": inMat4 216} 217 218def genConversionCases(inValueList, convFuncList): 219 combinations = list(itertools.product(inValueList, convFuncList)) 220 return [ConversionCase(inValues, convFunc) for (inValues, convFunc) in combinations] 221 222allCases = [] 223 224# Vector swizzles. 225 226vectorSwizzleCases = [] 227 228# \todo [petri] Uses fixed precision. 229for dataType in VECTOR_TYPES: 230 scalarSize = getDataTypeScalarSize(dataType) 231 precision = "mediump" 232 for swizzleComponents in SWIZZLE_NAMES: 233 for swizzleIndices in getSwizzlesForWidth(scalarSize): 234 swizzle = "".join(map(lambda x: swizzleComponents[x], swizzleIndices)) 235 #print "%s %s .%s" % (precision, dataType, swizzle) 236 caseName = "%s_%s_%s" % (precision, dataType, swizzle) 237 inputs = INPUTS[dataType] 238 outputs = map(lambda x: x.swizzle(swizzleIndices), inputs) 239 outType = outputs[0].typeString() 240 vectorSwizzleCases.append(SwizzleCase(caseName, precision, dataType, swizzle, [("%s in0" % dataType, inputs)], [("%s out0" % outType, outputs)])) 241 242# ?? 243#for dataType in VECTOR_TYPES: 244# scalarSize = getDataTypeScalarSize(dataType) 245# for precision in PRECISION_TYPES: 246# for swizzleIndices in getSwizzlesForWidth(scalarSize): 247# swizzle = "".join(map(lambda x: "xyzw"[x], swizzleIndices)) 248# #print "%s %s .%s" % (precision, dataType, swizzle) 249# caseName = "%s_%s_%s" % (precision, dataType, swizzle) 250# inputs = INPUTS[dataType] 251# outputs = map(lambda x: x.swizzle(swizzleIndices), inputs) 252# vectorSwizzleCases.append(SwizzleCase(caseName, precision, dataType, swizzle, [("in0", inputs)], [("out0", outputs)])) 253 254allCases.append(CaseGroup("vector_swizzles", "Vector Swizzles", vectorSwizzleCases)) 255 256# Swizzles: 257# - vector components 258# * int, float, bool vectors 259# * .xyzw, .rgba, .stpq 260# * illegal to mix 261# * not allowed for scalar types 262# * legal to chain: vec4.rgba.xyzw.stpq 263# * illegal to select more than 4 components 264 265# TODO: precisions!! 266 267#allCases.append(CaseGroup("vector_swizzles", "Vector Swizzles", 268# genSwizzleCase([inVec2, inVec3, inVec4], 269 270# Main program. 271 272if __name__ == "__main__": 273 print "Generating shader case files." 274 writeAllCases("swizzles.test", allCases) 275