1e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*-
2e5c31af7Sopenharmony_ci
3e5c31af7Sopenharmony_ci#-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci# drawElements Quality Program utilities
5e5c31af7Sopenharmony_ci# --------------------------------------
6e5c31af7Sopenharmony_ci#
7e5c31af7Sopenharmony_ci# Copyright 2015 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 sys
24e5c31af7Sopenharmony_ciimport random
25e5c31af7Sopenharmony_ciimport operator
26e5c31af7Sopenharmony_ciimport itertools
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_cifrom genutil import *
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_cirandom.seed(1234567)
31e5c31af7Sopenharmony_ciindices = xrange(sys.maxint)
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ci# Swizzles:
34e5c31af7Sopenharmony_ci# - vector components
35e5c31af7Sopenharmony_ci#   * int, float, bool vectors
36e5c31af7Sopenharmony_ci#   * .xyzw, .rgba, .stpq
37e5c31af7Sopenharmony_ci#   * illegal to mix
38e5c31af7Sopenharmony_ci#   * not allowed for scalar types
39e5c31af7Sopenharmony_ci#   * legal to chain: vec4.rgba.xyzw.stpq
40e5c31af7Sopenharmony_ci#   * illegal to select more than 4 components
41e5c31af7Sopenharmony_ci#
42e5c31af7Sopenharmony_ci# Subscripts:
43e5c31af7Sopenharmony_ci# - array-like indexing with [] operator
44e5c31af7Sopenharmony_ci#   * vectors, matrices
45e5c31af7Sopenharmony_ci# - read & write
46e5c31af7Sopenharmony_ci# - vectors components
47e5c31af7Sopenharmony_ci#   * [] accessor
48e5c31af7Sopenharmony_ci# - matrix columns
49e5c31af7Sopenharmony_ci#   * [] accessor
50e5c31af7Sopenharmony_ci#   * note: mat4[0].x = 1.0; vs mat4[0][0] = 1.0; ??
51e5c31af7Sopenharmony_ci#   * out-of-bounds accesses
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_ci#
54e5c31af7Sopenharmony_ci# - vector swizzles
55e5c31af7Sopenharmony_ci#   * all vector types (bvec2..4, ivec2..4, vec2..4)
56e5c31af7Sopenharmony_ci#   * all precisions (lowp, mediump, highp)
57e5c31af7Sopenharmony_ci#   * all component names (xyzw, rgba, stpq)
58e5c31af7Sopenharmony_ci#   * broadcast each, reverse, N random
59e5c31af7Sopenharmony_ci# - component-masked writes
60e5c31af7Sopenharmony_ci#   * all vector types (bvec2..4, ivec2..4, vec2..4)
61e5c31af7Sopenharmony_ci#   * all precisions (lowp, mediump, highp)
62e5c31af7Sopenharmony_ci#   * all component names (xyzw, rgba, stpq)
63e5c31af7Sopenharmony_ci#   * all possible subsets
64e5c31af7Sopenharmony_ci#   * all input types (attribute, varying, uniform, tmp)
65e5c31af7Sopenharmony_ci#   -> a few hundred cases
66e5c31af7Sopenharmony_ci# - concatenated swizzles
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ci#
69e5c31af7Sopenharmony_ciVECTOR_TYPES	= [ "vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4", "bvec2", "bvec3", "bvec4" ]
70e5c31af7Sopenharmony_ciPRECISION_TYPES	= [ "lowp", "mediump", "highp" ]
71e5c31af7Sopenharmony_ciINPUT_TYPES		= [ "uniform", "varying", "attribute", "tmp" ]
72e5c31af7Sopenharmony_ciSWIZZLE_NAMES	= [ "xyzw", "stpq", "rgba" ]
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_cidef getDataTypeScalarSize (dt):
75e5c31af7Sopenharmony_ci	return {
76e5c31af7Sopenharmony_ci		"float":	1,
77e5c31af7Sopenharmony_ci		"vec2":		2,
78e5c31af7Sopenharmony_ci		"vec3":		3,
79e5c31af7Sopenharmony_ci		"vec4":		4,
80e5c31af7Sopenharmony_ci		"int":		1,
81e5c31af7Sopenharmony_ci		"ivec2":	2,
82e5c31af7Sopenharmony_ci		"ivec3":	3,
83e5c31af7Sopenharmony_ci		"ivec4":	4,
84e5c31af7Sopenharmony_ci		"bool":		1,
85e5c31af7Sopenharmony_ci		"bvec2":	2,
86e5c31af7Sopenharmony_ci		"bvec3":	3,
87e5c31af7Sopenharmony_ci		"bvec4":	4,
88e5c31af7Sopenharmony_ci		"mat2":		4,
89e5c31af7Sopenharmony_ci		"mat3":		9,
90e5c31af7Sopenharmony_ci		"mat4":		16
91e5c31af7Sopenharmony_ci	}[dt]
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_ciif False:
94e5c31af7Sopenharmony_ci	class Combinations:
95e5c31af7Sopenharmony_ci		def __init__(self, *args):
96e5c31af7Sopenharmony_ci			self.lists				= list(args)
97e5c31af7Sopenharmony_ci			self.numLists			= len(args)
98e5c31af7Sopenharmony_ci			self.numCombinations	= reduce(operator.mul, map(len, self.lists), 1)
99e5c31af7Sopenharmony_ci			print(self.lists)
100e5c31af7Sopenharmony_ci			print(self.numCombinations)
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_ci		def iterate(self):
103e5c31af7Sopenharmony_ci			return [tuple(map(lambda x: x[0], self.lists))]
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci	combinations = Combinations(INPUT_TYPES, VECTOR_TYPES, PRECISION_TYPES)
106e5c31af7Sopenharmony_ci	print(combinations.iterate())
107e5c31af7Sopenharmony_ci	for (inputType, dataType, precision) in combinations.iterate():
108e5c31af7Sopenharmony_ci		scalarSize = getDataTypeScalarSize(dataType)
109e5c31af7Sopenharmony_ci		print(inputType, precision, dataType)
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_cidef getSwizzlesForWidth(width):
112e5c31af7Sopenharmony_ci	if (width == 2):
113e5c31af7Sopenharmony_ci		return [(0,), (0,0), (0,1), (1,0), (1,0,1), (0,1,0,0), (1,1,1,1)]
114e5c31af7Sopenharmony_ci	elif (width == 3):
115e5c31af7Sopenharmony_ci		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)]
116e5c31af7Sopenharmony_ci	elif (width == 4):
117e5c31af7Sopenharmony_ci		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)]
118e5c31af7Sopenharmony_ci	else:
119e5c31af7Sopenharmony_ci		assert False
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ci# Templates.
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_cis_swizzleCaseTemplate = """
124e5c31af7Sopenharmony_cicase ${{NAME}}
125e5c31af7Sopenharmony_ci	values
126e5c31af7Sopenharmony_ci	{
127e5c31af7Sopenharmony_ci		${{VALUES}}
128e5c31af7Sopenharmony_ci	}
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci	both ""
131e5c31af7Sopenharmony_ci		precision mediump float;
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci		${DECLARATIONS}
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ci		void main()
136e5c31af7Sopenharmony_ci		{
137e5c31af7Sopenharmony_ci			${SETUP}
138e5c31af7Sopenharmony_ci			${{OP}}
139e5c31af7Sopenharmony_ci			${OUTPUT}
140e5c31af7Sopenharmony_ci		}
141e5c31af7Sopenharmony_ci	""
142e5c31af7Sopenharmony_ciend
143e5c31af7Sopenharmony_ci"""[1:]
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_cis_simpleIllegalCaseTemplate = """
146e5c31af7Sopenharmony_cicase ${{NAME}}
147e5c31af7Sopenharmony_ci	expect compile_fail
148e5c31af7Sopenharmony_ci	values {}
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ci	both ""
151e5c31af7Sopenharmony_ci		precision mediump float;
152e5c31af7Sopenharmony_ci		precision mediump int;
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ci		${DECLARATIONS}
155e5c31af7Sopenharmony_ci
156e5c31af7Sopenharmony_ci		void main()
157e5c31af7Sopenharmony_ci		{
158e5c31af7Sopenharmony_ci			${SETUP}
159e5c31af7Sopenharmony_ci			${{OP}}
160e5c31af7Sopenharmony_ci			${OUTPUT}
161e5c31af7Sopenharmony_ci		}
162e5c31af7Sopenharmony_ci	""
163e5c31af7Sopenharmony_ciend
164e5c31af7Sopenharmony_ci"""[1:]
165e5c31af7Sopenharmony_ci
166e5c31af7Sopenharmony_ciclass SwizzleCase(ShaderCase):
167e5c31af7Sopenharmony_ci	def __init__(self, name, precision, dataType, swizzle, inputs, outputs):
168e5c31af7Sopenharmony_ci		self.name		= name
169e5c31af7Sopenharmony_ci		self.precision	= precision
170e5c31af7Sopenharmony_ci		self.dataType	= dataType
171e5c31af7Sopenharmony_ci		self.swizzle	= swizzle
172e5c31af7Sopenharmony_ci		self.inputs		= inputs
173e5c31af7Sopenharmony_ci		self.outputs	= outputs
174e5c31af7Sopenharmony_ci		self.op			= "out0 = in0.%s;" % swizzle
175e5c31af7Sopenharmony_ci
176e5c31af7Sopenharmony_ci	def __str__(self):
177e5c31af7Sopenharmony_ci		params = {
178e5c31af7Sopenharmony_ci			"NAME":		self.name,
179e5c31af7Sopenharmony_ci			"VALUES":	genValues(self.inputs, self.outputs),
180e5c31af7Sopenharmony_ci			"OP":		self.op
181e5c31af7Sopenharmony_ci		}
182e5c31af7Sopenharmony_ci		return fillTemplate(s_swizzleCaseTemplate, params)
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci# CASE DECLARATIONS
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ciinFloat	= [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]]
187e5c31af7Sopenharmony_ciinInt	= [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]]
188e5c31af7Sopenharmony_ciinBool	= [Scalar(x) for x in [True, False]]
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ciinVec4	= [Vec4(0.0, 0.5, 0.75, 0.825), Vec4(1.0, 1.25, 1.125, 1.75),
191e5c31af7Sopenharmony_ci		   Vec4(-0.5, -2.25, -4.875, 9.0), Vec4(-32.0, 64.0, -51.0, 24.0),
192e5c31af7Sopenharmony_ci		   Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0)]
193e5c31af7Sopenharmony_ciinVec3	= toVec3(inVec4)
194e5c31af7Sopenharmony_ciinVec2	= toVec2(inVec4)
195e5c31af7Sopenharmony_ciinIVec4	= toIVec4(inVec4)
196e5c31af7Sopenharmony_ciinIVec3	= toIVec3(inVec4)
197e5c31af7Sopenharmony_ciinIVec2	= toIVec2(inVec4)
198e5c31af7Sopenharmony_ciinBVec4	= [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)]
199e5c31af7Sopenharmony_ciinBVec3	= toBVec3(inBVec4)
200e5c31af7Sopenharmony_ciinBVec2	= toBVec2(inBVec4)
201e5c31af7Sopenharmony_ci
202e5c31af7Sopenharmony_ci# \todo [petri] Enable large values when epsilon adapts to the values.
203e5c31af7Sopenharmony_ciinMat4	= [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),
204e5c31af7Sopenharmony_ci		   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),
205e5c31af7Sopenharmony_ci		   #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)
206e5c31af7Sopenharmony_ci		   ]
207e5c31af7Sopenharmony_ciinMat3	= [Mat3(1.0, 0.0, 0.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0),
208e5c31af7Sopenharmony_ci		   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),
209e5c31af7Sopenharmony_ci		   #Mat3(-18.725, -0.5, -0.0125,  19.975, -0.25, -17.75,  9.25, 65.125, -21.425),
210e5c31af7Sopenharmony_ci		   #Mat3(128.0, -4096.0, -8192.0,  192.0, 768.0, -1536.0,  8192.0, 6144.0, -6144.0)
211e5c31af7Sopenharmony_ci		   ]
212e5c31af7Sopenharmony_ciinMat2	= [Mat2(1.0, 0.0,  0.0, 1.0),
213e5c31af7Sopenharmony_ci		   Mat2(6.5, 12.5,  -0.75, 9.975),
214e5c31af7Sopenharmony_ci		   Mat2(6.5, 12.5,  -0.75, 9.975),
215e5c31af7Sopenharmony_ci		   Mat2(8.0, 16.0,  -24.0, -16.0),
216e5c31af7Sopenharmony_ci		   Mat2(1.0/8.0, 1.0/16.0,  1.0/32.0, 1.0/64.0),
217e5c31af7Sopenharmony_ci		   Mat2(-18.725, -0.5,  -0.0125, 19.975),
218e5c31af7Sopenharmony_ci		   #Mat2(128.0, -4096.0,  192.0, -1536.0),
219e5c31af7Sopenharmony_ci		   #Mat2(-1536.0, 8192.0,  6144.0, -6144.0)
220e5c31af7Sopenharmony_ci		   ]
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ciINPUTS = {
223e5c31af7Sopenharmony_ci	"float":	inFloat,
224e5c31af7Sopenharmony_ci	"vec2":		inVec2,
225e5c31af7Sopenharmony_ci	"vec3":		inVec3,
226e5c31af7Sopenharmony_ci	"vec4":		inVec4,
227e5c31af7Sopenharmony_ci	"int":		inInt,
228e5c31af7Sopenharmony_ci	"ivec2":	inIVec2,
229e5c31af7Sopenharmony_ci	"ivec3":	inIVec3,
230e5c31af7Sopenharmony_ci	"ivec4":	inIVec4,
231e5c31af7Sopenharmony_ci	"bool":		inBool,
232e5c31af7Sopenharmony_ci	"bvec2":	inBVec2,
233e5c31af7Sopenharmony_ci	"bvec3":	inBVec3,
234e5c31af7Sopenharmony_ci	"bvec4":	inBVec4,
235e5c31af7Sopenharmony_ci	"mat2":		inMat2,
236e5c31af7Sopenharmony_ci	"mat3":		inMat3,
237e5c31af7Sopenharmony_ci	"mat4":		inMat4
238e5c31af7Sopenharmony_ci}
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_cidef genConversionCases(inValueList, convFuncList):
241e5c31af7Sopenharmony_ci	combinations = list(itertools.product(inValueList, convFuncList))
242e5c31af7Sopenharmony_ci	return [ConversionCase(inValues, convFunc) for (inValues, convFunc) in combinations]
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_ciallCases = []
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci# Vector swizzles.
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_civectorSwizzleCases = []
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci# \todo [petri] Uses fixed precision.
251e5c31af7Sopenharmony_cifor dataType in VECTOR_TYPES:
252e5c31af7Sopenharmony_ci	scalarSize = getDataTypeScalarSize(dataType)
253e5c31af7Sopenharmony_ci	precision = "mediump"
254e5c31af7Sopenharmony_ci	for swizzleComponents in SWIZZLE_NAMES:
255e5c31af7Sopenharmony_ci		for swizzleIndices in getSwizzlesForWidth(scalarSize):
256e5c31af7Sopenharmony_ci			swizzle = "".join(map(lambda x: swizzleComponents[x], swizzleIndices))
257e5c31af7Sopenharmony_ci			#print("%s %s .%s" % (precision, dataType, swizzle))
258e5c31af7Sopenharmony_ci			caseName = "%s_%s_%s" % (precision, dataType, swizzle)
259e5c31af7Sopenharmony_ci			inputs = INPUTS[dataType]
260e5c31af7Sopenharmony_ci			outputs = map(lambda x: x.swizzle(swizzleIndices), inputs)
261e5c31af7Sopenharmony_ci			outType = outputs[0].typeString()
262e5c31af7Sopenharmony_ci			vectorSwizzleCases.append(SwizzleCase(caseName, precision, dataType, swizzle, [("%s in0" % dataType, inputs)], [("%s out0" % outType, outputs)]))
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_ci# ??
265e5c31af7Sopenharmony_ci#for dataType in VECTOR_TYPES:
266e5c31af7Sopenharmony_ci#	scalarSize = getDataTypeScalarSize(dataType)
267e5c31af7Sopenharmony_ci#	for precision in PRECISION_TYPES:
268e5c31af7Sopenharmony_ci#		for swizzleIndices in getSwizzlesForWidth(scalarSize):
269e5c31af7Sopenharmony_ci#			swizzle = "".join(map(lambda x: "xyzw"[x], swizzleIndices))
270e5c31af7Sopenharmony_ci#			#print("%s %s .%s" % (precision, dataType, swizzle))
271e5c31af7Sopenharmony_ci#			caseName = "%s_%s_%s" % (precision, dataType, swizzle)
272e5c31af7Sopenharmony_ci#			inputs = INPUTS[dataType]
273e5c31af7Sopenharmony_ci#			outputs = map(lambda x: x.swizzle(swizzleIndices), inputs)
274e5c31af7Sopenharmony_ci#			vectorSwizzleCases.append(SwizzleCase(caseName, precision, dataType, swizzle, [("in0", inputs)], [("out0", outputs)]))
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_ciallCases.append(CaseGroup("vector_swizzles", "Vector Swizzles", vectorSwizzleCases))
277e5c31af7Sopenharmony_ci
278e5c31af7Sopenharmony_ci# Swizzles:
279e5c31af7Sopenharmony_ci# - vector components
280e5c31af7Sopenharmony_ci#   * int, float, bool vectors
281e5c31af7Sopenharmony_ci#   * .xyzw, .rgba, .stpq
282e5c31af7Sopenharmony_ci#   * illegal to mix
283e5c31af7Sopenharmony_ci#   * not allowed for scalar types
284e5c31af7Sopenharmony_ci#   * legal to chain: vec4.rgba.xyzw.stpq
285e5c31af7Sopenharmony_ci#   * illegal to select more than 4 components
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci# TODO: precisions!!
288e5c31af7Sopenharmony_ci
289e5c31af7Sopenharmony_ci#allCases.append(CaseGroup("vector_swizzles", "Vector Swizzles",
290e5c31af7Sopenharmony_ci#	genSwizzleCase([inVec2, inVec3, inVec4],
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci# Main program.
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_ciif __name__ == "__main__":
295e5c31af7Sopenharmony_ci	print("Generating shader case files.")
296e5c31af7Sopenharmony_ci	writeAllCases("swizzles.test", allCases)
297