65de31499ab61b34aafcc656b1a68f7a3ae33410
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / scripts / gen-swizzle-math-operations.py
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, precision, dataType, swizzle1, swizzle2, inputs1, inputs2, operator, outputs):
94                 self.name       = name
95                 self.precision  = precision
96                 self.dataType   = dataType
97                 self.swizzle1   = swizzle1
98                 self.swizzle2   = swizzle2
99                 self.inputs1    = inputs1
100                 self.inputs2    = inputs2
101                 self.inputs     = inputs1 + inputs2
102                 self.outputs    = outputs
103                 self.op         = "out0 = in0.%s %s in1.%s;" % (swizzle1, operator, swizzle2)
104
105         def __str__(self):
106                 params = {
107                         "NAME":         self.name,
108                         "VALUES":       genValues(self.inputs, self.outputs),
109                         "OP":           self.op
110                 }
111                 return fillTemplate(s_swizzleCaseTemplate, params)
112
113
114 # CASE DECLARATIONS
115 inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]]
116 inInt   = [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]]
117
118 inVec4  = [
119         Vec4(0.1, 0.5, 0.75, 0.825),
120         Vec4(1.0, 1.25, 1.125, 1.75),
121         Vec4(-0.5, -2.25, -4.875, 9.0),
122         Vec4(-32.0, 64.0, -51.0, 24.0),
123         Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0),
124 ]
125
126 inVec3  = toVec3(inVec4)
127 inVec2  = toVec2(inVec4)
128
129 inIVec4 = toIVec4(
130         [
131             Vec4(-1, 1, -1, 1),
132             Vec4(1, 2, 3, 4),
133             Vec4(-1, -2, -4, -9),
134         ]
135 )
136
137 inIVec3 = toIVec3(inIVec4)
138 inIVec2 = toIVec2(inIVec4)
139
140 INPUTS = OrderedDict([
141         ("float",       inFloat),
142         ("vec2",        inVec2),
143         ("vec3",        inVec3),
144         ("vec4",        inVec4),
145         ("int",         inInt),
146         ("ivec2",       inIVec2),
147         ("ivec3",       inIVec3),
148         ("ivec4",       inIVec4),
149 ])
150
151 OPERATORS = OrderedDict([
152         ("add",         op.add),
153         ("subtract",    op.sub),
154         ("multiply",    op.mul),
155         ("divide",      op.div),
156 ])
157
158 vectorSwizzleGroupCases = {
159         "add":          [],
160         "subtract" :    [],
161         "multiply" :    [],
162         "divide" :      [],
163 }
164
165 allCases = []
166
167 for operator in OPERATORS:
168         for dataType in VECTOR_TYPES:
169                 scalarSize = getDataTypeScalarSize(dataType)
170                 for precision in PRECISION_TYPES:
171                         for swizzleComponents in SWIZZLE_NAMES:
172                                 for swizzleIndices in getSwizzlesForWidth(scalarSize):
173                                         swizzle1 = "".join(map(lambda x: swizzleComponents[x], swizzleIndices))
174
175                                         swizzle2 = rotate(swizzle1, 1)
176                                         rotatedSwizzleIndices = rotate(swizzleIndices, 1)
177
178                                         operands1 = INPUTS[dataType]
179                                         operands2 = INPUTS[dataType]  # these input values will be swizzled
180
181                                         outputs = map(lambda x, y: OPERATORS[operator](x.swizzle(swizzleIndices), y.swizzle(rotatedSwizzleIndices)), operands1, operands2)
182                                         outType = outputs[0].typeString()
183                                         caseName = "%s_%s_%s_%s" % (precision, dataType, swizzle1, swizzle2)
184
185                                         case = SwizzleCase(     caseName,
186                                                                 precision,
187                                                                 dataType,
188                                                                 swizzle1,
189                                                                 swizzle2,
190                                                                 [("%s in0" % dataType, operands1)],
191                                                                 [("%s in1" % dataType, operands2)],
192                                                                 operatorToSymbol(operator),
193                                                                 [("%s out0" % outType, outputs)])
194
195                                         vectorSwizzleGroupCases[operator].append(case)
196
197         allCases.append(CaseGroup("vector_" + operator, "Vector swizzle math operations", vectorSwizzleGroupCases[operator]))
198
199 if __name__ == "__main__":
200         print "Generating shader case files."
201         writeAllCases("swizzle_math_operations.test", allCases)