X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=63c76f9a2233050851e9491af42855ee9f0e8a8c;hb=e0caeb9be47bc140978552bb7149f1c9c8c973db;hp=52885342b004492a11cb8e4bb8c61d54801cea79;hpb=91e65bc9e24a6889995081035f6f6f0a78a6c20e;p=libs%2Fgl.git diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 52885342..63c76f9a 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -11,121 +11,123 @@ namespace SL { const SpirVGenerator::BuiltinFunctionInfo SpirVGenerator::builtin_functions[] = { - { "radians", "f", "GLSL.std.450", GLSL450_RADIANS, { 1 }, 0 }, - { "degrees", "f", "GLSL.std.450", GLSL450_DEGREES, { 1 }, 0 }, - { "sin", "f", "GLSL.std.450", GLSL450_SIN, { 1 }, 0 }, - { "cos", "f", "GLSL.std.450", GLSL450_COS, { 1 }, 0 }, - { "tan", "f", "GLSL.std.450", GLSL450_TAN, { 1 }, 0 }, - { "asin", "f", "GLSL.std.450", GLSL450_ASIN, { 1 }, 0 }, - { "acos", "f", "GLSL.std.450", GLSL450_ACOS, { 1 }, 0 }, - { "atan", "f", "GLSL.std.450", GLSL450_ATAN, { 1 }, 0 }, - { "atan", "ff", "GLSL.std.450", GLSL450_ATAN2, { 1, 2 }, 0 }, - { "sinh", "f", "GLSL.std.450", GLSL450_SINH, { 1 }, 0 }, - { "cosh", "f", "GLSL.std.450", GLSL450_COSH, { 1 }, 0 }, - { "tanh", "f", "GLSL.std.450", GLSL450_TANH, { 1 }, 0 }, - { "asinh", "f", "GLSL.std.450", GLSL450_ASINH, { 1 }, 0 }, - { "acosh", "f", "GLSL.std.450", GLSL450_ACOSH, { 1 }, 0 }, - { "atanh", "f", "GLSL.std.450", GLSL450_ATANH, { 1 }, 0 }, - { "pow", "ff", "GLSL.std.450", GLSL450_POW, { 1, 2 }, 0 }, - { "exp", "f", "GLSL.std.450", GLSL450_EXP, { 1 }, 0 }, - { "log", "f", "GLSL.std.450", GLSL450_LOG, { 1 }, 0 }, - { "exp2", "f", "GLSL.std.450", GLSL450_EXP2, { 1 }, 0 }, - { "log2", "f", "GLSL.std.450", GLSL450_LOG2, { 1 }, 0 }, - { "sqrt", "f", "GLSL.std.450", GLSL450_SQRT, { 1 }, 0 }, - { "inversesqrt", "f", "GLSL.std.450", GLSL450_INVERSE_SQRT, { 1 }, 0 }, - { "abs", "f", "GLSL.std.450", GLSL450_F_ABS, { 1 }, 0 }, - { "abs", "i", "GLSL.std.450", GLSL450_S_ABS, { 1 }, 0 }, - { "sign", "f", "GLSL.std.450", GLSL450_F_SIGN, { 1 }, 0 }, - { "sign", "i", "GLSL.std.450", GLSL450_S_SIGN, { 1 }, 0 }, - { "floor", "f", "GLSL.std.450", GLSL450_FLOOR, { 1 }, 0 }, - { "trunc", "f", "GLSL.std.450", GLSL450_TRUNC, { 1 }, 0 }, - { "round", "f", "GLSL.std.450", GLSL450_ROUND, { 1 }, 0 }, - { "roundEven", "f", "GLSL.std.450", GLSL450_ROUND_EVEN, { 1 }, 0 }, - { "ceil", "f", "GLSL.std.450", GLSL450_CEIL, { 1 }, 0 }, - { "fract", "f", "GLSL.std.450", GLSL450_FRACT, { 1 }, 0 }, - { "mod", "f", "", OP_F_MOD, { 1, 2 }, 0 }, - { "min", "ff", "GLSL.std.450", GLSL450_F_MIN, { 1, 2 }, 0 }, - { "min", "ii", "GLSL.std.450", GLSL450_S_MIN, { 1, 2 }, 0 }, - { "min", "uu", "GLSL.std.450", GLSL450_U_MIN, { 1, 2 }, 0 }, - { "max", "ff", "GLSL.std.450", GLSL450_F_MAX, { 1, 2 }, 0 }, - { "max", "ii", "GLSL.std.450", GLSL450_S_MAX, { 1, 2 }, 0 }, - { "max", "uu", "GLSL.std.450", GLSL450_U_MAX, { 1, 2 }, 0 }, - { "clamp", "fff", "GLSL.std.450", GLSL450_F_CLAMP, { 1, 2, 3 }, 0 }, - { "clamp", "iii", "GLSL.std.450", GLSL450_S_CLAMP, { 1, 2, 3 }, 0 }, - { "clamp", "uuu", "GLSL.std.450", GLSL450_U_CLAMP, { 1, 2, 3 }, 0 }, - { "mix", "fff", "GLSL.std.450", GLSL450_F_MIX, { 1, 2, 3 }, 0 }, - { "mix", "ffb", "", OP_SELECT, { 3, 2, 1 }, 0 }, - { "mix", "iib", "", OP_SELECT, { 3, 2, 1 }, 0 }, - { "mix", "uub", "", OP_SELECT, { 3, 2, 1 }, 0 }, - { "step", "ff", "GLSL.std.450", GLSL450_F_STEP, { 1, 2 }, 0 }, - { "smoothstep", "fff", "GLSL.std.450", GLSL450_F_SMOOTH_STEP, { 1, 2, 3 }, 0 }, - { "isnan", "f", "", OP_IS_NAN, { 1 }, 0 }, - { "isinf", "f", "", OP_IS_INF, { 1 }, 0 }, - { "fma", "fff", "GLSL.std.450", GLSL450_F_FMA, { 1, 2, 3 }, 0 }, - { "length", "f", "GLSL.std.450", GLSL450_LENGTH, { 1 }, 0 }, - { "distance", "ff", "GLSL.std.450", GLSL450_DISTANCE, { 1, 2 }, 0 }, - { "dot", "ff", "", OP_DOT, { 1, 2 }, 0 }, - { "cross", "ff", "GLSL.std.450", GLSL450_CROSS, { 1, 2 }, 0 }, - { "normalize", "f", "GLSL.std.450", GLSL450_NORMALIZE, { 1 }, 0 }, - { "faceforward", "fff", "GLSL.std.450", GLSL450_FACE_FORWARD, { 1, 2, 3 }, 0 }, - { "reflect", "ff", "GLSL.std.450", GLSL450_REFLECT, { 1, 2 }, 0 }, - { "refract", "fff", "GLSL.std.450", GLSL450_REFRACT, { 1, 2, 3 }, 0 }, - { "matrixCompMult", "ff", "", 0, { 0 }, &SpirVGenerator::visit_builtin_matrix_comp_mult }, - { "outerProduct", "ff", "", OP_OUTER_PRODUCT, { 1, 2 }, 0 }, - { "transpose", "f", "", OP_TRANSPOSE, { 1 }, 0 }, - { "determinant", "f", "GLSL.std.450", GLSL450_DETERMINANT, { 1 }, 0 }, - { "inverse", "f", "GLSL.std.450", GLSL450_MATRIX_INVERSE, { 1 }, 0 }, - { "lessThan", "ff", "", OP_F_ORD_LESS_THAN, { 1, 2 }, 0 }, - { "lessThan", "ii", "", OP_S_LESS_THAN, { 1, 2 }, 0 }, - { "lessThan", "uu", "", OP_U_LESS_THAN, { 1, 2 }, 0 }, - { "lessThanEqual", "ff", "", OP_F_ORD_LESS_THAN_EQUAL, { 1, 2 }, 0 }, - { "lessThanEqual", "ii", "", OP_S_LESS_THAN_EQUAL, { 1, 2 }, 0 }, - { "lessThanEqual", "uu", "", OP_U_LESS_THAN_EQUAL, { 1, 2 }, 0 }, - { "greaterThan", "ff", "", OP_F_ORD_GREATER_THAN, { 1, 2 }, 0 }, - { "greaterThan", "ii", "", OP_S_GREATER_THAN, { 1, 2 }, 0 }, - { "greaterThan", "uu", "", OP_U_GREATER_THAN, { 1, 2 }, 0 }, - { "greaterThanEqual", "ff", "", OP_F_ORD_GREATER_THAN_EQUAL, { 1, 2 }, 0 }, - { "greaterThanEqual", "ii", "", OP_S_GREATER_THAN_EQUAL, { 1, 2 }, 0 }, - { "greaterThanEqual", "uu", "", OP_U_GREATER_THAN_EQUAL, { 1, 2 }, 0 }, - { "equal", "ff", "", OP_F_ORD_EQUAL, { 1, 2 }, 0 }, - { "equal", "ii", "", OP_I_EQUAL, { 1, 2 }, 0 }, - { "equal", "uu", "", OP_I_EQUAL, { 1, 2 }, 0 }, - { "notEqual", "ff", "", OP_F_ORD_NOT_EQUAL, { 1, 2 }, 0 }, - { "notEqual", "ii", "", OP_I_NOT_EQUAL, { 1, 2 }, 0 }, - { "notEqual", "uu", "", OP_I_NOT_EQUAL, { 1, 2 }, 0 }, - { "any", "b", "", OP_ANY, { 1 }, 0 }, - { "all", "b", "", OP_ALL, { 1 }, 0 }, - { "not", "b", "", OP_LOGICAL_NOT, { 1 }, 0 }, - { "bitfieldExtract", "iii", "", OP_BIT_FIELD_S_EXTRACT, { 1, 2, 3 }, 0 }, - { "bitfieldExtract", "uii", "", OP_BIT_FIELD_U_EXTRACT, { 1, 2, 3 }, 0 }, - { "bitfieldInsert", "iiii", "", OP_BIT_FIELD_INSERT, { 1, 2, 3, 4 }, 0 }, - { "bitfieldInsert", "uuii", "", OP_BIT_FIELD_INSERT, { 1, 2, 3, 4 }, 0 }, - { "bitfieldReverse", "i", "", OP_BIT_REVERSE, { 1 }, 0 }, - { "bitfieldReverse", "u", "", OP_BIT_REVERSE, { 1 }, 0 }, - { "bitCount", "i", "", OP_BIT_COUNT, { 1 }, 0 }, - { "findLSB", "i", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0 }, - { "findLSB", "u", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0 }, - { "findMSB", "i", "GLSL.std.450", GLSL450_FIND_S_MSB, { 1 }, 0 }, - { "findMSB", "u", "GLSL.std.450", GLSL450_FIND_U_MSB, { 1 }, 0 }, - { "textureSize", "", "", OP_IMAGE_QUERY_SIZE_LOD, { 1, 2 }, 0 }, - { "texture", "", "", 0, { }, &SpirVGenerator::visit_builtin_texture }, - { "textureLod", "", "", 0, { }, &SpirVGenerator::visit_builtin_texture }, - { "texelFetch", "", "", 0, { }, &SpirVGenerator::visit_builtin_texel_fetch }, - { "EmitVertex", "", "", OP_EMIT_VERTEX, { }, 0 }, - { "EndPrimitive", "", "", OP_END_PRIMITIVE, { }, 0 }, - { "dFdx", "f", "", OP_DP_DX, { 1 }, 0 }, - { "dFdy", "f", "", OP_DP_DY, { 1 }, 0 }, - { "dFdxFine", "f", "", OP_DP_DX_FINE, { 1 }, 0 }, - { "dFdyFine", "f", "", OP_DP_DY_FINE, { 1 }, 0 }, - { "dFdxCoarse", "f", "", OP_DP_DX_COARSE, { 1 }, 0 }, - { "dFdyCoarse", "f", "", OP_DP_DY_COARSE, { 1 }, 0 }, - { "fwidth", "f", "", OP_FWIDTH, { 1 }, 0 }, - { "fwidthFine", "f", "", OP_FWIDTH_FINE, { 1 }, 0 }, - { "fwidthCoarse", "f", "", OP_FWIDTH_COARSE, { 1 }, 0 }, - { "interpolateAtCentroid", "", "", 0, { }, &SpirVGenerator::visit_builtin_interpolate }, - { "interpolateAtSample", "", "", 0, { }, &SpirVGenerator::visit_builtin_interpolate }, - { "interpolateAtOffset", "", "", 0, { }, &SpirVGenerator::visit_builtin_interpolate }, - { "", "", "", 0, { }, 0 } + { "radians", "f", "GLSL.std.450", GLSL450_RADIANS, { 1 }, 0, 0 }, + { "degrees", "f", "GLSL.std.450", GLSL450_DEGREES, { 1 }, 0, 0 }, + { "sin", "f", "GLSL.std.450", GLSL450_SIN, { 1 }, 0, 0 }, + { "cos", "f", "GLSL.std.450", GLSL450_COS, { 1 }, 0, 0 }, + { "tan", "f", "GLSL.std.450", GLSL450_TAN, { 1 }, 0, 0 }, + { "asin", "f", "GLSL.std.450", GLSL450_ASIN, { 1 }, 0, 0 }, + { "acos", "f", "GLSL.std.450", GLSL450_ACOS, { 1 }, 0, 0 }, + { "atan", "f", "GLSL.std.450", GLSL450_ATAN, { 1 }, 0, 0 }, + { "atan", "ff", "GLSL.std.450", GLSL450_ATAN2, { 1, 2 }, 0, 0 }, + { "sinh", "f", "GLSL.std.450", GLSL450_SINH, { 1 }, 0, 0 }, + { "cosh", "f", "GLSL.std.450", GLSL450_COSH, { 1 }, 0, 0 }, + { "tanh", "f", "GLSL.std.450", GLSL450_TANH, { 1 }, 0, 0 }, + { "asinh", "f", "GLSL.std.450", GLSL450_ASINH, { 1 }, 0, 0 }, + { "acosh", "f", "GLSL.std.450", GLSL450_ACOSH, { 1 }, 0, 0 }, + { "atanh", "f", "GLSL.std.450", GLSL450_ATANH, { 1 }, 0, 0 }, + { "pow", "ff", "GLSL.std.450", GLSL450_POW, { 1, 2 }, 0, 0 }, + { "exp", "f", "GLSL.std.450", GLSL450_EXP, { 1 }, 0, 0 }, + { "log", "f", "GLSL.std.450", GLSL450_LOG, { 1 }, 0, 0 }, + { "exp2", "f", "GLSL.std.450", GLSL450_EXP2, { 1 }, 0, 0 }, + { "log2", "f", "GLSL.std.450", GLSL450_LOG2, { 1 }, 0, 0 }, + { "sqrt", "f", "GLSL.std.450", GLSL450_SQRT, { 1 }, 0, 0 }, + { "inversesqrt", "f", "GLSL.std.450", GLSL450_INVERSE_SQRT, { 1 }, 0, 0 }, + { "abs", "f", "GLSL.std.450", GLSL450_F_ABS, { 1 }, 0, 0 }, + { "abs", "i", "GLSL.std.450", GLSL450_S_ABS, { 1 }, 0, 0 }, + { "sign", "f", "GLSL.std.450", GLSL450_F_SIGN, { 1 }, 0, 0 }, + { "sign", "i", "GLSL.std.450", GLSL450_S_SIGN, { 1 }, 0, 0 }, + { "floor", "f", "GLSL.std.450", GLSL450_FLOOR, { 1 }, 0, 0 }, + { "trunc", "f", "GLSL.std.450", GLSL450_TRUNC, { 1 }, 0, 0 }, + { "round", "f", "GLSL.std.450", GLSL450_ROUND, { 1 }, 0, 0 }, + { "roundEven", "f", "GLSL.std.450", GLSL450_ROUND_EVEN, { 1 }, 0, 0 }, + { "ceil", "f", "GLSL.std.450", GLSL450_CEIL, { 1 }, 0, 0 }, + { "fract", "f", "GLSL.std.450", GLSL450_FRACT, { 1 }, 0, 0 }, + { "mod", "f", "", OP_F_MOD, { 1, 2 }, 0, 0 }, + { "min", "ff", "GLSL.std.450", GLSL450_F_MIN, { 1, 2 }, 0, 0 }, + { "min", "ii", "GLSL.std.450", GLSL450_S_MIN, { 1, 2 }, 0, 0 }, + { "min", "uu", "GLSL.std.450", GLSL450_U_MIN, { 1, 2 }, 0, 0 }, + { "max", "ff", "GLSL.std.450", GLSL450_F_MAX, { 1, 2 }, 0, 0 }, + { "max", "ii", "GLSL.std.450", GLSL450_S_MAX, { 1, 2 }, 0, 0 }, + { "max", "uu", "GLSL.std.450", GLSL450_U_MAX, { 1, 2 }, 0, 0 }, + { "clamp", "fff", "GLSL.std.450", GLSL450_F_CLAMP, { 1, 2, 3 }, 0, 0 }, + { "clamp", "iii", "GLSL.std.450", GLSL450_S_CLAMP, { 1, 2, 3 }, 0, 0 }, + { "clamp", "uuu", "GLSL.std.450", GLSL450_U_CLAMP, { 1, 2, 3 }, 0, 0 }, + { "mix", "fff", "GLSL.std.450", GLSL450_F_MIX, { 1, 2, 3 }, 0, 0 }, + { "mix", "ffb", "", OP_SELECT, { 3, 2, 1 }, 0, 0 }, + { "mix", "iib", "", OP_SELECT, { 3, 2, 1 }, 0, 0 }, + { "mix", "uub", "", OP_SELECT, { 3, 2, 1 }, 0, 0 }, + { "step", "ff", "GLSL.std.450", GLSL450_F_STEP, { 1, 2 }, 0, 0 }, + { "smoothstep", "fff", "GLSL.std.450", GLSL450_F_SMOOTH_STEP, { 1, 2, 3 }, 0, 0 }, + { "isnan", "f", "", OP_IS_NAN, { 1 }, 0, 0 }, + { "isinf", "f", "", OP_IS_INF, { 1 }, 0, 0 }, + { "fma", "fff", "GLSL.std.450", GLSL450_F_FMA, { 1, 2, 3 }, 0, 0 }, + { "length", "f", "GLSL.std.450", GLSL450_LENGTH, { 1 }, 0, 0 }, + { "distance", "ff", "GLSL.std.450", GLSL450_DISTANCE, { 1, 2 }, 0, 0 }, + { "dot", "ff", "", OP_DOT, { 1, 2 }, 0, 0 }, + { "cross", "ff", "GLSL.std.450", GLSL450_CROSS, { 1, 2 }, 0, 0 }, + { "normalize", "f", "GLSL.std.450", GLSL450_NORMALIZE, { 1 }, 0, 0 }, + { "faceforward", "fff", "GLSL.std.450", GLSL450_FACE_FORWARD, { 1, 2, 3 }, 0, 0 }, + { "reflect", "ff", "GLSL.std.450", GLSL450_REFLECT, { 1, 2 }, 0, 0 }, + { "refract", "fff", "GLSL.std.450", GLSL450_REFRACT, { 1, 2, 3 }, 0, 0 }, + { "matrixCompMult", "ff", "", 0, { 0 }, 0, &SpirVGenerator::visit_builtin_matrix_comp_mult }, + { "outerProduct", "ff", "", OP_OUTER_PRODUCT, { 1, 2 }, 0, 0 }, + { "transpose", "f", "", OP_TRANSPOSE, { 1 }, 0, 0 }, + { "determinant", "f", "GLSL.std.450", GLSL450_DETERMINANT, { 1 }, 0, 0 }, + { "inverse", "f", "GLSL.std.450", GLSL450_MATRIX_INVERSE, { 1 }, 0, 0 }, + { "lessThan", "ff", "", OP_F_ORD_LESS_THAN, { 1, 2 }, 0, 0 }, + { "lessThan", "ii", "", OP_S_LESS_THAN, { 1, 2 }, 0, 0 }, + { "lessThan", "uu", "", OP_U_LESS_THAN, { 1, 2 }, 0, 0 }, + { "lessThanEqual", "ff", "", OP_F_ORD_LESS_THAN_EQUAL, { 1, 2 }, 0, 0 }, + { "lessThanEqual", "ii", "", OP_S_LESS_THAN_EQUAL, { 1, 2 }, 0, 0 }, + { "lessThanEqual", "uu", "", OP_U_LESS_THAN_EQUAL, { 1, 2 }, 0, 0 }, + { "greaterThan", "ff", "", OP_F_ORD_GREATER_THAN, { 1, 2 }, 0, 0 }, + { "greaterThan", "ii", "", OP_S_GREATER_THAN, { 1, 2 }, 0, 0 }, + { "greaterThan", "uu", "", OP_U_GREATER_THAN, { 1, 2 }, 0, 0 }, + { "greaterThanEqual", "ff", "", OP_F_ORD_GREATER_THAN_EQUAL, { 1, 2 }, 0, 0 }, + { "greaterThanEqual", "ii", "", OP_S_GREATER_THAN_EQUAL, { 1, 2 }, 0, 0 }, + { "greaterThanEqual", "uu", "", OP_U_GREATER_THAN_EQUAL, { 1, 2 }, 0, 0 }, + { "equal", "ff", "", OP_F_ORD_EQUAL, { 1, 2 }, 0, 0 }, + { "equal", "ii", "", OP_I_EQUAL, { 1, 2 }, 0, 0 }, + { "equal", "uu", "", OP_I_EQUAL, { 1, 2 }, 0, 0 }, + { "notEqual", "ff", "", OP_F_ORD_NOT_EQUAL, { 1, 2 }, 0, 0 }, + { "notEqual", "ii", "", OP_I_NOT_EQUAL, { 1, 2 }, 0, 0 }, + { "notEqual", "uu", "", OP_I_NOT_EQUAL, { 1, 2 }, 0, 0 }, + { "any", "b", "", OP_ANY, { 1 }, 0, 0 }, + { "all", "b", "", OP_ALL, { 1 }, 0, 0 }, + { "not", "b", "", OP_LOGICAL_NOT, { 1 }, 0, 0 }, + { "bitfieldExtract", "iii", "", OP_BIT_FIELD_S_EXTRACT, { 1, 2, 3 }, 0, 0 }, + { "bitfieldExtract", "uii", "", OP_BIT_FIELD_U_EXTRACT, { 1, 2, 3 }, 0, 0 }, + { "bitfieldInsert", "iiii", "", OP_BIT_FIELD_INSERT, { 1, 2, 3, 4 }, 0, 0 }, + { "bitfieldInsert", "uuii", "", OP_BIT_FIELD_INSERT, { 1, 2, 3, 4 }, 0, 0 }, + { "bitfieldReverse", "i", "", OP_BIT_REVERSE, { 1 }, 0, 0 }, + { "bitfieldReverse", "u", "", OP_BIT_REVERSE, { 1 }, 0, 0 }, + { "bitCount", "i", "", OP_BIT_COUNT, { 1 }, 0, 0 }, + { "findLSB", "i", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0, 0 }, + { "findLSB", "u", "GLSL.std.450", GLSL450_FIND_I_LSB, { 1 }, 0, 0 }, + { "findMSB", "i", "GLSL.std.450", GLSL450_FIND_S_MSB, { 1 }, 0, 0 }, + { "findMSB", "u", "GLSL.std.450", GLSL450_FIND_U_MSB, { 1 }, 0, 0 }, + { "textureSize", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query }, + { "textureQueryLod", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query }, + { "textureQueryLevels", "", "", 0, { }, CAP_IMAGE_QUERY, &SpirVGenerator::visit_builtin_texture_query }, + { "texture", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture }, + { "textureLod", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texture }, + { "texelFetch", "", "", 0, { }, 0, &SpirVGenerator::visit_builtin_texel_fetch }, + { "EmitVertex", "", "", OP_EMIT_VERTEX, { }, 0, 0 }, + { "EndPrimitive", "", "", OP_END_PRIMITIVE, { }, 0, 0 }, + { "dFdx", "f", "", OP_DP_DX, { 1 }, 0, 0 }, + { "dFdy", "f", "", OP_DP_DY, { 1 }, 0, 0 }, + { "dFdxFine", "f", "", OP_DP_DX_FINE, { 1 }, CAP_DERIVATIVE_CONTROL, 0 }, + { "dFdyFine", "f", "", OP_DP_DY_FINE, { 1 }, CAP_DERIVATIVE_CONTROL, 0 }, + { "dFdxCoarse", "f", "", OP_DP_DX_COARSE, { 1 }, CAP_DERIVATIVE_CONTROL, 0 }, + { "dFdyCoarse", "f", "", OP_DP_DY_COARSE, { 1 }, CAP_DERIVATIVE_CONTROL, 0 }, + { "fwidth", "f", "", OP_FWIDTH, { 1 }, 0, 0 }, + { "fwidthFine", "f", "", OP_FWIDTH_FINE, { 1 }, CAP_DERIVATIVE_CONTROL, 0 }, + { "fwidthCoarse", "f", "", OP_FWIDTH_COARSE, { 1 }, CAP_DERIVATIVE_CONTROL, 0 }, + { "interpolateAtCentroid", "", "", 0, { }, CAP_INTERPOLATION_FUNCTION, &SpirVGenerator::visit_builtin_interpolate }, + { "interpolateAtSample", "", "", 0, { }, CAP_INTERPOLATION_FUNCTION, &SpirVGenerator::visit_builtin_interpolate }, + { "interpolateAtOffset", "", "", 0, { }, CAP_INTERPOLATION_FUNCTION, &SpirVGenerator::visit_builtin_interpolate }, + { "", "", "", 0, { }, 0, 0 } }; SpirVGenerator::SpirVGenerator(): @@ -237,8 +239,28 @@ SpirVGenerator::Id SpirVGenerator::get_id(Node &node) const SpirVGenerator::Id SpirVGenerator::allocate_id(Node &node, Id type_id) { + map::iterator i = declared_ids.find(&node); + if(i!=declared_ids.end()) + { + if(i->second.type_id) + throw key_error(&node); + i->second.type_id = type_id; + return i->second.id; + } + + Id id = next_id++; + declared_ids.insert(make_pair(&node, Declaration(id, type_id))); + return id; +} + +SpirVGenerator::Id SpirVGenerator::allocate_forward_id(Node &node) +{ + map::iterator i = declared_ids.find(&node); + if(i!=declared_ids.end()) + return i->second.id; + Id id = next_id++; - insert_unique(declared_ids, &node, Declaration(id, type_id)); + declared_ids.insert(make_pair(&node, Declaration(id, 0))); return id; } @@ -1051,6 +1073,7 @@ void SpirVGenerator::visit(FunctionCall &call) throw internal_error("function call in constant expression"); Id result_type_id = get_id(*call.type); + r_constant_result = false; if(call.constructor) visit_constructor(call, argument_ids, all_args_const); @@ -1075,6 +1098,9 @@ void SpirVGenerator::visit(FunctionCall &call) if(builtin_info->function==call.name && (!builtin_info->arg_types[0] || builtin_info->arg_types==arg_types)) break; + if(builtin_info->capability) + use_capability(static_cast(builtin_info->capability)); + if(builtin_info->opcode) { Opcode opcode; @@ -1156,7 +1182,7 @@ void SpirVGenerator::visit_constructor(FunctionCall &call, const vector &arg Id zero_id = get_constant_id(get_id(elem), 0.0f); for(unsigned i=0; i &argument_ids) +{ + if(argument_ids.size()<1) + throw internal_error("invalid texture query call"); + + Opcode opcode; + if(call.name=="textureSize") + opcode = OP_IMAGE_QUERY_SIZE_LOD; + else if(call.name=="textureQueryLod") + opcode = OP_IMAGE_QUERY_LOD; + else if(call.name=="textureQueryLevels") + opcode = OP_IMAGE_QUERY_LEVELS; + else + throw internal_error("invalid texture query call"); + + ImageTypeDeclaration &image_arg0 = dynamic_cast(*call.arguments[0]->type); + + Id image_id; + if(image_arg0.sampled) + { + Id image_type_id = get_item(image_type_ids, get_id(image_arg0)); + image_id = write_expression(OP_IMAGE, image_type_id, argument_ids[0]); + } + else + image_id = argument_ids[0]; + + Id result_type_id = get_id(*call.type); + r_expression_result_id = begin_expression(opcode, result_type_id, argument_ids.size()); + writer.write(image_id); + for(unsigned i=1; i &argument_ids) { if(argument_ids.size()<2) @@ -1340,8 +1400,6 @@ void SpirVGenerator::visit_builtin_interpolate(FunctionCall &call, const vector< else throw internal_error("invalid interpolate call"); - use_capability(CAP_INTERPOLATION_FUNCTION); - Id ext_id = import_extension("GLSL.std.450"); r_expression_result_id = begin_expression(OP_EXT_INST, get_id(*call.type)); writer.write(ext_id); @@ -1446,6 +1504,7 @@ void SpirVGenerator::visit(ImageTypeDeclaration &image) { writer.write_op_name(type_id, image.name); writer.write_op(content.globals, OP_TYPE_SAMPLED_IMAGE, type_id, image_id); + insert_unique(image_type_ids, type_id, image_id); } if(image.dimensions==ImageTypeDeclaration::ONE) @@ -1574,6 +1633,7 @@ void SpirVGenerator::visit(VariableDeclaration &var) { SetFlag set_const(constant_expression, !current_function); r_expression_result_id = 0; + r_constant_result = false; var.init_expression->visit(*this); init_id = r_expression_result_id; } @@ -1601,7 +1661,10 @@ void SpirVGenerator::visit(VariableDeclaration &var) } if(init_id && current_function) + { writer.write_op(content.function_body, OP_STORE, var_id, init_id); + variable_load_ids[&var] = init_id; + } } writer.write_op_name(var_id, var.name); @@ -1704,8 +1767,14 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id) void SpirVGenerator::visit(FunctionDeclaration &func) { - if(func.source==BUILTIN_SOURCE || func.definition!=&func) + if(func.source==BUILTIN_SOURCE) return; + else if(func.definition!=&func) + { + if(func.definition) + allocate_forward_id(*func.definition); + return; + } Id return_type_id = get_id(*func.return_type_declaration); vector param_type_ids; @@ -1804,6 +1873,8 @@ void SpirVGenerator::visit(Iteration &iter) if(iter.init_statement) iter.init_statement->visit(*this); + variable_load_ids.clear(); + Id header_id = next_id++; Id continue_id = next_id++; Id merge_block_id = next_id++; @@ -1831,7 +1902,6 @@ void SpirVGenerator::visit(Iteration &iter) writer.write_op(content.function_body, OP_BRANCH, header_id); writer.write_op_label(merge_block_id); - prune_loads(header_id); reachable = true; }