import sys import itertools from collections import namedtuple from genutil import * # Templates declarationTemplate = """ case ${{NAME}} ${{COMPILE_FAIL}} values {} vertex "" #version 300 es precision mediump float; in highp vec4 dEQP_Position; ${{VARIABLE_VTX}} void main() { x0 = 1.0; x1 = 2.0; gl_Position = dEQP_Position; } "" fragment "" #version 300 es precision mediump float; layout(location = 0) out mediump vec4 dEQP_FragColor; ${{VARIABLE_FRG}} void main() { float result = (x0 + x1 + x2) / 3.0; dEQP_FragColor = vec4(result, result, result, 1.0); } "" end """[1:-1] parameterTemplate = """ case ${{NAME}} ${{COMPILE_FAIL}} version 300 es values {} both "" #version 300 es precision mediump float; ${DECLARATIONS} float foo0 (${{PARAMETER0}}) { return x + 1.0; } void foo1 (${{PARAMETER1}}) { x = 1.0; } float foo2 (${{PARAMETER2}}) { return x + 1.0; } void main() { ${SETUP} float result; foo1(result); float x0 = foo0(1.0); foo2(result); ${OUTPUT} } "" end """[1:-1] # Classes class DeclarationCase(ShaderCase): def __init__(self, compileFail, invariantInput, paramList): self.compileFail = 'expect compile_fail' if compileFail else 'expect pass' self.name = '' var0 = '' var1 = '' var2 = '' for p in paramList: self.name += p.name if paramList.index(p) != len(paramList)-1: self.name += '_' var0 += p.vars[0] + ' ' var1 += p.vars[1] + ' ' var2 += p.vars[2] + ' ' if invariantInput: self.name += "_invariant_input" var0 += 'float x0;\n' var1 += 'float x1;\n' var2 += 'float x2;' variables = (var0 + var1 + var2).strip() variables = variables.replace(" ", " ") self.variableVtx = variables.replace("anon_centroid", "out") self.variableFrg = variables.replace("anon_centroid", "in") self.variableVtx = self.variableVtx.replace("centroid", "centroid out") self.variableFrg = self.variableFrg.replace("centroid", "centroid in") self.variableFrg = self.variableFrg.replace("invariant", "") # input variable cannot be invariant... if invariantInput: self.variableFrg = "invariant " + self.variableFrg # ...unless we are doing a negative test def __str__(self): params = { "NAME" : self.name, "COMPILE_FAIL" : self.compileFail, "VARIABLE_VTX" : self.variableVtx, "VARIABLE_FRG" : self.variableFrg } return fillTemplate(declarationTemplate, params) class ParameterCase(ShaderCase): def __init__(self, compileFail, paramList): self.compileFail = "expect compile_fail" if compileFail else "expect pass" self.name = '' self.param0 = '' self.param1 = '' self.param2 = '' for p in paramList: self.name += p.name if paramList.index(p) != len(paramList)-1: self.name += '_' self.param0 += p.vars[0] + ' ' self.param1 += p.vars[1] + ' ' self.param2 += p.vars[2] + ' ' self.param0 += 'float x' self.param1 += 'float x' self.param2 += 'float x' self.param0 = self.param0.replace(" ", " ") self.param1 = self.param1.replace(" ", " ") self.param2 = self.param2.replace(" ", " ") def __str__(self): params = { "NAME" : self.name, "COMPILE_FAIL" : self.compileFail, "PARAMETER0" : self.param0, "PARAMETER1" : self.param1, "PARAMETER2" : self.param2, } return fillTemplate(parameterTemplate, params) # Declarations CaseFormat = namedtuple('CaseFormat', 'name vars') DECL_INVARIANT = CaseFormat("invariant", [ "invariant", "", "" ]) DECL_INTERPOLATION = CaseFormat("interp", [ "smooth", "flat", "" ]) DECL_STORAGE = CaseFormat("storage", [ "centroid", "anon_centroid", "uniform" ]) DECL_PRECISION = CaseFormat("precision", [ "lowp", "mediump", "highp" ]) PARAM_STORAGE = CaseFormat("storage", [ "const", "", ""]) PARAM_PARAMETER = CaseFormat("parameter", [ "in", "out", "inout" ]) PARAM_PRECISION = CaseFormat("precision", [ "lowp", "mediump", "highp" ]) # Order of qualification tests validDeclarationCases = [] invalidDeclarationCases = [] validParameterCases = [] invalidParameterCases = [] declFormats = [ [DECL_INVARIANT, DECL_INTERPOLATION, DECL_STORAGE, DECL_PRECISION], [DECL_INTERPOLATION, DECL_STORAGE, DECL_PRECISION], [DECL_INVARIANT, DECL_INTERPOLATION, DECL_STORAGE], [DECL_INVARIANT, DECL_STORAGE, DECL_PRECISION], [DECL_STORAGE, DECL_PRECISION], [DECL_INTERPOLATION, DECL_STORAGE], [DECL_INVARIANT, DECL_STORAGE] ] paramFormats = [ [PARAM_STORAGE, PARAM_PARAMETER, PARAM_PRECISION], [PARAM_STORAGE, PARAM_PARAMETER], [PARAM_STORAGE, PARAM_PRECISION], [PARAM_PARAMETER, PARAM_PRECISION] ] print len(paramFormats) for f in declFormats: for p in itertools.permutations(f): if list(p) == f: validDeclarationCases.append(DeclarationCase(False, False, p)) # Correct order else: invalidDeclarationCases.append(DeclarationCase(True, False, p)) # Incorrect order for f in declFormats: invalidDeclarationCases.append(DeclarationCase(True, True, f)) # Correct order but invariant is not allowed as and input parameter for f in paramFormats: for p in itertools.permutations(f): if list(p) == f: validParameterCases.append(ParameterCase(False, p)) # Correct order else: invalidParameterCases.append(ParameterCase(True, p)) # Incorrect order qualificationOrderCases = [ CaseGroup("variables", "Order of qualification in variable declarations.", children = [ CaseGroup("valid", "Valid orderings.", validDeclarationCases), CaseGroup("invalid", "Invalid orderings.", invalidDeclarationCases) ]), CaseGroup("parameters", "Order of qualification in function parameters.", children = [ CaseGroup("valid", "Valid orderings.", validParameterCases), CaseGroup("invalid", "Invalid orderings.", invalidParameterCases) ]) ] # Main program if __name__ == "__main__": print "Generating shader case files." writeAllCases("qualification_order.test", qualificationOrderCases)