xref: /aosp_15_r20/external/deqp/modules/gles3/scripts/gen-qualification_order.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
1# -*- coding: utf-8 -*-
2
3#-------------------------------------------------------------------------
4# drawElements Quality Program utilities
5# --------------------------------------
6#
7# Copyright 2015 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 sys
24import itertools
25from collections import namedtuple
26from genutil import *
27
28# Templates
29
30declarationTemplate = """
31case ${{NAME}}
32    ${{COMPILE_FAIL}}
33    values {}
34
35    vertex ""
36        #version 300 es
37        precision mediump float;
38        in highp vec4 dEQP_Position;
39
40        ${{VARIABLE_VTX}}
41
42        void main()
43        {
44            x0 = 1.0;
45            x1 = 2.0;
46            gl_Position = dEQP_Position;
47        }
48    ""
49
50    fragment ""
51        #version 300 es
52        precision mediump float;
53        layout(location = 0) out mediump vec4 dEQP_FragColor;
54
55        ${{VARIABLE_FRG}}
56
57        void main()
58        {
59            float result = (x0 + x1 + x2) / 3.0;
60            dEQP_FragColor = vec4(result, result, result, 1.0);
61        }
62    ""
63end
64"""[1:-1]
65
66parameterTemplate = """
67case ${{NAME}}
68    ${{COMPILE_FAIL}}
69    version 300 es
70    values {}
71
72    both ""
73        #version 300 es
74        precision mediump float;
75        ${DECLARATIONS}
76
77        float foo0 (${{PARAMETER0}})
78        {
79            return x + 1.0;
80        }
81
82        void foo1 (${{PARAMETER1}})
83        {
84            x = 1.0;
85        }
86
87        float foo2 (${{PARAMETER2}})
88        {
89            return x + 1.0;
90        }
91
92        void main()
93        {
94            ${SETUP}
95            float result;
96            foo1(result);
97            float x0 = foo0(1.0);
98            foo2(result);
99            ${OUTPUT}
100        }
101    ""
102end
103"""[1:-1]
104
105# Classes
106
107class DeclarationCase(ShaderCase):
108    def __init__(self, compileFail, invariantInput, paramList):
109        self.compileFail = 'expect compile_fail' if compileFail else 'expect pass'
110        self.name = ''
111        var0 = ''
112        var1 = ''
113        var2 = ''
114
115        for p in paramList:
116            self.name += p.name
117            if paramList.index(p) != len(paramList)-1:
118                self.name += '_'
119
120            var0 += p.vars[0] + ' '
121            var1 += p.vars[1] + ' '
122            var2 += p.vars[2] + ' '
123
124        if invariantInput:
125            self.name += "_invariant_input"
126
127        var0 += 'float x0;\n'
128        var1 += 'float x1;\n'
129        var2 += 'float x2;'
130
131        variables = (var0 + var1 + var2).strip()
132        variables = variables.replace("  ", " ")
133        self.variableVtx = variables.replace("anon_centroid", "out")
134        self.variableFrg = variables.replace("anon_centroid", "in")
135        self.variableVtx = self.variableVtx.replace("centroid", "centroid out")
136        self.variableFrg = self.variableFrg.replace("centroid", "centroid in")
137
138        self.variableFrg = self.variableFrg.replace("invariant", "")    # input variable cannot be invariant...
139        if invariantInput:
140            self.variableFrg = "invariant " + self.variableFrg            # ...unless we are doing a negative test
141
142    def __str__(self):
143        params = {
144            "NAME"            : self.name,
145            "COMPILE_FAIL"    : self.compileFail,
146            "VARIABLE_VTX"    : self.variableVtx,
147            "VARIABLE_FRG"    : self.variableFrg
148        }
149        return fillTemplate(declarationTemplate, params)
150
151class ParameterCase(ShaderCase):
152    def __init__(self, compileFail, paramList):
153        self.compileFail = "expect compile_fail" if compileFail else "expect pass"
154        self.name = ''
155        self.param0 = ''
156        self.param1 = ''
157        self.param2 = ''
158
159        for p in paramList:
160            self.name += p.name
161            if paramList.index(p) != len(paramList)-1:
162                self.name += '_'
163
164            self.param0 += p.vars[0] + ' '
165            self.param1 += p.vars[1] + ' '
166            self.param2 += p.vars[2] + ' '
167
168        self.param0 += 'float x'
169        self.param1 += 'float x'
170        self.param2 += 'float x'
171        self.param0 = self.param0.replace("  ", " ")
172        self.param1 = self.param1.replace("  ", " ")
173        self.param2 = self.param2.replace("  ", " ")
174
175    def __str__(self):
176        params = {
177            "NAME"            : self.name,
178            "COMPILE_FAIL"    : self.compileFail,
179            "PARAMETER0"    : self.param0,
180            "PARAMETER1"    : self.param1,
181            "PARAMETER2"    : self.param2,
182        }
183        return fillTemplate(parameterTemplate, params)
184
185# Declarations
186
187CaseFormat = namedtuple('CaseFormat', 'name vars')
188
189DECL_INVARIANT = CaseFormat("invariant", [ "invariant", "", "" ])
190DECL_INTERPOLATION = CaseFormat("interp", [ "smooth", "flat", "" ])
191DECL_STORAGE = CaseFormat("storage", [ "centroid", "anon_centroid", "uniform" ])
192DECL_PRECISION = CaseFormat("precision", [ "lowp", "mediump", "highp" ])
193
194PARAM_STORAGE = CaseFormat("storage", [ "const", "", ""])
195PARAM_PARAMETER = CaseFormat("parameter", [ "in", "out", "inout" ])
196PARAM_PRECISION = CaseFormat("precision", [ "lowp", "mediump", "highp" ])
197
198# Order of qualification tests
199
200validDeclarationCases = []
201invalidDeclarationCases = []
202validParameterCases = []
203invalidParameterCases = []
204
205declFormats = [
206    [DECL_INVARIANT, DECL_INTERPOLATION, DECL_STORAGE, DECL_PRECISION],
207    [DECL_INTERPOLATION, DECL_STORAGE, DECL_PRECISION],
208    [DECL_INVARIANT, DECL_INTERPOLATION, DECL_STORAGE],
209    [DECL_INVARIANT, DECL_STORAGE, DECL_PRECISION],
210    [DECL_STORAGE, DECL_PRECISION],
211    [DECL_INTERPOLATION, DECL_STORAGE],
212    [DECL_INVARIANT, DECL_STORAGE]
213]
214
215paramFormats = [
216    [PARAM_STORAGE, PARAM_PARAMETER, PARAM_PRECISION],
217    [PARAM_STORAGE, PARAM_PARAMETER],
218    [PARAM_STORAGE, PARAM_PRECISION],
219    [PARAM_PARAMETER, PARAM_PRECISION]
220]
221print(len(paramFormats))
222
223for f in declFormats:
224    for p in itertools.permutations(f):
225        if list(p) == f:
226            validDeclarationCases.append(DeclarationCase(False, False, p))    # Correct order
227        else:
228            invalidDeclarationCases.append(DeclarationCase(True, False, p))    # Incorrect order
229
230for f in declFormats:
231    invalidDeclarationCases.append(DeclarationCase(True, True, f))    # Correct order but invariant is not allowed as and input parameter
232
233for f in paramFormats:
234    for p in itertools.permutations(f):
235        if list(p) == f:
236            validParameterCases.append(ParameterCase(False, p))    # Correct order
237        else:
238            invalidParameterCases.append(ParameterCase(True, p))    # Incorrect order
239
240qualificationOrderCases = [
241    CaseGroup("variables", "Order of qualification in variable declarations.", children = [
242        CaseGroup("valid", "Valid orderings.", validDeclarationCases),
243        CaseGroup("invalid", "Invalid orderings.", invalidDeclarationCases)
244    ]),
245    CaseGroup("parameters", "Order of qualification in function parameters.", children = [
246        CaseGroup("valid", "Valid orderings.", validParameterCases),
247        CaseGroup("invalid", "Invalid orderings.", invalidParameterCases)
248    ])
249]
250
251# Main program
252
253if __name__ == "__main__":
254    print("Generating shader case files.")
255    writeAllCases("qualification_order.test", qualificationOrderCases)
256