• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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