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 23 import sys 24 import itertools 25 from collections import namedtuple 26 from genutil import * 27 28 # Templates 29 30 declarationTemplate = """ 31 case ${{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 "" 63 end 64 """[1:-1] 65 66 parameterTemplate = """ 67 case ${{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 "" 102 end 103 """[1:-1] 104 105 # Classes 106 107 class 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 151 class 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 187 CaseFormat = namedtuple('CaseFormat', 'name vars') 188 189 DECL_INVARIANT = CaseFormat("invariant", [ "invariant", "", "" ]) 190 DECL_INTERPOLATION = CaseFormat("interp", [ "smooth", "flat", "" ]) 191 DECL_STORAGE = CaseFormat("storage", [ "centroid", "anon_centroid", "uniform" ]) 192 DECL_PRECISION = CaseFormat("precision", [ "lowp", "mediump", "highp" ]) 193 194 PARAM_STORAGE = CaseFormat("storage", [ "const", "", ""]) 195 PARAM_PARAMETER = CaseFormat("parameter", [ "in", "out", "inout" ]) 196 PARAM_PRECISION = CaseFormat("precision", [ "lowp", "mediump", "highp" ]) 197 198 # Order of qualification tests 199 200 validDeclarationCases = [] 201 invalidDeclarationCases = [] 202 validParameterCases = [] 203 invalidParameterCases = [] 204 205 declFormats = [ 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 215 paramFormats = [ 216 [PARAM_STORAGE, PARAM_PARAMETER, PARAM_PRECISION], 217 [PARAM_STORAGE, PARAM_PARAMETER], 218 [PARAM_STORAGE, PARAM_PRECISION], 219 [PARAM_PARAMETER, PARAM_PRECISION] 220 ] 221 print len(paramFormats) 222 223 for 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 230 for f in declFormats: 231 invalidDeclarationCases.append(DeclarationCase(True, True, f)) # Correct order but invariant is not allowed as and input parameter 232 233 for 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 240 qualificationOrderCases = [ 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 253 if __name__ == "__main__": 254 print "Generating shader case files." 255 writeAllCases("qualification_order.test", qualificationOrderCases) 256