1# -*- coding: utf-8 -*- 2 3#------------------------------------------------------------------------- 4# drawElements Quality Program utilities 5# -------------------------------------- 6# 7# Copyright 2017 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 operator as op 24from genutil import * 25from collections import OrderedDict 26 27VECTOR_TYPES = ["vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4"] 28PRECISION_TYPES = ["mediump"] 29SWIZZLE_NAMES = ["xyzw"] 30 31s_swizzleCaseTemplate = """ 32case ${{NAME}} 33 version 300 es 34 values 35 { 36 ${{VALUES}} 37 } 38 39 both "" 40 #version 300 es 41 precision mediump float; 42 43 ${DECLARATIONS} 44 45 void main() 46 { 47 ${SETUP} 48 ${{OP}} 49 ${OUTPUT} 50 } 51 "" 52end 53"""[1:] 54 55def getDataTypeScalarSize (dt): 56 return { 57 "vec2": 2, 58 "vec3": 3, 59 "vec4": 4, 60 "ivec2": 2, 61 "ivec3": 3, 62 "ivec4": 4, 63 }[dt] 64 65def getSwizzlesForWidth(width): 66 if (width == 2): 67 return [(0, ), 68 (0,0), (0,1), (1,0), 69 (1,0,1), (0,1,0,0), (1,0,1,0)] 70 elif (width == 3): 71 return [(0,), (2,), 72 (0,2), (2,2), 73 (0,1,2), (2,1,0), (0,0,0), (2,2,2), (2,2,1), (1,0,1), (0,2,0), 74 (0,1,1,0), (2,0,1,2)] 75 elif (width == 4): 76 return [(0,), (3,), 77 (3,0), (3,2), 78 (3,3,3), (1,1,3), (3,2,1), 79 (0,1,2,3), (3,2,1,0), (0,1,0,1), (1,2,2,1), (3,0,3,3), (0,1,0,0), (2,2,2,2)] 80 else: 81 assert False 82 83def operatorToSymbol(operator): 84 if operator == "add": return "+" 85 if operator == "subtract": return "-" 86 if operator == "multiply": return "*" 87 if operator == "divide": return "/" 88 89def rotate(l, n) : 90 return l[n:] + l[:n] 91 92class SwizzleCase(ShaderCase): 93 def __init__(self, name, swizzle1, swizzle2, inputs1, inputs2, operator, outputs): 94 self.name = name 95 self.swizzle1 = swizzle1 96 self.swizzle2 = swizzle2 97 self.inputs = inputs1 + inputs2 98 self.outputs = outputs 99 self.op = "out0 = in0.%s %s in1.%s;" % (swizzle1, operator, swizzle2) 100 101 def __str__(self): 102 params = { 103 "NAME": self.name, 104 "VALUES": genValues(self.inputs, self.outputs), 105 "OP": self.op 106 } 107 return fillTemplate(s_swizzleCaseTemplate, params) 108 109 110# CASE DECLARATIONS 111inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]] 112inInt = [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]] 113 114inVec4 = [ 115 Vec4(0.1, 0.5, 0.75, 0.825), 116 Vec4(1.0, 1.25, 1.125, 1.75), 117 Vec4(-0.5, -2.25, -4.875, 9.0), 118 Vec4(-32.0, 64.0, -51.0, 24.0), 119 Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0), 120] 121 122inVec3 = toVec3(inVec4) 123inVec2 = toVec2(inVec4) 124 125inIVec4 = toIVec4( 126 [ 127 Vec4(-1, 1, -1, 1), 128 Vec4(1, 2, 3, 4), 129 Vec4(-1, -2, -4, -9), 130 ] 131) 132 133inIVec3 = toIVec3(inIVec4) 134inIVec2 = toIVec2(inIVec4) 135 136INPUTS = OrderedDict([ 137 ("float", inFloat), 138 ("vec2", inVec2), 139 ("vec3", inVec3), 140 ("vec4", inVec4), 141 ("int", inInt), 142 ("ivec2", inIVec2), 143 ("ivec3", inIVec3), 144 ("ivec4", inIVec4), 145]) 146 147OPERATORS = OrderedDict([ 148 ("add", op.add), 149 ("subtract", op.sub), 150 ("multiply", op.mul), 151 ("divide", op.div), 152]) 153 154vectorSwizzleGroupCases = { 155 "add": [], 156 "subtract" : [], 157 "multiply" : [], 158 "divide" : [], 159} 160 161allCases = [] 162 163for operator in OPERATORS: 164 for dataType in VECTOR_TYPES: 165 scalarSize = getDataTypeScalarSize(dataType) 166 for precision in PRECISION_TYPES: 167 for swizzleComponents in SWIZZLE_NAMES: 168 for swizzleIndices in getSwizzlesForWidth(scalarSize): 169 swizzle1 = "".join(map(lambda x: swizzleComponents[x], swizzleIndices)) 170 171 swizzle2 = rotate(swizzle1, 1) 172 rotatedSwizzleIndices = rotate(swizzleIndices, 1) 173 174 operands1 = INPUTS[dataType] 175 operands2 = INPUTS[dataType] # these input values will be swizzled 176 177 outputs = map(lambda x, y: OPERATORS[operator](x.swizzle(swizzleIndices), y.swizzle(rotatedSwizzleIndices)), operands1, operands2) 178 outType = outputs[0].typeString() 179 caseName = "%s_%s_%s_%s" % (precision, dataType, swizzle1, swizzle2) 180 181 case = SwizzleCase( caseName, 182 swizzle1, 183 swizzle2, 184 [("%s in0" % dataType, operands1)], 185 [("%s in1" % dataType, operands2)], 186 operatorToSymbol(operator), 187 [("%s out0" % outType, outputs)]) 188 189 vectorSwizzleGroupCases[operator].append(case) 190 191 allCases.append(CaseGroup("vector_" + operator, "Vector swizzle math operations", vectorSwizzleGroupCases[operator])) 192 193if __name__ == "__main__": 194 print("Generating shader case files.") 195 writeAllCases("swizzle_math_operations.test", allCases) 196