1e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*-
2e5c31af7Sopenharmony_ci
3e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci# drawElements Quality Program utilities
5e5c31af7Sopenharmony_ci# --------------------------------------
6e5c31af7Sopenharmony_ci#
7e5c31af7Sopenharmony_ci# Copyright 2017 The Android Open Source Project
8e5c31af7Sopenharmony_ci#
9e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci# You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci#
13e5c31af7Sopenharmony_ci#      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci#
15e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci# limitations under the License.
20e5c31af7Sopenharmony_ci#
21e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
22e5c31af7Sopenharmony_ci
23e5c31af7Sopenharmony_ciimport operator as op
24e5c31af7Sopenharmony_cifrom genutil import *
25e5c31af7Sopenharmony_cifrom collections import OrderedDict
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ciVECTOR_TYPES	= ["vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4"]
28e5c31af7Sopenharmony_ciPRECISION_TYPES = ["mediump"]
29e5c31af7Sopenharmony_ciSWIZZLE_NAMES	= ["xyzw"]
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_cis_swizzleCaseTemplate = """
32e5c31af7Sopenharmony_cicase ${{NAME}}
33e5c31af7Sopenharmony_ci	version 300 es
34e5c31af7Sopenharmony_ci	values
35e5c31af7Sopenharmony_ci	{
36e5c31af7Sopenharmony_ci		${{VALUES}}
37e5c31af7Sopenharmony_ci	}
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ci	both ""
40e5c31af7Sopenharmony_ci		#version 300 es
41e5c31af7Sopenharmony_ci		precision mediump float;
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_ci		${DECLARATIONS}
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_ci		void main()
46e5c31af7Sopenharmony_ci		{
47e5c31af7Sopenharmony_ci			${SETUP}
48e5c31af7Sopenharmony_ci			${{OP}}
49e5c31af7Sopenharmony_ci			${OUTPUT}
50e5c31af7Sopenharmony_ci		}
51e5c31af7Sopenharmony_ci	""
52e5c31af7Sopenharmony_ciend
53e5c31af7Sopenharmony_ci"""[1:]
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_cidef getDataTypeScalarSize (dt):
56e5c31af7Sopenharmony_ci	return {
57e5c31af7Sopenharmony_ci		"vec2":		2,
58e5c31af7Sopenharmony_ci		"vec3":		3,
59e5c31af7Sopenharmony_ci		"vec4":		4,
60e5c31af7Sopenharmony_ci		"ivec2":	2,
61e5c31af7Sopenharmony_ci		"ivec3":	3,
62e5c31af7Sopenharmony_ci		"ivec4":	4,
63e5c31af7Sopenharmony_ci	}[dt]
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_cidef getSwizzlesForWidth(width):
66e5c31af7Sopenharmony_ci	if (width == 2):
67e5c31af7Sopenharmony_ci		return [(0, ),
68e5c31af7Sopenharmony_ci			(0,0), (0,1), (1,0),
69e5c31af7Sopenharmony_ci			(1,0,1), (0,1,0,0), (1,0,1,0)]
70e5c31af7Sopenharmony_ci	elif (width == 3):
71e5c31af7Sopenharmony_ci		return [(0,), (2,),
72e5c31af7Sopenharmony_ci			(0,2), (2,2),
73e5c31af7Sopenharmony_ci			(0,1,2), (2,1,0), (0,0,0), (2,2,2), (2,2,1), (1,0,1), (0,2,0),
74e5c31af7Sopenharmony_ci			(0,1,1,0), (2,0,1,2)]
75e5c31af7Sopenharmony_ci	elif (width == 4):
76e5c31af7Sopenharmony_ci		return [(0,), (3,),
77e5c31af7Sopenharmony_ci			(3,0), (3,2),
78e5c31af7Sopenharmony_ci			(3,3,3), (1,1,3), (3,2,1),
79e5c31af7Sopenharmony_ci			(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)]
80e5c31af7Sopenharmony_ci	else:
81e5c31af7Sopenharmony_ci		assert False
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_cidef operatorToSymbol(operator):
84e5c31af7Sopenharmony_ci	if operator == "add":		return "+"
85e5c31af7Sopenharmony_ci	if operator == "subtract":	return "-"
86e5c31af7Sopenharmony_ci	if operator == "multiply":	return "*"
87e5c31af7Sopenharmony_ci	if operator == "divide":	return "/"
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_cidef rotate(l, n) :
90e5c31af7Sopenharmony_ci	return l[n:] + l[:n]
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_ciclass SwizzleCase(ShaderCase):
93e5c31af7Sopenharmony_ci	def __init__(self, name, swizzle1, swizzle2, inputs1, inputs2, operator, outputs):
94e5c31af7Sopenharmony_ci		self.name	= name
95e5c31af7Sopenharmony_ci		self.swizzle1	= swizzle1
96e5c31af7Sopenharmony_ci		self.swizzle2	= swizzle2
97e5c31af7Sopenharmony_ci		self.inputs	= inputs1 + inputs2
98e5c31af7Sopenharmony_ci		self.outputs	= outputs
99e5c31af7Sopenharmony_ci		self.op		= "out0 = in0.%s %s in1.%s;" % (swizzle1, operator, swizzle2)
100e5c31af7Sopenharmony_ci
101e5c31af7Sopenharmony_ci	def __str__(self):
102e5c31af7Sopenharmony_ci		params = {
103e5c31af7Sopenharmony_ci			"NAME":		self.name,
104e5c31af7Sopenharmony_ci			"VALUES":	genValues(self.inputs, self.outputs),
105e5c31af7Sopenharmony_ci			"OP":		self.op
106e5c31af7Sopenharmony_ci		}
107e5c31af7Sopenharmony_ci		return fillTemplate(s_swizzleCaseTemplate, params)
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ci
110e5c31af7Sopenharmony_ci# CASE DECLARATIONS
111e5c31af7Sopenharmony_ciinFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]]
112e5c31af7Sopenharmony_ciinInt	= [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]]
113e5c31af7Sopenharmony_ci
114e5c31af7Sopenharmony_ciinVec4	= [
115e5c31af7Sopenharmony_ci	Vec4(0.1, 0.5, 0.75, 0.825),
116e5c31af7Sopenharmony_ci	Vec4(1.0, 1.25, 1.125, 1.75),
117e5c31af7Sopenharmony_ci	Vec4(-0.5, -2.25, -4.875, 9.0),
118e5c31af7Sopenharmony_ci	Vec4(-32.0, 64.0, -51.0, 24.0),
119e5c31af7Sopenharmony_ci	Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0),
120e5c31af7Sopenharmony_ci]
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ciinVec3	= toVec3(inVec4)
123e5c31af7Sopenharmony_ciinVec2	= toVec2(inVec4)
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ciinIVec4 = toIVec4(
126e5c31af7Sopenharmony_ci	[
127e5c31af7Sopenharmony_ci	    Vec4(-1, 1, -1, 1),
128e5c31af7Sopenharmony_ci	    Vec4(1, 2, 3, 4),
129e5c31af7Sopenharmony_ci	    Vec4(-1, -2, -4, -9),
130e5c31af7Sopenharmony_ci	]
131e5c31af7Sopenharmony_ci)
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ciinIVec3 = toIVec3(inIVec4)
134e5c31af7Sopenharmony_ciinIVec2 = toIVec2(inIVec4)
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ciINPUTS = OrderedDict([
137e5c31af7Sopenharmony_ci	("float",	inFloat),
138e5c31af7Sopenharmony_ci	("vec2",	inVec2),
139e5c31af7Sopenharmony_ci	("vec3",	inVec3),
140e5c31af7Sopenharmony_ci	("vec4",	inVec4),
141e5c31af7Sopenharmony_ci	("int",		inInt),
142e5c31af7Sopenharmony_ci	("ivec2",	inIVec2),
143e5c31af7Sopenharmony_ci	("ivec3",	inIVec3),
144e5c31af7Sopenharmony_ci	("ivec4",	inIVec4),
145e5c31af7Sopenharmony_ci])
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_ciOPERATORS = OrderedDict([
148e5c31af7Sopenharmony_ci	("add",		op.add),
149e5c31af7Sopenharmony_ci	("subtract",	op.sub),
150e5c31af7Sopenharmony_ci	("multiply",	op.mul),
151e5c31af7Sopenharmony_ci	("divide",	op.div),
152e5c31af7Sopenharmony_ci])
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_civectorSwizzleGroupCases = {
155e5c31af7Sopenharmony_ci	"add":		[],
156e5c31af7Sopenharmony_ci	"subtract" :	[],
157e5c31af7Sopenharmony_ci	"multiply" :	[],
158e5c31af7Sopenharmony_ci	"divide" :	[],
159e5c31af7Sopenharmony_ci}
160e5c31af7Sopenharmony_ci
161e5c31af7Sopenharmony_ciallCases = []
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_cifor operator in OPERATORS:
164e5c31af7Sopenharmony_ci	for dataType in VECTOR_TYPES:
165e5c31af7Sopenharmony_ci		scalarSize = getDataTypeScalarSize(dataType)
166e5c31af7Sopenharmony_ci		for precision in PRECISION_TYPES:
167e5c31af7Sopenharmony_ci			for swizzleComponents in SWIZZLE_NAMES:
168e5c31af7Sopenharmony_ci				for swizzleIndices in getSwizzlesForWidth(scalarSize):
169e5c31af7Sopenharmony_ci					swizzle1 = "".join(map(lambda x: swizzleComponents[x], swizzleIndices))
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_ci					swizzle2 = rotate(swizzle1, 1)
172e5c31af7Sopenharmony_ci					rotatedSwizzleIndices = rotate(swizzleIndices, 1)
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_ci					operands1 = INPUTS[dataType]
175e5c31af7Sopenharmony_ci					operands2 = INPUTS[dataType]  # these input values will be swizzled
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci					outputs = map(lambda x, y: OPERATORS[operator](x.swizzle(swizzleIndices), y.swizzle(rotatedSwizzleIndices)), operands1, operands2)
178e5c31af7Sopenharmony_ci					outType = outputs[0].typeString()
179e5c31af7Sopenharmony_ci					caseName = "%s_%s_%s_%s" % (precision, dataType, swizzle1, swizzle2)
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_ci					case = SwizzleCase(	caseName,
182e5c31af7Sopenharmony_ci								swizzle1,
183e5c31af7Sopenharmony_ci								swizzle2,
184e5c31af7Sopenharmony_ci								[("%s in0" % dataType, operands1)],
185e5c31af7Sopenharmony_ci								[("%s in1" % dataType, operands2)],
186e5c31af7Sopenharmony_ci								operatorToSymbol(operator),
187e5c31af7Sopenharmony_ci								[("%s out0" % outType, outputs)])
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_ci					vectorSwizzleGroupCases[operator].append(case)
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci	allCases.append(CaseGroup("vector_" + operator, "Vector swizzle math operations", vectorSwizzleGroupCases[operator]))
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ciif __name__ == "__main__":
194e5c31af7Sopenharmony_ci	print("Generating shader case files.")
195e5c31af7Sopenharmony_ci	writeAllCases("swizzle_math_operations.test", allCases)
196