Home | History | Annotate | Download | only in scripts
      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 
     23 import operator as op
     24 from genutil import *
     25 from collections import OrderedDict
     26 
     27 VECTOR_TYPES	= ["vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4"]
     28 PRECISION_TYPES = ["mediump"]
     29 SWIZZLE_NAMES	= ["xyzw"]
     30 
     31 s_swizzleCaseTemplate = """
     32 case ${{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 	""
     52 end
     53 """[1:]
     54 
     55 def 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 
     65 def 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 
     83 def operatorToSymbol(operator):
     84 	if operator == "add":		return "+"
     85 	if operator == "subtract":	return "-"
     86 	if operator == "multiply":	return "*"
     87 	if operator == "divide":	return "/"
     88 
     89 def rotate(l, n) :
     90 	return l[n:] + l[:n]
     91 
     92 class 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
    111 inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]]
    112 inInt	= [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]]
    113 
    114 inVec4	= [
    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 
    122 inVec3	= toVec3(inVec4)
    123 inVec2	= toVec2(inVec4)
    124 
    125 inIVec4 = toIVec4(
    126 	[
    127 	    Vec4(-1, 1, -1, 1),
    128 	    Vec4(1, 2, 3, 4),
    129 	    Vec4(-1, -2, -4, -9),
    130 	]
    131 )
    132 
    133 inIVec3 = toIVec3(inIVec4)
    134 inIVec2 = toIVec2(inIVec4)
    135 
    136 INPUTS = 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 
    147 OPERATORS = OrderedDict([
    148 	("add",		op.add),
    149 	("subtract",	op.sub),
    150 	("multiply",	op.mul),
    151 	("divide",	op.div),
    152 ])
    153 
    154 vectorSwizzleGroupCases = {
    155 	"add":		[],
    156 	"subtract" :	[],
    157 	"multiply" :	[],
    158 	"divide" :	[],
    159 }
    160 
    161 allCases = []
    162 
    163 for 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 
    193 if __name__ == "__main__":
    194 	print "Generating shader case files."
    195 	writeAllCases("swizzle_math_operations.test", allCases)
    196