| # -*- coding: utf-8 -*- |
| |
| #------------------------------------------------------------------------- |
| # drawElements Quality Program utilities |
| # -------------------------------------- |
| # |
| # Copyright 2017 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| #------------------------------------------------------------------------- |
| |
| import operator as op |
| from genutil import * |
| from collections import OrderedDict |
| |
| VECTOR_TYPES = ["vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4"] |
| PRECISION_TYPES = ["mediump"] |
| SWIZZLE_NAMES = ["xyzw"] |
| |
| s_swizzleCaseTemplate = """ |
| case ${{NAME}} |
| version 300 es |
| values |
| { |
| ${{VALUES}} |
| } |
| |
| both "" |
| #version 300 es |
| precision mediump float; |
| |
| ${DECLARATIONS} |
| |
| void main() |
| { |
| ${SETUP} |
| ${{OP}} |
| ${OUTPUT} |
| } |
| "" |
| end |
| """[1:] |
| |
| def getDataTypeScalarSize (dt): |
| return { |
| "vec2": 2, |
| "vec3": 3, |
| "vec4": 4, |
| "ivec2": 2, |
| "ivec3": 3, |
| "ivec4": 4, |
| }[dt] |
| |
| def getSwizzlesForWidth(width): |
| if (width == 2): |
| return [(0, ), |
| (0,0), (0,1), (1,0), |
| (1,0,1), (0,1,0,0), (1,0,1,0)] |
| elif (width == 3): |
| return [(0,), (2,), |
| (0,2), (2,2), |
| (0,1,2), (2,1,0), (0,0,0), (2,2,2), (2,2,1), (1,0,1), (0,2,0), |
| (0,1,1,0), (2,0,1,2)] |
| elif (width == 4): |
| return [(0,), (3,), |
| (3,0), (3,2), |
| (3,3,3), (1,1,3), (3,2,1), |
| (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)] |
| else: |
| assert False |
| |
| def operatorToSymbol(operator): |
| if operator == "add": return "+" |
| if operator == "subtract": return "-" |
| if operator == "multiply": return "*" |
| if operator == "divide": return "/" |
| |
| def rotate(l, n) : |
| return l[n:] + l[:n] |
| |
| class SwizzleCase(ShaderCase): |
| def __init__(self, name, swizzle1, swizzle2, inputs1, inputs2, operator, outputs): |
| self.name = name |
| self.swizzle1 = swizzle1 |
| self.swizzle2 = swizzle2 |
| self.inputs = inputs1 + inputs2 |
| self.outputs = outputs |
| self.op = "out0 = in0.%s %s in1.%s;" % (swizzle1, operator, swizzle2) |
| |
| def __str__(self): |
| params = { |
| "NAME": self.name, |
| "VALUES": genValues(self.inputs, self.outputs), |
| "OP": self.op |
| } |
| return fillTemplate(s_swizzleCaseTemplate, params) |
| |
| |
| # CASE DECLARATIONS |
| inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]] |
| inInt = [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]] |
| |
| inVec4 = [ |
| Vec4(0.1, 0.5, 0.75, 0.825), |
| Vec4(1.0, 1.25, 1.125, 1.75), |
| Vec4(-0.5, -2.25, -4.875, 9.0), |
| Vec4(-32.0, 64.0, -51.0, 24.0), |
| Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0), |
| ] |
| |
| inVec3 = toVec3(inVec4) |
| inVec2 = toVec2(inVec4) |
| |
| inIVec4 = toIVec4( |
| [ |
| Vec4(-1, 1, -1, 1), |
| Vec4(1, 2, 3, 4), |
| Vec4(-1, -2, -4, -9), |
| ] |
| ) |
| |
| inIVec3 = toIVec3(inIVec4) |
| inIVec2 = toIVec2(inIVec4) |
| |
| INPUTS = OrderedDict([ |
| ("float", inFloat), |
| ("vec2", inVec2), |
| ("vec3", inVec3), |
| ("vec4", inVec4), |
| ("int", inInt), |
| ("ivec2", inIVec2), |
| ("ivec3", inIVec3), |
| ("ivec4", inIVec4), |
| ]) |
| |
| OPERATORS = OrderedDict([ |
| ("add", op.add), |
| ("subtract", op.sub), |
| ("multiply", op.mul), |
| ("divide", op.div), |
| ]) |
| |
| vectorSwizzleGroupCases = { |
| "add": [], |
| "subtract" : [], |
| "multiply" : [], |
| "divide" : [], |
| } |
| |
| allCases = [] |
| |
| for operator in OPERATORS: |
| for dataType in VECTOR_TYPES: |
| scalarSize = getDataTypeScalarSize(dataType) |
| for precision in PRECISION_TYPES: |
| for swizzleComponents in SWIZZLE_NAMES: |
| for swizzleIndices in getSwizzlesForWidth(scalarSize): |
| swizzle1 = "".join(map(lambda x: swizzleComponents[x], swizzleIndices)) |
| |
| swizzle2 = rotate(swizzle1, 1) |
| rotatedSwizzleIndices = rotate(swizzleIndices, 1) |
| |
| operands1 = INPUTS[dataType] |
| operands2 = INPUTS[dataType] # these input values will be swizzled |
| |
| outputs = map(lambda x, y: OPERATORS[operator](x.swizzle(swizzleIndices), y.swizzle(rotatedSwizzleIndices)), operands1, operands2) |
| outType = outputs[0].typeString() |
| caseName = "%s_%s_%s_%s" % (precision, dataType, swizzle1, swizzle2) |
| |
| case = SwizzleCase( caseName, |
| swizzle1, |
| swizzle2, |
| [("%s in0" % dataType, operands1)], |
| [("%s in1" % dataType, operands2)], |
| operatorToSymbol(operator), |
| [("%s out0" % outType, outputs)]) |
| |
| vectorSwizzleGroupCases[operator].append(case) |
| |
| allCases.append(CaseGroup("vector_" + operator, "Vector swizzle math operations", vectorSwizzleGroupCases[operator])) |
| |
| if __name__ == "__main__": |
| print("Generating shader case files.") |
| writeAllCases("swizzle_math_operations.test", allCases) |