From 93061b53442ce303e9d3ef74c7eeddc034802c4f Mon Sep 17 00:00:00 2001 From: Ethan Nicholas Date: Tue, 1 Aug 2017 13:41:59 -0400 Subject: support for 'half' types in sksl, plus general numeric type improvements Bug: skia: Change-Id: Id285262fda8291847f11343d499b5df62ddb4b09 Reviewed-on: https://skia-review.googlesource.com/28980 Reviewed-by: Brian Salomon Commit-Queue: Ethan Nicholas --- src/gpu/effects/GrDitherEffect.cpp | 12 ++--- src/gpu/effects/GrDitherEffect.fp | 4 +- src/sksl/SkSLCPPCodeGenerator.cpp | 4 ++ src/sksl/SkSLCPPCodeGenerator.h | 2 + src/sksl/SkSLCompiler.cpp | 34 ++++++++++++ src/sksl/SkSLContext.h | 108 +++++++++++++++++++++++++++++-------- src/sksl/SkSLGLSLCodeGenerator.cpp | 51 ++++++++++++++++-- src/sksl/SkSLGLSLCodeGenerator.h | 4 +- src/sksl/SkSLIRGenerator.cpp | 58 +++++++++++++------- src/sksl/SkSLIRGenerator.h | 6 +-- src/sksl/ir/SkSLExpression.h | 4 ++ src/sksl/ir/SkSLIntLiteral.h | 7 +++ src/sksl/ir/SkSLType.cpp | 30 ++++++----- src/sksl/ir/SkSLType.h | 66 ++++++++++++++++++----- src/sksl/sksl.include | 50 ++++++++++++++--- 15 files changed, 348 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp index 3b70493338..17b94ff087 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -28,12 +28,12 @@ public: "0.0039215686274509803;\n break;\n case 1:\n range = " "0.015873015873015872;\n break;\n default:\n range = " "0.0083333333333333332;\n break;\n}\n@if (sk_Caps.integerSupport) {\n " - "int x = int(sk_FragCoord.x);\n int y = int(sk_FragCoord.y);\n uint m = " - "uint((((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) " - ">> 1) | (x & 4) >> 2);\n value = float(m) / 64.0 - 0.4921875;\n} else {\n " - "value = fract(sin(dot(sk_FragCoord.xy, float2(12.989800000000001, " - "78.233000000000004))) * 43758.545299999998) - 0.5;\n}\n%s = float4(clamp(%s.xyz + " - "value * range, 0.0, %s.w), %s.w);\n", + "uint x = uint(sk_FragCoord.x);\n uint y = uint(sk_FragCoord.y);\n uint m = " + "(((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) >> 1) " + "| (x & 4) >> 2;\n value = float(m) / 64.0 - 0.4921875;\n} else {\n value = " + "fract(sin(dot(sk_FragCoord.xy, float2(12.989800000000001, 78.233000000000004))) * " + "43758.545299999998) - 0.5;\n}\n%s = float4(clamp(%s.xyz + value * range, 0.0, " + "%s.w), %s.w);\n", _outer.rangeType(), args.fOutputColor, args.fInputColor ? args.fInputColor : "float4(1)", args.fInputColor ? args.fInputColor : "float4(1)", diff --git a/src/gpu/effects/GrDitherEffect.fp b/src/gpu/effects/GrDitherEffect.fp index f983702f2b..308e02ed43 100644 --- a/src/gpu/effects/GrDitherEffect.fp +++ b/src/gpu/effects/GrDitherEffect.fp @@ -48,8 +48,8 @@ void main() { } @if (sk_Caps.integerSupport) { // This ordered-dither code is lifted from the cpu backend. - int x = int(sk_FragCoord.x); - int y = int(sk_FragCoord.y); + uint x = uint(sk_FragCoord.x); + uint y = uint(sk_FragCoord.y); uint m = (y & 1) << 5 | (x & 1) << 4 | (y & 2) << 2 | (x & 2) << 1 | (y & 4) >> 1 | (x & 4) >> 2; diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp index 2276ce372e..76faef9aae 100644 --- a/src/sksl/SkSLCPPCodeGenerator.cpp +++ b/src/sksl/SkSLCPPCodeGenerator.cpp @@ -181,6 +181,10 @@ String CPPCodeGenerator::getSamplerHandle(const Variable& var) { ABORT("should have found sampler in parameters\n"); } +void CPPCodeGenerator::writeIntLiteral(const IntLiteral& i) { + this->write(to_string((int32_t) i.fValue)); +} + void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) { switch (ref.fVariable.fModifiers.fLayout.fBuiltin) { case SK_INCOLOR_BUILTIN: diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h index b4f31ba1b0..27b434a0ca 100644 --- a/src/sksl/SkSLCPPCodeGenerator.h +++ b/src/sksl/SkSLCPPCodeGenerator.h @@ -39,6 +39,8 @@ private: void writeIndexExpression(const IndexExpression& i) override; + void writeIntLiteral(const IntLiteral& i) override; + void writeVariableReference(const VariableReference& ref) override; String getSamplerHandle(const Variable& var); diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index d96515cd88..4ea956ce0f 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -68,6 +68,10 @@ Compiler::Compiler(Flags flags) ADD_TYPE(Float2); ADD_TYPE(Float3); ADD_TYPE(Float4); + ADD_TYPE(Half); + ADD_TYPE(Half2); + ADD_TYPE(Half3); + ADD_TYPE(Half4); ADD_TYPE(Double); ADD_TYPE(Double2); ADD_TYPE(Double3); @@ -80,6 +84,14 @@ Compiler::Compiler(Flags flags) ADD_TYPE(UInt2); ADD_TYPE(UInt3); ADD_TYPE(UInt4); + ADD_TYPE(Short); + ADD_TYPE(Short2); + ADD_TYPE(Short3); + ADD_TYPE(Short4); + ADD_TYPE(UShort); + ADD_TYPE(UShort2); + ADD_TYPE(UShort3); + ADD_TYPE(UShort4); ADD_TYPE(Bool); ADD_TYPE(Bool2); ADD_TYPE(Bool3); @@ -93,7 +105,26 @@ Compiler::Compiler(Flags flags) ADD_TYPE(Float4x2); ADD_TYPE(Float4x3); ADD_TYPE(Float4x4); + ADD_TYPE(Half2x2); + ADD_TYPE(Half2x3); + ADD_TYPE(Half2x4); + ADD_TYPE(Half3x2); + ADD_TYPE(Half3x3); + ADD_TYPE(Half3x4); + 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); @@ -104,9 +135,12 @@ Compiler::Compiler(Flags flags) ADD_TYPE(GVec2); ADD_TYPE(GVec3); ADD_TYPE(GVec4); + ADD_TYPE(HVec); ADD_TYPE(DVec); ADD_TYPE(IVec); ADD_TYPE(UVec); + ADD_TYPE(SVec); + ADD_TYPE(USVec); ADD_TYPE(BVec); ADD_TYPE(Sampler1D); diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h index 2de584fab2..b132cec33d 100644 --- a/src/sksl/SkSLContext.h +++ b/src/sksl/SkSLContext.h @@ -21,45 +21,65 @@ public: Context() : fInvalid_Type(new Type(String(""))) , fVoid_Type(new Type(String("void"))) - , fDouble_Type(new Type(String("double"), true)) + , fDouble_Type(new Type(String("double"), Type::kFloat_NumberKind)) , fDouble2_Type(new Type(String("double2"), *fDouble_Type, 2)) , fDouble3_Type(new Type(String("double3"), *fDouble_Type, 3)) , fDouble4_Type(new Type(String("double4"), *fDouble_Type, 4)) - , fFloat_Type(new Type(String("float"), true, { fDouble_Type.get() })) + , fFloat_Type(new Type(String("float"), Type::kFloat_NumberKind)) , fFloat2_Type(new Type(String("float2"), *fFloat_Type, 2)) , fFloat3_Type(new Type(String("float3"), *fFloat_Type, 3)) , fFloat4_Type(new Type(String("float4"), *fFloat_Type, 4)) - , fUInt_Type(new Type(String("uint"), true, { fFloat_Type.get(), fDouble_Type.get() })) + , fHalf_Type(new Type(String("half"), Type::kFloat_NumberKind)) + , fHalf2_Type(new Type(String("half2"), *fHalf_Type, 2)) + , fHalf3_Type(new Type(String("half3"), *fHalf_Type, 3)) + , fHalf4_Type(new Type(String("half4"), *fHalf_Type, 4)) + , fUInt_Type(new Type(String("uint"), Type::kUnsigned_NumberKind)) , fUInt2_Type(new Type(String("uint2"), *fUInt_Type, 2)) , fUInt3_Type(new Type(String("uint3"), *fUInt_Type, 3)) , fUInt4_Type(new Type(String("uint4"), *fUInt_Type, 4)) - , fInt_Type(new Type(String("int"), true, { fUInt_Type.get(), fFloat_Type.get(), - fDouble_Type.get() })) + , fInt_Type(new Type(String("int"), Type::kSigned_NumberKind)) , fInt2_Type(new Type(String("int2"), *fInt_Type, 2)) , fInt3_Type(new Type(String("int3"), *fInt_Type, 3)) , fInt4_Type(new Type(String("int4"), *fInt_Type, 4)) - , fBool_Type(new Type(String("bool"), false)) + , fUShort_Type(new Type(String("ushort"), Type::kUnsigned_NumberKind)) + , fUShort2_Type(new Type(String("ushort2"), *fUShort_Type, 2)) + , fUShort3_Type(new Type(String("ushort3"), *fUShort_Type, 3)) + , fUShort4_Type(new Type(String("ushort4"), *fUShort_Type, 4)) + , fShort_Type(new Type(String("short"), Type::kSigned_NumberKind)) + , fShort2_Type(new Type(String("short2"), *fShort_Type, 2)) + , fShort3_Type(new Type(String("short3"), *fShort_Type, 3)) + , fShort4_Type(new Type(String("short4"), *fShort_Type, 4)) + , fBool_Type(new Type(String("bool"), Type::kNonnumeric_NumberKind)) , fBool2_Type(new Type(String("bool2"), *fBool_Type, 2)) , fBool3_Type(new Type(String("bool3"), *fBool_Type, 3)) , fBool4_Type(new Type(String("bool4"), *fBool_Type, 4)) - , fFloat2x2_Type(new Type(String("float2x2"), *fFloat_Type, 2, 2)) + , fFloat2x2_Type(new Type(String("float2x2"), *fFloat_Type, 2, 2)) , fFloat2x3_Type(new Type(String("float2x3"), *fFloat_Type, 2, 3)) , fFloat2x4_Type(new Type(String("float2x4"), *fFloat_Type, 2, 4)) , fFloat3x2_Type(new Type(String("float3x2"), *fFloat_Type, 3, 2)) - , fFloat3x3_Type(new Type(String("float3x3"), *fFloat_Type, 3, 3)) + , fFloat3x3_Type(new Type(String("float3x3"), *fFloat_Type, 3, 3)) , fFloat3x4_Type(new Type(String("float3x4"), *fFloat_Type, 3, 4)) , fFloat4x2_Type(new Type(String("float4x2"), *fFloat_Type, 4, 2)) , fFloat4x3_Type(new Type(String("float4x3"), *fFloat_Type, 4, 3)) - , fFloat4x4_Type(new Type(String("float4x4"), *fFloat_Type, 4, 4)) - , fDouble2x2_Type(new Type(String("double2x2"), *fFloat_Type, 2, 2)) - , fDouble2x3_Type(new Type(String("double2x3"), *fFloat_Type, 2, 3)) - , fDouble2x4_Type(new Type(String("double2x4"), *fFloat_Type, 2, 4)) - , fDouble3x2_Type(new Type(String("double3x2"), *fFloat_Type, 3, 2)) - , fDouble3x3_Type(new Type(String("double3x3"), *fFloat_Type, 3, 3)) - , fDouble3x4_Type(new Type(String("double3x4"), *fFloat_Type, 3, 4)) - , fDouble4x2_Type(new Type(String("double4x2"), *fFloat_Type, 4, 2)) - , fDouble4x3_Type(new Type(String("double4x3"), *fFloat_Type, 4, 3)) - , fDouble4x4_Type(new Type(String("double4x4"), *fFloat_Type, 4, 4)) + , fFloat4x4_Type(new Type(String("float4x4"), *fFloat_Type, 4, 4)) + , fHalf2x2_Type(new Type(String("half2x2"), *fHalf_Type, 2, 2)) + , fHalf2x3_Type(new Type(String("half2x3"), *fHalf_Type, 2, 3)) + , fHalf2x4_Type(new Type(String("half2x4"), *fHalf_Type, 2, 4)) + , fHalf3x2_Type(new Type(String("half3x2"), *fHalf_Type, 3, 2)) + , fHalf3x3_Type(new Type(String("half3x3"), *fHalf_Type, 3, 3)) + , fHalf3x4_Type(new Type(String("half3x4"), *fHalf_Type, 3, 4)) + , fHalf4x2_Type(new Type(String("half4x2"), *fHalf_Type, 4, 2)) + , fHalf4x3_Type(new Type(String("half4x3"), *fHalf_Type, 4, 3)) + , fHalf4x4_Type(new Type(String("half4x4"), *fHalf_Type, 4, 4)) + , fDouble2x2_Type(new Type(String("double2x2"), *fDouble_Type, 2, 2)) + , fDouble2x3_Type(new Type(String("double2x3"), *fDouble_Type, 2, 3)) + , fDouble2x4_Type(new Type(String("double2x4"), *fDouble_Type, 2, 4)) + , fDouble3x2_Type(new Type(String("double3x2"), *fDouble_Type, 3, 2)) + , fDouble3x3_Type(new Type(String("double3x3"), *fDouble_Type, 3, 3)) + , fDouble3x4_Type(new Type(String("double3x4"), *fDouble_Type, 3, 4)) + , fDouble4x2_Type(new Type(String("double4x2"), *fDouble_Type, 4, 2)) + , fDouble4x3_Type(new Type(String("double4x3"), *fDouble_Type, 4, 3)) + , fDouble4x4_Type(new Type(String("double4x4"), *fDouble_Type, 4, 4)) , fSampler1D_Type(new Type(String("sampler1D"), SpvDim1D, false, false, false, true)) , fSampler2D_Type(new Type(String("sampler2D"), SpvDim2D, false, false, false, true)) , fSampler3D_Type(new Type(String("sampler3D"), SpvDim3D, false, false, false, true)) @@ -118,6 +138,8 @@ public: static_type(*fSamplerCubeArrayShadow_Type))) , fGenType_Type(new Type(String("$genType"), { fFloat_Type.get(), fFloat2_Type.get(), fFloat3_Type.get(), fFloat4_Type.get() })) + , fGenHType_Type(new Type(String("$genHType"), { fHalf_Type.get(), fHalf2_Type.get(), + fHalf3_Type.get(), fHalf4_Type.get() })) , fGenDType_Type(new Type(String("$genDType"), { fDouble_Type.get(), fDouble2_Type.get(), fDouble3_Type.get(), fDouble4_Type.get() })) , fGenIType_Type(new Type(String("$genIType"), { fInt_Type.get(), fInt2_Type.get(), @@ -130,23 +152,34 @@ public: fFloat2x4_Type.get(), fFloat3x2_Type.get(), fFloat3x3_Type.get(), fFloat3x4_Type.get(), fFloat4x2_Type.get(), fFloat4x3_Type.get(), - fFloat4x4_Type.get(), fDouble2x2_Type.get(), - fDouble2x3_Type.get(), fDouble2x4_Type.get(), - fDouble3x2_Type.get(), fDouble3x3_Type.get(), - fDouble3x4_Type.get(), fDouble4x2_Type.get(), - fDouble4x3_Type.get(), fDouble4x4_Type.get() })) + fFloat4x4_Type.get(), fHalf2x2_Type.get(), + fHalf2x3_Type.get(), fHalf2x4_Type.get(), + fHalf3x2_Type.get(), fHalf3x3_Type.get(), + fHalf3x4_Type.get(), fHalf4x2_Type.get(), + fHalf4x3_Type.get(), fHalf4x4_Type.get(), + fDouble2x2_Type.get(), fDouble2x3_Type.get(), + fDouble2x4_Type.get(), fDouble3x2_Type.get(), + fDouble3x3_Type.get(), fDouble3x4_Type.get(), + fDouble4x2_Type.get(), fDouble4x3_Type.get(), + fDouble4x4_Type.get() })) , fVec_Type(new Type(String("$vec"), { fInvalid_Type.get(), fFloat2_Type.get(), fFloat3_Type.get(), fFloat4_Type.get() })) , fGVec_Type(new Type(String("$gvec"))) , fGVec2_Type(new Type(String("$gfloat2"))) , fGVec3_Type(new Type(String("$gfloat3"))) , fGVec4_Type(new Type(String("$gfloat4"), static_type(*fFloat4_Type))) + , fHVec_Type(new Type(String("$hvec"), { fInvalid_Type.get(), fHalf2_Type.get(), + fHalf3_Type.get(), fHalf4_Type.get() })) , fDVec_Type(new Type(String("$dvec"), { fInvalid_Type.get(), fDouble2_Type.get(), fDouble3_Type.get(), fDouble4_Type.get() })) , fIVec_Type(new Type(String("$ivec"), { fInvalid_Type.get(), fInt2_Type.get(), fInt3_Type.get(), fInt4_Type.get() })) , fUVec_Type(new Type(String("$uvec"), { fInvalid_Type.get(), fUInt2_Type.get(), fUInt3_Type.get(), fUInt4_Type.get() })) + , fSVec_Type(new Type(String("$svec"), { fInvalid_Type.get(), fShort2_Type.get(), + fShort3_Type.get(), fShort4_Type.get() })) + , fUSVec_Type(new Type(String("$usvec"), { fInvalid_Type.get(), fUShort2_Type.get(), + fUShort3_Type.get(), fUShort4_Type.get() })) , fBVec_Type(new Type(String("$bvec"), { fInvalid_Type.get(), fBool2_Type.get(), fBool3_Type.get(), fBool4_Type.get() })) , fSkCaps_Type(new Type(String("$sk_Caps"))) @@ -171,6 +204,11 @@ public: const std::unique_ptr fFloat3_Type; const std::unique_ptr fFloat4_Type; + const std::unique_ptr fHalf_Type; + const std::unique_ptr fHalf2_Type; + const std::unique_ptr fHalf3_Type; + const std::unique_ptr fHalf4_Type; + const std::unique_ptr fUInt_Type; const std::unique_ptr fUInt2_Type; const std::unique_ptr fUInt3_Type; @@ -181,6 +219,16 @@ public: const std::unique_ptr fInt3_Type; const std::unique_ptr fInt4_Type; + const std::unique_ptr fUShort_Type; + const std::unique_ptr fUShort2_Type; + const std::unique_ptr fUShort3_Type; + const std::unique_ptr fUShort4_Type; + + const std::unique_ptr fShort_Type; + const std::unique_ptr fShort2_Type; + const std::unique_ptr fShort3_Type; + const std::unique_ptr fShort4_Type; + const std::unique_ptr fBool_Type; const std::unique_ptr fBool2_Type; const std::unique_ptr fBool3_Type; @@ -196,6 +244,16 @@ public: const std::unique_ptr fFloat4x3_Type; const std::unique_ptr fFloat4x4_Type; + const std::unique_ptr fHalf2x2_Type; + const std::unique_ptr fHalf2x3_Type; + const std::unique_ptr fHalf2x4_Type; + const std::unique_ptr fHalf3x2_Type; + const std::unique_ptr fHalf3x3_Type; + const std::unique_ptr fHalf3x4_Type; + const std::unique_ptr fHalf4x2_Type; + const std::unique_ptr fHalf4x3_Type; + const std::unique_ptr fHalf4x4_Type; + const std::unique_ptr fDouble2x2_Type; const std::unique_ptr fDouble2x3_Type; const std::unique_ptr fDouble2x4_Type; @@ -249,6 +307,7 @@ public: const std::unique_ptr fGSamplerCubeArrayShadow_Type; 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; @@ -262,9 +321,12 @@ public: const std::unique_ptr fGVec2_Type; const std::unique_ptr fGVec3_Type; const std::unique_ptr fGVec4_Type; + const std::unique_ptr fHVec_Type; const std::unique_ptr fDVec_Type; const std::unique_ptr fIVec_Type; const std::unique_ptr fUVec_Type; + const std::unique_ptr fSVec_Type; + const std::unique_ptr fUSVec_Type; const std::unique_ptr fBVec_Type; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 330f14517d..69d3028298 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -68,6 +68,7 @@ void GLSLCodeGenerator::writeType(const Type& type) { fIndentation++; for (const auto& f : type.fields()) { this->writeModifiers(f.fModifiers, false); + this->writeTypePrecision(*f.fType); // sizes (which must be static in structs) are part of the type name here this->writeType(*f.fType); this->writeLine(" " + f.fName + ";"); @@ -78,32 +79,38 @@ void GLSLCodeGenerator::writeType(const Type& type) { switch (type.kind()) { case Type::kVector_Kind: { Type component = type.componentType(); - if (component == *fContext.fFloat_Type) { + if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) { this->write("vec"); } else if (component == *fContext.fDouble_Type) { this->write("dvec"); } - else if (component == *fContext.fInt_Type) { + else if (component == *fContext.fInt_Type || component == *fContext.fShort_Type) { this->write("ivec"); } - else if (component == *fContext.fUInt_Type) { + else if (component == *fContext.fUInt_Type || component == *fContext.fUShort_Type) { this->write("uvec"); } else if (component == *fContext.fBool_Type) { this->write("bvec"); } + else { + ABORT("unsupported vector type"); + } this->write(to_string(type.columns())); break; } case Type::kMatrix_Kind: { Type component = type.componentType(); - if (component == *fContext.fFloat_Type) { + if (component == *fContext.fFloat_Type || component == *fContext.fHalf_Type) { this->write("mat"); } else if (component == *fContext.fDouble_Type) { this->write("dmat"); } + else { + ABORT("unsupported matrix type"); + } this->write(to_string(type.columns())); if (type.columns() != type.rows()) { this->write("x"); @@ -120,6 +127,21 @@ void GLSLCodeGenerator::writeType(const Type& type) { this->write("]"); break; } + case Type::kScalar_Kind: { + if (type == *fContext.fHalf_Type) { + this->write("float"); + } + else if (type == *fContext.fShort_Type) { + this->write("int"); + } + else if (type == *fContext.fUShort_Type) { + this->write("uint"); + } + else { + this->write(type.name()); + } + break; + } default: this->write(type.name()); } @@ -653,6 +675,7 @@ void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { } for (const auto& f : structType->fields()) { this->writeModifiers(f.fModifiers, false); + this->writeTypePrecision(*f.fType); this->writeType(*f.fType); this->writeLine(" " + f.fName + ";"); } @@ -676,6 +699,25 @@ void GLSLCodeGenerator::writeVarInitializer(const Variable& var, const Expressio this->writeExpression(value, kTopLevel_Precedence); } +void GLSLCodeGenerator::writeTypePrecision(const Type& type) { + if (fProgram.fSettings.fCaps->usesPrecisionModifiers()) { + switch (type.kind()) { + case Type::kScalar_Kind: + if (type == *fContext.fHalf_Type || type == *fContext.fShort_Type || + type == *fContext.fUShort_Type) { + this->write("mediump "); + } + break; + case Type::kVector_Kind: // fall through + case Type::kMatrix_Kind: + this->writeTypePrecision(type.componentType()); + break; + default: + break; + } + } +} + void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool global) { ASSERT(decl.fVars.size() > 0); bool wroteType = false; @@ -685,6 +727,7 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g this->write(", "); } else { this->writeModifiers(var.fVar->fModifiers, global); + this->writeTypePrecision(decl.fBaseType); this->writeType(decl.fBaseType); this->write(" "); wroteType = true; diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h index 115d89ab28..e10299aa14 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.h +++ b/src/sksl/SkSLGLSLCodeGenerator.h @@ -116,6 +116,8 @@ protected: virtual void writeVarInitializer(const Variable& var, const Expression& value); + void writeTypePrecision(const Type& type); + void writeVarDeclarations(const VarDeclarations& decl, bool global); void writeFragCoord(); @@ -150,7 +152,7 @@ protected: void writeBoolLiteral(const BoolLiteral& b); - void writeIntLiteral(const IntLiteral& i); + virtual void writeIntLiteral(const IntLiteral& i); void writeFloatLiteral(const FloatLiteral& f); diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp index 3604cd91d8..a46a9312c1 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -910,7 +910,7 @@ std::unique_ptr IRGenerator::coerce(std::unique_ptr expr if (expr->fType == *fContext.fInvalid_Type) { return nullptr; } - if (!expr->fType.canCoerceTo(type)) { + if (expr->coercionCost(type) == INT_MAX) { fErrors.error(expr->fPosition, "expected '" + type.description() + "', but found '" + expr->fType.description() + "'"); return nullptr; @@ -1213,8 +1213,20 @@ std::unique_ptr IRGenerator::convertBinaryExpression( const Type* leftType; const Type* rightType; const Type* resultType; - if (!determine_binary_type(fContext, expression.fOperator, left->fType, right->fType, &leftType, - &rightType, &resultType, + const Type* rawLeftType; + if (left->fKind == Expression::kIntLiteral_Kind && right->fType.isInteger()) { + rawLeftType = &right->fType; + } else { + rawLeftType = &left->fType; + } + const Type* rawRightType; + if (right->fKind == Expression::kIntLiteral_Kind && left->fType.isInteger()) { + rawRightType = &left->fType; + } else { + rawRightType = &right->fType; + } + if (!determine_binary_type(fContext, expression.fOperator, *rawLeftType, *rawRightType, + &leftType, &rightType, &resultType, !Token::IsAssignment(expression.fOperator))) { fErrors.error(expression.fPosition, "type mismatch: '" + Token::OperatorName(expression.fOperator) + @@ -1367,32 +1379,30 @@ std::unique_ptr IRGenerator::call(Position position, } /** - * Determines the cost of coercing the arguments of a function to the required types. Returns true - * if the cost could be computed, false if the call is not valid. Cost has no particular meaning - * other than "lower costs are preferred". + * Determines the cost of coercing the arguments of a function to the required types. Cost has no + * particular meaning other than "lower costs are preferred". Returns INT_MAX if the call is not + * valid. */ -bool IRGenerator::determineCallCost(const FunctionDeclaration& function, - const std::vector>& arguments, - int* outCost) { +int IRGenerator::callCost(const FunctionDeclaration& function, + const std::vector>& arguments) { if (function.fParameters.size() != arguments.size()) { - return false; + return INT_MAX; } int total = 0; std::vector types; const Type* ignored; if (!function.determineFinalTypes(arguments, &types, &ignored)) { - return false; + return INT_MAX; } for (size_t i = 0; i < arguments.size(); i++) { - int cost; - if (arguments[i]->fType.determineCoercionCost(*types[i], &cost)) { + int cost = arguments[i]->coercionCost(*types[i]); + if (cost != INT_MAX) { total += cost; } else { - return false; + return INT_MAX; } } - *outCost = total; - return true; + return total; } std::unique_ptr IRGenerator::applyColorSpace(std::unique_ptr texture, @@ -1436,8 +1446,8 @@ std::unique_ptr IRGenerator::call(Position position, const FunctionDeclaration* best = nullptr; if (ref->fFunctions.size() > 1) { for (const auto& f : ref->fFunctions) { - int cost; - if (this->determineCallCost(*f, arguments, &cost) && cost < bestCost) { + int cost = this->callCost(*f, arguments); + if (cost < bestCost) { bestCost = cost; best = f; } @@ -1470,8 +1480,16 @@ std::unique_ptr IRGenerator::convertNumberConstructor( to_string((uint64_t) args.size()) + ")"); return nullptr; } - if (type == *fContext.fFloat_Type && args.size() == 1 && - args[0]->fKind == Expression::kIntLiteral_Kind) { + if (type.isFloat() && args[0]->fType.isFloat()) { + return std::move(args[0]); + } + if (type.isSigned() && args[0]->fType.isSigned()) { + return std::move(args[0]); + } + if (type.isUnsigned() && args[0]->fType.isUnsigned()) { + return std::move(args[0]); + } + if (type.isFloat() && args.size() == 1 && args[0]->fKind == Expression::kIntLiteral_Kind) { int64_t value = ((IntLiteral&) *args[0]).fValue; return std::unique_ptr(new FloatLiteral(fContext, position, (double) value)); } diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h index 70416c5379..0a1bae4f64 100644 --- a/src/sksl/SkSLIRGenerator.h +++ b/src/sksl/SkSLIRGenerator.h @@ -106,11 +106,11 @@ private: std::unique_ptr call(Position position, const FunctionDeclaration& function, std::vector> arguments); - bool determineCallCost(const FunctionDeclaration& function, - const std::vector>& arguments, - int* outCost); + int callCost(const FunctionDeclaration& function, + const std::vector>& arguments); std::unique_ptr call(Position position, std::unique_ptr function, std::vector> arguments); + int coercionCost(const Expression& expr, const Type& type); std::unique_ptr coerce(std::unique_ptr expr, const Type& type); std::unique_ptr convertBlock(const ASTBlock& block); std::unique_ptr convertBreak(const ASTBreakStatement& b); diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h index 89a1a1e84a..286610f078 100644 --- a/src/sksl/ir/SkSLExpression.h +++ b/src/sksl/ir/SkSLExpression.h @@ -85,6 +85,10 @@ struct Expression : public IRNode { return nullptr; } + virtual int coercionCost(const Type& target) const { + return fType.coercionCost(target); + } + const Kind fKind; const Type& fType; diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h index d8eba5573a..6199f96610 100644 --- a/src/sksl/ir/SkSLIntLiteral.h +++ b/src/sksl/ir/SkSLIntLiteral.h @@ -40,6 +40,13 @@ struct IntLiteral : public Expression { return fValue == i.fValue; } + int coercionCost(const Type& target) const override { + if (target.isUnsigned()) { + return 0; + } + return INHERITED::coercionCost(target); + } + const int64_t fValue; typedef Expression INHERITED; diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp index 60d40cd867..1fdc9bb68a 100644 --- a/src/sksl/ir/SkSLType.cpp +++ b/src/sksl/ir/SkSLType.cpp @@ -10,31 +10,37 @@ namespace SkSL { -bool Type::determineCoercionCost(const Type& other, int* outCost) const { +int Type::coercionCost(const Type& other) const { if (*this == other) { - *outCost = 0; - return true; + return 0; } if (this->kind() == kVector_Kind && other.kind() == kVector_Kind) { if (this->columns() == other.columns()) { - return this->componentType().determineCoercionCost(other.componentType(), outCost); + return this->componentType().coercionCost(other.componentType()); } - return false; + return INT_MAX; } if (this->kind() == kMatrix_Kind) { - if (this->columns() == other.columns() && - this->rows() == other.rows()) { - return this->componentType().determineCoercionCost(other.componentType(), outCost); + if (this->columns() == other.columns() && this->rows() == other.rows()) { + return this->componentType().coercionCost(other.componentType()); } - return false; + return INT_MAX; + } + if (this->isNumber() && other.isFloat()) { + return 1; + } + if (this->isSigned() && other.isSigned()) { + return 1; + } + if (this->isUnsigned() && other.isUnsigned()) { + return 1; } for (size_t i = 0; i < fCoercibleTypes.size(); i++) { if (*fCoercibleTypes[i] == other) { - *outCost = (int) i + 1; - return true; + return (int) i + 1; } } - return false; + return INT_MAX; } const Type& Type::toCompound(const Context& context, int columns, int rows) const { diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h index 9d122635c2..1f793da2d9 100644 --- a/src/sksl/ir/SkSLType.h +++ b/src/sksl/ir/SkSLType.h @@ -51,37 +51,47 @@ public: kOther_Kind }; + enum NumberKind { + kFloat_NumberKind, + kSigned_NumberKind, + kUnsigned_NumberKind, + kNonnumeric_NumberKind + }; + // Create an "other" (special) type with the given name. These types cannot be directly // referenced from user code. Type(String name) : INHERITED(Position(), kType_Kind, std::move(name)) - , fTypeKind(kOther_Kind) {} + , fTypeKind(kOther_Kind) + , fNumberKind(kNonnumeric_NumberKind) {} // Create a generic type which maps to the listed types. Type(String name, std::vector types) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kGeneric_Kind) + , fNumberKind(kNonnumeric_NumberKind) , fCoercibleTypes(std::move(types)) {} // Create a struct type with the given fields. Type(Position position, String name, std::vector fields) : INHERITED(position, kType_Kind, std::move(name)) , fTypeKind(kStruct_Kind) + , fNumberKind(kNonnumeric_NumberKind) , fFields(std::move(fields)) {} // Create a scalar type. - Type(String name, bool isNumber) + Type(String name, NumberKind numberKind) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kScalar_Kind) - , fIsNumber(isNumber) + , fNumberKind(numberKind) , fColumns(1) , fRows(1) {} // Create a scalar type which can be coerced to the listed types. - Type(String name, bool isNumber, std::vector coercibleTypes) + Type(String name, NumberKind numberKind, std::vector coercibleTypes) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kScalar_Kind) - , fIsNumber(isNumber) + , fNumberKind(numberKind) , fCoercibleTypes(std::move(coercibleTypes)) , fColumns(1) , fRows(1) {} @@ -94,6 +104,7 @@ public: Type(String name, Kind kind, const Type& componentType, int columns) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kind) + , fNumberKind(kNonnumeric_NumberKind) , fComponentType(&componentType) , fColumns(columns) , fRows(1) @@ -103,6 +114,7 @@ public: Type(String name, const Type& componentType, int columns, int rows) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kMatrix_Kind) + , fNumberKind(kNonnumeric_NumberKind) , fComponentType(&componentType) , fColumns(columns) , fRows(rows) @@ -113,13 +125,14 @@ public: bool isSampled) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kSampler_Kind) + , fNumberKind(kNonnumeric_NumberKind) , fDimensions(dimensions) , fIsDepth(isDepth) , fIsArrayed(isArrayed) , fIsMultisampled(isMultisampled) , fIsSampled(isSampled) {} - String name() const { + const String& name() const { return fName; } @@ -146,7 +159,35 @@ public: * Returns true if this is a numeric scalar type. */ bool isNumber() const { - return fIsNumber; + return fNumberKind != kNonnumeric_NumberKind; + } + + /** + * Returns true if this is a floating-point scalar type (float, half, or double). + */ + bool isFloat() const { + return fNumberKind == kFloat_NumberKind; + } + + /** + * Returns true if this is a signed scalar type (int or short). + */ + bool isSigned() const { + return fNumberKind == kSigned_NumberKind; + } + + /** + * Returns true if this is an unsigned scalar type (uint or ushort). + */ + bool isUnsigned() const { + return fNumberKind == kUnsigned_NumberKind; + } + + /** + * Returns true if this is a signed or unsigned integer. + */ + bool isInteger() const { + return isSigned() || isUnsigned(); } /** @@ -154,17 +195,15 @@ public: * another type. */ bool canCoerceTo(const Type& other) const { - int cost; - return determineCoercionCost(other, &cost); + return coercionCost(other) != INT_MAX; } /** * Determines the "cost" of coercing (implicitly converting) this type to another type. The cost * is a number with no particular meaning other than that lower costs are preferable to higher - * costs. Returns true if a conversion is possible, false otherwise. The value of the out - * parameter is undefined if false is returned. + * costs. Returns INT_MAX if the coercion is not possible. */ - bool determineCoercionCost(const Type& other, int* outCost) const; + int coercionCost(const Type& other) const; /** * For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component @@ -244,7 +283,8 @@ private: typedef Symbol INHERITED; const Kind fTypeKind; - const bool fIsNumber = false; + // always kNonnumeric_NumberKind for non-scalar values + const NumberKind fNumberKind; const Type* fComponentType = nullptr; const std::vector fCoercibleTypes; const int fColumns = -1; diff --git a/src/sksl/sksl.include b/src/sksl/sksl.include index 5d905e3435..7b738d5845 100644 --- a/src/sksl/sksl.include +++ b/src/sksl/sksl.include @@ -99,6 +99,8 @@ $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); //$genDType fma($genDType a, $genDType b, $genDType c); $genType frexp($genType x, out $genIType exp); //$genDType frexp($genDType x, out $genIType exp); @@ -117,22 +119,30 @@ uint2 unpackDouble2x32(double v); uint packHalf2x16(float2 v); float2 unpackHalf2x16(uint v); float length($genType x); -//double length($genDType x); +half length($genHType x); +double length($genDType x); float distance($genType p0, $genType p1); -//double distance($genDType p0, $genDType p1); +half distance($genHType p0, $genHType p1); +double distance($genDType p0, $genDType p1); float dot($genType x, $genType y); -//double dot($genDType x, $genDType y); +half dot($genHType x, $genHType y); +double dot($genDType x, $genDType y); float3 cross(float3 x, float3 y); -//double3 cross(double3 x, double3 y); +half3 cross(half3 x, half3 y); +double3 cross(double3 x, double3 y); $genType normalize($genType x); -//$genDType normalize($genDType x); +$genHType normalize($genHType x); +$genDType normalize($genDType x); float4 ftransform(); $genType faceforward($genType N, $genType I, $genType Nref); -//$genDType faceforward($genDType N, $genDType I, $genDType Nref); +$genHType faceforward($genHType N, $genHType I, $genHType Nref); +$genDType faceforward($genDType N, $genDType I, $genDType Nref); $genType reflect($genType I, $genType N); -//$genDType reflect($genDType I, $genDType N); +$genHType reflect($genHType I, $genHType N); +$genDType reflect($genDType I, $genDType N); $genType refract($genType I, $genType N, float eta); -//$genDType refract($genDType I, $genDType 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); @@ -159,24 +169,48 @@ float2x2 inverse(float2x2 m); float3x3 inverse(float3x3 m); float4x4 inverse(float4x4 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); +$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); +$bvec notEqual($usvec x, $usvec y); $bvec notEqual($bvec x, $bvec y); bool any($bvec x); bool all($bvec x); -- cgit v1.2.3