xref: /aosp_15_r20/external/deqp/modules/gles3/scripts/gen-swizzle-math-operations.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
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