From 8c5786622b4ecf6024356be5d5395bd1c8b1fa6f Mon Sep 17 00:00:00 2001 From: John Stiles Date: Mon, 1 Jun 2020 15:32:47 +0000 Subject: [PATCH] Reland "Remove double support from SkSL." This reverts commit 59aa4b7187c6a6a6c9ee43dfd70224d5957bc55a. Reason for revert: ASAN failures were actually unrelated to this CL. Original change's description: > Revert "Remove double support from SkSL." > > This reverts commit 71a35d49b73448e646c82538ecb009fc68471580. > > Reason for revert: ASAN failures on swarming bots > > Original change's description: > > Remove double support from SkSL. > > > > Doubles are not supported by Metal or GLSL pre-4.0, are not supported in > > most backends, and aren't used in any GMs. There isn't any good way to > > use them in new code as it would just degrade to float on many of our > > supported platforms. (This is assuming that our backends actually know > > how to degrade doubles to floats, which is not universally the case.) > > > > Change-Id: Ieacc69db4bdacca104a15a6eef33e05f977d1ffa > > Bug: skia:10299 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292846 > > Commit-Queue: John Stiles > > Commit-Queue: Ethan Nicholas > > Reviewed-by: Ethan Nicholas > > Auto-Submit: John Stiles > > TBR=bsalomon@google.com,ethannicholas@google.com,johnstiles@google.com > > Change-Id: I175e42420bcae8dfacd0bfeb269dd84e0b3c9d25 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia:10299 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293268 > Reviewed-by: John Stiles > Commit-Queue: John Stiles TBR=bsalomon@google.com,ethannicholas@google.com,johnstiles@google.com # Not skipping CQ checks because this is a reland. Bug: skia:10299 Change-Id: I5cdd71a1512228175514a0d29e19ae91afc78b6a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293273 Reviewed-by: John Stiles Commit-Queue: John Stiles Auto-Submit: John Stiles --- src/sksl/SkSLCompiler.cpp | 15 -------- src/sksl/SkSLContext.h | 23 ------------ src/sksl/SkSLGLSLCodeGenerator.cpp | 6 --- src/sksl/SkSLSPIRVCodeGenerator.cpp | 57 ++++++++++------------------- src/sksl/ir/SkSLIndexExpression.h | 8 ---- src/sksl/ir/SkSLSwizzle.h | 6 --- src/sksl/ir/SkSLType.cpp | 32 ---------------- src/sksl/ir/SkSLType.h | 4 +- src/sksl/sksl_gpu.inc | 18 --------- tests/SkSLGLSLTest.cpp | 16 ++++---- 10 files changed, 29 insertions(+), 156 deletions(-) diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 85f4bb6d7f..9916d6d146 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -126,10 +126,6 @@ Compiler::Compiler(Flags flags) ADD_TYPE(Half2); ADD_TYPE(Half3); ADD_TYPE(Half4); - ADD_TYPE(Double); - ADD_TYPE(Double2); - ADD_TYPE(Double3); - ADD_TYPE(Double4); ADD_TYPE(Int); ADD_TYPE(Int2); ADD_TYPE(Int3); @@ -176,18 +172,8 @@ Compiler::Compiler(Flags flags) ADD_TYPE(Half4x2); ADD_TYPE(Half4x3); ADD_TYPE(Half4x4); - ADD_TYPE(Double2x2); - ADD_TYPE(Double2x3); - ADD_TYPE(Double2x4); - ADD_TYPE(Double3x2); - ADD_TYPE(Double3x3); - ADD_TYPE(Double3x4); - ADD_TYPE(Double4x2); - ADD_TYPE(Double4x3); - ADD_TYPE(Double4x4); ADD_TYPE(GenType); ADD_TYPE(GenHType); - ADD_TYPE(GenDType); ADD_TYPE(GenIType); ADD_TYPE(GenUType); ADD_TYPE(GenBType); @@ -198,7 +184,6 @@ Compiler::Compiler(Flags flags) ADD_TYPE(GVec3); ADD_TYPE(GVec4); ADD_TYPE(HVec); - ADD_TYPE(DVec); ADD_TYPE(IVec); ADD_TYPE(UVec); ADD_TYPE(SVec); diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h index 39968d42bf..832413035a 100644 --- a/src/sksl/SkSLContext.h +++ b/src/sksl/SkSLContext.h @@ -24,10 +24,6 @@ public: , fNull_Type(new Type("null")) , fFloatLiteral_Type(new Type("$floatLiteral", Type::kFloat_NumberKind, 3)) , fIntLiteral_Type(new Type("$intLiteral", Type::kSigned_NumberKind, 1)) - , fDouble_Type(new Type("double", Type::kFloat_NumberKind, 6, true)) - , fDouble2_Type(new Type("double2", *fDouble_Type, 2)) - , fDouble3_Type(new Type("double3", *fDouble_Type, 3)) - , fDouble4_Type(new Type("double4", *fDouble_Type, 4)) , fFloat_Type(new Type("float", Type::kFloat_NumberKind, 5, true)) , fFloat2_Type(new Type("float2", *fFloat_Type, 2)) , fFloat3_Type(new Type("float3", *fFloat_Type, 3)) @@ -82,15 +78,6 @@ public: , fHalf4x2_Type(new Type("half4x2", *fHalf_Type, 4, 2)) , fHalf4x3_Type(new Type("half4x3", *fHalf_Type, 4, 3)) , fHalf4x4_Type(new Type("half4x4", *fHalf_Type, 4, 4)) - , fDouble2x2_Type(new Type("double2x2", *fDouble_Type, 2, 2)) - , fDouble2x3_Type(new Type("double2x3", *fDouble_Type, 2, 3)) - , fDouble2x4_Type(new Type("double2x4", *fDouble_Type, 2, 4)) - , fDouble3x2_Type(new Type("double3x2", *fDouble_Type, 3, 2)) - , fDouble3x3_Type(new Type("double3x3", *fDouble_Type, 3, 3)) - , fDouble3x4_Type(new Type("double3x4", *fDouble_Type, 3, 4)) - , fDouble4x2_Type(new Type("double4x2", *fDouble_Type, 4, 2)) - , fDouble4x3_Type(new Type("double4x3", *fDouble_Type, 4, 3)) - , fDouble4x4_Type(new Type("double4x4", *fDouble_Type, 4, 4)) , fTexture1D_Type(new Type("texture1D", SpvDim1D, false, false, false, true)) , fTexture2D_Type(new Type("texture2D", SpvDim2D, false, false, false, true)) , fTexture3D_Type(new Type("texture3D", SpvDim3D, false, false, false, true)) @@ -158,8 +145,6 @@ public: fFloat3_Type.get(), fFloat4_Type.get() })) , fGenHType_Type(new Type("$genHType", { fHalf_Type.get(), fHalf2_Type.get(), fHalf3_Type.get(), fHalf4_Type.get() })) - , fGenDType_Type(new Type("$genDType", { fDouble_Type.get(), fDouble2_Type.get(), - fDouble3_Type.get(), fDouble4_Type.get() })) , fGenIType_Type(new Type("$genIType", { fInt_Type.get(), fInt2_Type.get(), fInt3_Type.get(), fInt4_Type.get() })) , fGenUType_Type(new Type("$genUType", { fUInt_Type.get(), fUInt2_Type.get(), @@ -188,8 +173,6 @@ public: , fGVec4_Type(new Type("$gfloat4", static_type(*fFloat4_Type))) , fHVec_Type(new Type("$hvec", { fInvalid_Type.get(), fHalf2_Type.get(), fHalf3_Type.get(), fHalf4_Type.get() })) - , fDVec_Type(new Type("$dvec", { fInvalid_Type.get(), fDouble2_Type.get(), - fDouble3_Type.get(), fDouble4_Type.get() })) , fIVec_Type(new Type("$ivec", { fInvalid_Type.get(), fInt2_Type.get(), fInt3_Type.get(), fInt4_Type.get() })) , fUVec_Type(new Type("$uvec", { fInvalid_Type.get(), fUInt2_Type.get(), @@ -219,11 +202,6 @@ public: const std::unique_ptr fFloatLiteral_Type; const std::unique_ptr fIntLiteral_Type; - const std::unique_ptr fDouble_Type; - const std::unique_ptr fDouble2_Type; - const std::unique_ptr fDouble3_Type; - const std::unique_ptr fDouble4_Type; - const std::unique_ptr fFloat_Type; const std::unique_ptr fFloat2_Type; const std::unique_ptr fFloat3_Type; @@ -353,7 +331,6 @@ public: const std::unique_ptr fGenType_Type; const std::unique_ptr fGenHType_Type; - const std::unique_ptr fGenDType_Type; const std::unique_ptr fGenIType_Type; const std::unique_ptr fGenUType_Type; const std::unique_ptr fGenBType_Type; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 0aa7bbc667..6f64ae54ce 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -87,9 +87,6 @@ String GLSLCodeGenerator::getTypeName(const Type& type) { if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) { result = "vec"; } - else if (component == *fContext.fDouble_Type) { - result = "dvec"; - } else if (component.isSigned()) { result = "ivec"; } @@ -111,9 +108,6 @@ String GLSLCodeGenerator::getTypeName(const Type& type) { if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) { result = "mat"; } - else if (component == *fContext.fDouble_Type) { - result = "dmat"; - } else { ABORT("unsupported matrix type"); } diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 6726a8f3a1..d79227a791 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -152,8 +152,7 @@ static bool is_float(const Context& context, const Type& type) { if (type.columns() > 1) { return is_float(context, type.componentType()); } - return type == *context.fFloat_Type || type == *context.fHalf_Type || - type == *context.fDouble_Type; + return type == *context.fFloat_Type || type == *context.fHalf_Type; } static bool is_signed(const Context& context, const Type& type) { @@ -491,8 +490,6 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou } else if (type == *fContext.fFloat_Type || type == *fContext.fHalf_Type || type == *fContext.fFloatLiteral_Type) { this->writeInstruction(SpvOpTypeFloat, result, 32, fConstantBuffer); - } else if (type == *fContext.fDouble_Type) { - this->writeInstruction(SpvOpTypeFloat, result, 64, fConstantBuffer); } else { SkASSERT(false); } @@ -2510,42 +2507,26 @@ SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) { } SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) { - if (f.fType != *fContext.fDouble_Type) { - ConstantType type; - if (f.fType == *fContext.fHalf_Type) { - type = ConstantType::kHalf; - } else { - type = ConstantType::kFloat; - } - float value = (float) f.fValue; - std::pair key(f.fValue, type); - auto entry = fNumberConstants.find(key); - if (entry == fNumberConstants.end()) { - SpvId result = this->nextId(); - uint32_t bits; - SkASSERT(sizeof(bits) == sizeof(value)); - memcpy(&bits, &value, sizeof(bits)); - this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits, - fConstantBuffer); - fNumberConstants[key] = result; - return result; - } - return entry->second; + ConstantType type; + if (f.fType == *fContext.fHalf_Type) { + type = ConstantType::kHalf; } else { - std::pair key(f.fValue, ConstantType::kDouble); - auto entry = fNumberConstants.find(key); - if (entry == fNumberConstants.end()) { - SpvId result = this->nextId(); - uint64_t bits; - SkASSERT(sizeof(bits) == sizeof(f.fValue)); - memcpy(&bits, &f.fValue, sizeof(bits)); - this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, - bits & 0xffffffff, bits >> 32, fConstantBuffer); - fNumberConstants[key] = result; - return result; - } - return entry->second; + type = ConstantType::kFloat; } + float value = (float) f.fValue; + std::pair key(f.fValue, type); + auto entry = fNumberConstants.find(key); + if (entry == fNumberConstants.end()) { + SpvId result = this->nextId(); + uint32_t bits; + SkASSERT(sizeof(bits) == sizeof(value)); + memcpy(&bits, &value, sizeof(bits)); + this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits, + fConstantBuffer); + fNumberConstants[key] = result; + return result; + } + return entry->second; } SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, OutputStream& out) { diff --git a/src/sksl/ir/SkSLIndexExpression.h b/src/sksl/ir/SkSLIndexExpression.h index 2018881354..5e7a011937 100644 --- a/src/sksl/ir/SkSLIndexExpression.h +++ b/src/sksl/ir/SkSLIndexExpression.h @@ -33,14 +33,6 @@ static const Type& index_type(const Context& context, const Type& type) { case 4: return *context.fHalf4_Type; default: SkASSERT(false); } - } else { - SkASSERT(type.componentType() == *context.fDouble_Type); - switch (type.rows()) { - case 2: return *context.fDouble2_Type; - case 3: return *context.fDouble3_Type; - case 4: return *context.fDouble4_Type; - default: SkASSERT(false); - } } } return type.componentType(); diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h index 59ff04cb8e..040af8491a 100644 --- a/src/sksl/ir/SkSLSwizzle.h +++ b/src/sksl/ir/SkSLSwizzle.h @@ -44,12 +44,6 @@ static const Type& get_type(const Context& context, Expression& value, size_t co case 3: return *context.fHalf3_Type; case 4: return *context.fHalf4_Type; } - } else if (base == *context.fDouble_Type) { - switch (count) { - case 2: return *context.fDouble2_Type; - case 3: return *context.fDouble3_Type; - case 4: return *context.fDouble4_Type; - } } else if (base == *context.fInt_Type) { switch (count) { case 2: return *context.fInt2_Type; diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp index cd18e8ed91..edff101dc9 100644 --- a/src/sksl/ir/SkSLType.cpp +++ b/src/sksl/ir/SkSLType.cpp @@ -116,38 +116,6 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons } default: ABORT("unsupported row count (%d)", rows); } - } else if (*this == *context.fDouble_Type) { - switch (rows) { - case 1: - switch (columns) { - case 2: return *context.fDouble2_Type; - case 3: return *context.fDouble3_Type; - case 4: return *context.fDouble4_Type; - default: ABORT("unsupported vector column count (%d)", columns); - } - case 2: - switch (columns) { - case 2: return *context.fDouble2x2_Type; - case 3: return *context.fDouble3x2_Type; - case 4: return *context.fDouble4x2_Type; - default: ABORT("unsupported matrix column count (%d)", columns); - } - case 3: - switch (columns) { - case 2: return *context.fDouble2x3_Type; - case 3: return *context.fDouble3x3_Type; - case 4: return *context.fDouble4x3_Type; - default: ABORT("unsupported matrix column count (%d)", columns); - } - case 4: - switch (columns) { - case 2: return *context.fDouble2x4_Type; - case 3: return *context.fDouble3x4_Type; - case 4: return *context.fDouble4x4_Type; - default: ABORT("unsupported matrix column count (%d)", columns); - } - default: ABORT("unsupported row count (%d)", rows); - } } else if (*this == *context.fInt_Type || *this == *context.fIntLiteral_Type) { switch (rows) { case 1: diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h index 37303cbee9..e8c6a653cf 100644 --- a/src/sksl/ir/SkSLType.h +++ b/src/sksl/ir/SkSLType.h @@ -269,7 +269,7 @@ public: } /** - * Returns true if this is a floating-point scalar type (float, half, or double). + * Returns true if this is a floating-point scalar type (float or half). */ bool isFloat() const { return fNumberKind == kFloat_NumberKind; @@ -297,7 +297,7 @@ public: } /** - * Returns the "priority" of a number type, in order of double > float > half > int > short. + * Returns the "priority" of a number type, in order of float > half > int > short. * When operating on two number types, the result is the higher-priority type. */ int priority() const { diff --git a/src/sksl/sksl_gpu.inc b/src/sksl/sksl_gpu.inc index 1bacef0d09..6122e48dd2 100644 --- a/src/sksl/sksl_gpu.inc +++ b/src/sksl/sksl_gpu.inc @@ -104,15 +104,12 @@ $genType smoothstep(float edge0, float edge1, $genType x); $genHType smoothstep($genHType edge0, $genHType edge1, $genHType x); $genHType smoothstep(half edge0, half edge1, $genHType x); $genBType isnan($genType x); -$genBType isnan($genDType x); $genBType isinf($genType x); -$genBType isinf($genDType x); $genIType floatBitsToInt($genType value); $genType intBitsTofloat($genIType value); $genType uintBitsTofloat($genUType value); $genType fma($genType a, $genType b, $genType c); $genHType fma($genHType a, $genHType b, $genHType c); -$genDType fma($genDType a, $genDType b, $genDType c); sk_has_side_effects $genType frexp($genType x, out $genIType exp); $genType ldexp($genType x, in $genIType exp); uint packUnorm2x16(float2 v); @@ -123,34 +120,25 @@ float2 unpackUnorm2x16(uint p); float2 unpackSnorm2x16(uint p); float4 unpackUnorm4x8(uint p); float4 unpackSnorm4x8(uint p); -uint2 unpackDouble2x32(double v); uint packHalf2x16(float2 v); float2 unpackHalf2x16(uint v); float length($genType x); half length($genHType x); -double length($genDType x); float distance($genType p0, $genType p1); half distance($genHType p0, $genHType p1); -double distance($genDType p0, $genDType p1); float dot($genType x, $genType y); half dot($genHType x, $genHType y); -double dot($genDType x, $genDType y); float3 cross(float3 x, float3 y); half3 cross(half3 x, half3 y); -double3 cross(double3 x, double3 y); $genType normalize($genType x); $genHType normalize($genHType x); -$genDType normalize($genDType x); float4 ftransform(); $genType faceforward($genType N, $genType I, $genType Nref); $genHType faceforward($genHType N, $genHType I, $genHType Nref); -$genDType faceforward($genDType N, $genDType I, $genDType Nref); $genType reflect($genType I, $genType N); $genHType reflect($genHType I, $genHType N); -$genDType reflect($genDType I, $genDType N); $genType refract($genType I, $genType N, float eta); $genHType refract($genHType I, $genHType N, float eta); -$genDType refract($genDType I, $genDType N, float eta); $mat matrixCompMult($mat x, $mat y); float2x2 outerProduct(float2 c, float2 r); float3x3 outerProduct(float3 c, float3 r); @@ -202,35 +190,30 @@ half3x3 inverse(half3x3 m); half4x4 inverse(half4x4 m); $bvec lessThan($vec x, $vec y); $bvec lessThan($hvec x, $hvec y); -$bvec lessThan($dvec x, $dvec y); $bvec lessThan($ivec x, $ivec y); $bvec lessThan($svec x, $svec y); $bvec lessThan($usvec x, $usvec y); $bvec lessThan($uvec x, $uvec y); $bvec lessThanEqual($vec x, $vec y); $bvec lessThanEqual($hvec x, $hvec y); -$bvec lessThanEqual($dvec x, $dvec y); $bvec lessThanEqual($ivec x, $ivec y); $bvec lessThanEqual($uvec x, $uvec y); $bvec lessThanEqual($svec x, $svec y); $bvec lessThanEqual($usvec x, $usvec y); $bvec greaterThan($vec x, $vec y); $bvec greaterThan($hvec x, $hvec y); -$bvec greaterThan($dvec x, $dvec y); $bvec greaterThan($ivec x, $ivec y); $bvec greaterThan($uvec x, $uvec y); $bvec greaterThan($svec x, $svec y); $bvec greaterThan($usvec x, $usvec y); $bvec greaterThanEqual($vec x, $vec y); $bvec greaterThanEqual($hvec x, $hvec y); -$bvec greaterThanEqual($dvec x, $dvec y); $bvec greaterThanEqual($ivec x, $ivec y); $bvec greaterThanEqual($uvec x, $uvec y); $bvec greaterThanEqual($svec x, $svec y); $bvec greaterThanEqual($usvec x, $usvec y); $bvec equal($vec x, $vec y); $bvec equal($hvec x, $hvec y); -$bvec equal($dvec x, $dvec y); $bvec equal($ivec x, $ivec y); $bvec equal($uvec x, $uvec y); $bvec equal($svec x, $svec y); @@ -238,7 +221,6 @@ $bvec equal($usvec x, $usvec y); $bvec equal($bvec x, $bvec y); $bvec notEqual($vec x, $vec y); $bvec notEqual($hvec x, $hvec y); -$bvec notEqual($dvec x, $dvec y); $bvec notEqual($ivec x, $ivec y); $bvec notEqual($uvec x, $uvec y); $bvec notEqual($svec x, $svec y); diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp index faddfbe89b..9629cc26eb 100644 --- a/tests/SkSLGLSLTest.cpp +++ b/tests/SkSLGLSLTest.cpp @@ -1867,13 +1867,13 @@ DEF_TEST(SkSLTypePrecision, r) { test(r, "float f = 1;" "half h = 2;" - "double d = 3;" + "float d = 3;" "float2 f2 = float2(1, 2);" "half3 h3 = half3(1, 2, 3);" - "double4 d4 = double4(1, 2, 3, 4);" + "float4 d4 = float4(1, 2, 3, 4);" "float2x2 f22 = float2x2(1, 2, 3, 4);" "half2x4 h24 = half2x4(1, 2, 3, 4, 5, 6, 7, 8);" - "double4x2 d42 = double4x2(1, 2, 3, 4, 5, 6, 7, 8);" + "float4x2 d42 = float4x2(1, 2, 3, 4, 5, 6, 7, 8);" "void main() {" "sk_FragColor.r = half(f + h + d + f2.x + h3.x + d4.x + f22[0][0] + h24[0][0] + " "d42[0][0]);" @@ -1883,16 +1883,16 @@ DEF_TEST(SkSLTypePrecision, r) { "out vec4 sk_FragColor;\n" "float f = 1.0;\n" "float h = 2.0;\n" - "double d = 3.0;\n" + "float d = 3.0;\n" "vec2 f2 = vec2(1.0, 2.0);\n" "vec3 h3 = vec3(1.0, 2.0, 3.0);\n" - "dvec4 d4 = dvec4(1.0, 2.0, 3.0, 4.0);\n" + "vec4 d4 = vec4(1.0, 2.0, 3.0, 4.0);\n" "mat2 f22 = mat2(1.0, 2.0, 3.0, 4.0);\n" "mat2x4 h24 = mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n" - "dmat4x2 d42 = dmat4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n" + "mat4x2 d42 = mat4x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n" "void main() {\n" - " sk_FragColor.x = float(((((((double(f + h) + d) + double(f2.x)) + double(h3.x)) + " - "d4.x) + double(f22[0][0])) + double(h24[0][0])) + d42[0][0]);\n" + " sk_FragColor.x = (((((((f + h) + d) + f2.x) + h3.x) + d4.x) + " + "f22[0][0]) + h24[0][0]) + d42[0][0];\n" "}\n"); test(r, "float f = 1;"