Revert "Revert "support for 'half' types in sksl, plus general numeric type improvements""
This reverts commit 0e96055424
.
Bug: skia:
Change-Id: Id45d091c1950887316c901ed9c9281181f346bcf
Reviewed-on: https://skia-review.googlesource.com/29602
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
d9971c0c20
commit
dcba08e891
@ -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)",
|
||||
|
@ -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;
|
||||
|
@ -238,7 +238,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
v->defineConstantf("int", "PERSPECTIVE_FLAG", "0x%x", kPerspective_InfoFlag);
|
||||
v->codeAppendf("float3x3 shapeMatrix = float3x3(%s, %s, float3(0, 0, 1));",
|
||||
inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
|
||||
v->codeAppendf("if (0 != (%s & PERSPECTIVE_FLAG)) {",
|
||||
v->codeAppendf("if (0 != (%s & uint(PERSPECTIVE_FLAG))) {",
|
||||
inputs.attr(Attrib::kInstanceInfo));
|
||||
v->codeAppend ( "shapeMatrix[2] = ");
|
||||
inputs.fetchNextParam(kVec3f_GrSLType);
|
||||
@ -249,7 +249,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
bool hasSingleShapeType = SkIsPow2(ip.opInfo().fShapeTypes);
|
||||
if (!hasSingleShapeType) {
|
||||
v->defineConstant("SHAPE_TYPE_BIT", kShapeType_InfoBit);
|
||||
v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
|
||||
v->codeAppendf("uint shapeType = %s >> uint(SHAPE_TYPE_BIT);",
|
||||
inputs.attr(Attrib::kInstanceInfo));
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
} else {
|
||||
if (ip.opInfo().fShapeTypes & kRRect_ShapesMask) {
|
||||
v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {");
|
||||
v->codeAppend ("if (shapeType >= uint(SIMPLE_R_RECT_SHAPE_TYPE)) {");
|
||||
backend->setupRRect(v, &usedShapeDefinitions);
|
||||
v->codeAppend ("}");
|
||||
usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
|
||||
@ -278,7 +278,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
if (ip.opInfo().fShapeTypes & kRRect_ShapesMask) {
|
||||
v->codeAppend ("else ");
|
||||
}
|
||||
v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {");
|
||||
v->codeAppend ("if (uint(OVAL_SHAPE_TYPE) == shapeType) {");
|
||||
usedShapeDefinitions |= kOval_ShapeFlag;
|
||||
} else {
|
||||
v->codeAppend ("else {");
|
||||
@ -298,8 +298,8 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
if (!hasSingleInnerShapeType) {
|
||||
v->defineConstantf("int", "INNER_SHAPE_TYPE_MASK", "0x%x", kInnerShapeType_InfoMask);
|
||||
v->defineConstant("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
|
||||
v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> "
|
||||
"INNER_SHAPE_TYPE_BIT);",
|
||||
v->codeAppendf("uint innerShapeType = ((%s & uint(INNER_SHAPE_TYPE_MASK)) >> "
|
||||
"uint(INNER_SHAPE_TYPE_BIT));",
|
||||
inputs.attr(Attrib::kInstanceInfo));
|
||||
}
|
||||
// Here we take advantage of the fact that outerRect == localRect in recordDRRect.
|
||||
@ -330,7 +330,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
} else {
|
||||
if (ip.opInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
|
||||
v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {");
|
||||
v->codeAppend ("if (uint(SIMPLE_R_RECT_SHAPE_TYPE) == innerShapeType) {");
|
||||
backend->setupInnerSimpleRRect(v);
|
||||
v->codeAppend("}");
|
||||
usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
|
||||
@ -340,7 +340,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
if (ip.opInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
|
||||
v->codeAppend ("else ");
|
||||
}
|
||||
v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {");
|
||||
v->codeAppend ("if (uint(OVAL_SHAPE_TYPE) == innerShapeType) {");
|
||||
usedShapeDefinitions |= kOval_ShapeFlag;
|
||||
} else {
|
||||
v->codeAppend ("else {");
|
||||
@ -378,7 +378,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
if (ip.opInfo().fHasLocalMatrix && ip.opInfo().fHasParams) {
|
||||
v->defineConstantf("int", "LOCAL_MATRIX_FLAG", "0x%x", kLocalMatrix_InfoFlag);
|
||||
v->codeAppendf("if (0 != (%s & LOCAL_MATRIX_FLAG)) {",
|
||||
v->codeAppendf("if (0 != (%s & uint(LOCAL_MATRIX_FLAG))) {",
|
||||
inputs.attr(Attrib::kInstanceInfo));
|
||||
if (!ip.opInfo().fUsesLocalCoords) {
|
||||
inputs.skipParams(2);
|
||||
@ -421,7 +421,7 @@ void GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler,
|
||||
}
|
||||
|
||||
void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) {
|
||||
v->codeAppendf("uint2 corner = uint2(%s & 1, (%s >> 1) & 1);",
|
||||
v->codeAppendf("uint2 corner = uint2(uint(%s) & 1, (uint(%s) >> 1) & 1);",
|
||||
fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs));
|
||||
v->codeAppend ("float2 cornerSign = float2(corner) * 2.0 - 1.0;");
|
||||
v->codeAppendf("float2 radii%s;", fNeedsNeighborRadii ? ", neighborRadii" : "");
|
||||
@ -439,7 +439,7 @@ void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* use
|
||||
}
|
||||
} else {
|
||||
if (types & kSimpleRRect_ShapeFlag) {
|
||||
v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {");
|
||||
v->codeAppend ("if (uint(SIMPLE_R_RECT_SHAPE_TYPE) == shapeType) {");
|
||||
this->setupSimpleRadii(v);
|
||||
v->codeAppend ("}");
|
||||
*usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
|
||||
@ -449,7 +449,7 @@ void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* use
|
||||
if (types & kSimpleRRect_ShapeFlag) {
|
||||
v->codeAppend ("else ");
|
||||
}
|
||||
v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {");
|
||||
v->codeAppend ("if (uint(NINE_PATCH_SHAPE_TYPE) == shapeType) {");
|
||||
*usedShapeDefinitions |= kNinePatch_ShapeFlag;
|
||||
} else {
|
||||
v->codeAppend ("else {");
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -21,45 +21,65 @@ public:
|
||||
Context()
|
||||
: fInvalid_Type(new Type(String("<INVALID>")))
|
||||
, 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<Type> fFloat3_Type;
|
||||
const std::unique_ptr<Type> fFloat4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fHalf_Type;
|
||||
const std::unique_ptr<Type> fHalf2_Type;
|
||||
const std::unique_ptr<Type> fHalf3_Type;
|
||||
const std::unique_ptr<Type> fHalf4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fUInt_Type;
|
||||
const std::unique_ptr<Type> fUInt2_Type;
|
||||
const std::unique_ptr<Type> fUInt3_Type;
|
||||
@ -181,6 +219,16 @@ public:
|
||||
const std::unique_ptr<Type> fInt3_Type;
|
||||
const std::unique_ptr<Type> fInt4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fUShort_Type;
|
||||
const std::unique_ptr<Type> fUShort2_Type;
|
||||
const std::unique_ptr<Type> fUShort3_Type;
|
||||
const std::unique_ptr<Type> fUShort4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fShort_Type;
|
||||
const std::unique_ptr<Type> fShort2_Type;
|
||||
const std::unique_ptr<Type> fShort3_Type;
|
||||
const std::unique_ptr<Type> fShort4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fBool_Type;
|
||||
const std::unique_ptr<Type> fBool2_Type;
|
||||
const std::unique_ptr<Type> fBool3_Type;
|
||||
@ -196,6 +244,16 @@ public:
|
||||
const std::unique_ptr<Type> fFloat4x3_Type;
|
||||
const std::unique_ptr<Type> fFloat4x4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fHalf2x2_Type;
|
||||
const std::unique_ptr<Type> fHalf2x3_Type;
|
||||
const std::unique_ptr<Type> fHalf2x4_Type;
|
||||
const std::unique_ptr<Type> fHalf3x2_Type;
|
||||
const std::unique_ptr<Type> fHalf3x3_Type;
|
||||
const std::unique_ptr<Type> fHalf3x4_Type;
|
||||
const std::unique_ptr<Type> fHalf4x2_Type;
|
||||
const std::unique_ptr<Type> fHalf4x3_Type;
|
||||
const std::unique_ptr<Type> fHalf4x4_Type;
|
||||
|
||||
const std::unique_ptr<Type> fDouble2x2_Type;
|
||||
const std::unique_ptr<Type> fDouble2x3_Type;
|
||||
const std::unique_ptr<Type> fDouble2x4_Type;
|
||||
@ -249,6 +307,7 @@ public:
|
||||
const std::unique_ptr<Type> fGSamplerCubeArrayShadow_Type;
|
||||
|
||||
const std::unique_ptr<Type> fGenType_Type;
|
||||
const std::unique_ptr<Type> fGenHType_Type;
|
||||
const std::unique_ptr<Type> fGenDType_Type;
|
||||
const std::unique_ptr<Type> fGenIType_Type;
|
||||
const std::unique_ptr<Type> fGenUType_Type;
|
||||
@ -262,9 +321,12 @@ public:
|
||||
const std::unique_ptr<Type> fGVec2_Type;
|
||||
const std::unique_ptr<Type> fGVec3_Type;
|
||||
const std::unique_ptr<Type> fGVec4_Type;
|
||||
const std::unique_ptr<Type> fHVec_Type;
|
||||
const std::unique_ptr<Type> fDVec_Type;
|
||||
const std::unique_ptr<Type> fIVec_Type;
|
||||
const std::unique_ptr<Type> fUVec_Type;
|
||||
const std::unique_ptr<Type> fSVec_Type;
|
||||
const std::unique_ptr<Type> fUSVec_Type;
|
||||
|
||||
const std::unique_ptr<Type> fBVec_Type;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -910,7 +910,7 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> 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<Expression> 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<Expression> 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<std::unique_ptr<Expression>>& arguments,
|
||||
int* outCost) {
|
||||
int IRGenerator::callCost(const FunctionDeclaration& function,
|
||||
const std::vector<std::unique_ptr<Expression>>& arguments) {
|
||||
if (function.fParameters.size() != arguments.size()) {
|
||||
return false;
|
||||
return INT_MAX;
|
||||
}
|
||||
int total = 0;
|
||||
std::vector<const Type*> 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<Expression> IRGenerator::applyColorSpace(std::unique_ptr<Expression> texture,
|
||||
@ -1436,8 +1446,8 @@ std::unique_ptr<Expression> 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<Expression> 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<Expression>(new FloatLiteral(fContext, position, (double) value));
|
||||
}
|
||||
|
@ -106,11 +106,11 @@ private:
|
||||
std::unique_ptr<Expression> call(Position position,
|
||||
const FunctionDeclaration& function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments);
|
||||
bool determineCallCost(const FunctionDeclaration& function,
|
||||
const std::vector<std::unique_ptr<Expression>>& arguments,
|
||||
int* outCost);
|
||||
int callCost(const FunctionDeclaration& function,
|
||||
const std::vector<std::unique_ptr<Expression>>& arguments);
|
||||
std::unique_ptr<Expression> call(Position position, std::unique_ptr<Expression> function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments);
|
||||
int coercionCost(const Expression& expr, const Type& type);
|
||||
std::unique_ptr<Expression> coerce(std::unique_ptr<Expression> expr, const Type& type);
|
||||
std::unique_ptr<Block> convertBlock(const ASTBlock& block);
|
||||
std::unique_ptr<Statement> convertBreak(const ASTBreakStatement& b);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -52,37 +52,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<const Type*> 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<Field> 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<const Type*> coercibleTypes)
|
||||
Type(String name, NumberKind numberKind, std::vector<const Type*> coercibleTypes)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kScalar_Kind)
|
||||
, fIsNumber(isNumber)
|
||||
, fNumberKind(numberKind)
|
||||
, fCoercibleTypes(std::move(coercibleTypes))
|
||||
, fColumns(1)
|
||||
, fRows(1) {}
|
||||
@ -95,6 +105,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)
|
||||
@ -104,6 +115,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)
|
||||
@ -114,13 +126,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;
|
||||
}
|
||||
|
||||
@ -147,7 +160,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();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,17 +196,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
|
||||
@ -245,7 +284,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<const Type*> fCoercibleTypes;
|
||||
const int fColumns = -1;
|
||||
|
@ -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);
|
||||
|
@ -316,7 +316,7 @@ DEF_TEST(SkSLUsesPrecisionModifiers, r) {
|
||||
" sk_FragColor.xy = vec2(x, y);\n"
|
||||
"}\n");
|
||||
test(r,
|
||||
"void main() { float x = 0.75; highp float y = 1; x++; y++;"
|
||||
"void main() { float x = 0.75; half y = 1; x++; y++;"
|
||||
"sk_FragColor.rg = float2(x, y); }",
|
||||
*SkSL::ShaderCapsFactory::UsesPrecisionModifiers(),
|
||||
"#version 400\n"
|
||||
@ -324,7 +324,7 @@ DEF_TEST(SkSLUsesPrecisionModifiers, r) {
|
||||
"out mediump vec4 sk_FragColor;\n"
|
||||
"void main() {\n"
|
||||
" float x = 0.75;\n"
|
||||
" highp float y = 1.0;\n"
|
||||
" mediump float y = 1.0;\n"
|
||||
" x++;\n"
|
||||
" y++;\n"
|
||||
" sk_FragColor.xy = vec2(x, y);\n"
|
||||
@ -1432,4 +1432,151 @@ DEF_TEST(SkSLInvocations, r) {
|
||||
SkSL::Program::kGeometry_Kind);
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLTypePrecision, r) {
|
||||
test(r,
|
||||
"float f = 1;"
|
||||
"half h = 2;"
|
||||
"double d = 3;"
|
||||
"float2 f2 = float2(1, 2);"
|
||||
"half3 h3 = half3(1, 2, 3);"
|
||||
"double4 d4 = double4(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);",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"float f = 1.0;\n"
|
||||
"float h = 2.0;\n"
|
||||
"double 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"
|
||||
"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");
|
||||
test(r,
|
||||
"float f = 1;"
|
||||
"half h = 2;"
|
||||
"float2 f2 = float2(1, 2);"
|
||||
"half3 h3 = half3(1, 2, 3);"
|
||||
"float2x2 f22 = float2x2(1, 2, 3, 4);"
|
||||
"half2x4 h24 = half2x4(1, 2, 3, 4, 5, 6, 7, 8);",
|
||||
*SkSL::ShaderCapsFactory::UsesPrecisionModifiers(),
|
||||
"#version 400\n"
|
||||
"precision highp float;\n"
|
||||
"out mediump vec4 sk_FragColor;\n"
|
||||
"float f = 1.0;\n"
|
||||
"mediump float h = 2.0;\n"
|
||||
"vec2 f2 = vec2(1.0, 2.0);\n"
|
||||
"mediump vec3 h3 = vec3(1.0, 2.0, 3.0);\n"
|
||||
"mat2 f22 = mat2(1.0, 2.0, 3.0, 4.0);\n"
|
||||
"mediump mat2x4 h24 = mat2x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);\n");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLNumberConversions, r) {
|
||||
test(r,
|
||||
"short s = short(sqrt(1));"
|
||||
"int i = int(sqrt(1));"
|
||||
"ushort us = ushort(sqrt(1));"
|
||||
"uint ui = uint(sqrt(1));"
|
||||
"half h = sqrt(1);"
|
||||
"float f = sqrt(1);"
|
||||
"double d = sqrt(1);"
|
||||
"short s2s = s;"
|
||||
"short i2s = i;"
|
||||
"short us2s = short(us);"
|
||||
"short ui2s = short(ui);"
|
||||
"short h2s = short(h);"
|
||||
"short f2s = short(f);"
|
||||
"short d2fs = short(d);"
|
||||
"int s2i = s;"
|
||||
"int i2i = i;"
|
||||
"int us2i = int(us);"
|
||||
"int ui2i = int(ui);"
|
||||
"int h2i = int(h);"
|
||||
"int f2i = int(f);"
|
||||
"int d2fi = int(d);"
|
||||
"ushort s2us = ushort(s);"
|
||||
"ushort i2us = ushort(i);"
|
||||
"ushort us2us = us;"
|
||||
"ushort ui2us = ui;"
|
||||
"ushort h2us = ushort(h);"
|
||||
"ushort f2us = ushort(f);"
|
||||
"ushort d2fus = ushort(d);"
|
||||
"uint s2ui = uint(s);"
|
||||
"uint i2ui = uint(i);"
|
||||
"uint us2ui = us;"
|
||||
"uint ui2ui = ui;"
|
||||
"uint h2ui = uint(h);"
|
||||
"uint f2ui = uint(f);"
|
||||
"uint d2fui = uint(d);"
|
||||
"float s2f = s;"
|
||||
"float i2f = i;"
|
||||
"float us2f = us;"
|
||||
"float ui2f = ui;"
|
||||
"float h2f = h;"
|
||||
"float f2f = f;"
|
||||
"float d2f = d;"
|
||||
"double s2d = s;"
|
||||
"double i2d = i;"
|
||||
"double us2d = us;"
|
||||
"double ui2d = ui;"
|
||||
"double h2d = h;"
|
||||
"double f2d = f;"
|
||||
"double d2d = d;",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"int s = int(sqrt(1.0));\n"
|
||||
"int i = int(sqrt(1.0));\n"
|
||||
"uint us = uint(sqrt(1.0));\n"
|
||||
"uint ui = uint(sqrt(1.0));\n"
|
||||
"float h = sqrt(1.0);\n"
|
||||
"float f = sqrt(1.0);\n"
|
||||
"double d = sqrt(1.0);\n"
|
||||
"int s2s = s;\n"
|
||||
"int i2s = i;\n"
|
||||
"int us2s = int(us);\n"
|
||||
"int ui2s = int(ui);\n"
|
||||
"int h2s = int(h);\n"
|
||||
"int f2s = int(f);\n"
|
||||
"int d2fs = int(d);\n"
|
||||
"int s2i = s;\n"
|
||||
"int i2i = i;\n"
|
||||
"int us2i = int(us);\n"
|
||||
"int ui2i = int(ui);\n"
|
||||
"int h2i = int(h);\n"
|
||||
"int f2i = int(f);\n"
|
||||
"int d2fi = int(d);\n"
|
||||
"uint s2us = uint(s);\n"
|
||||
"uint i2us = uint(i);\n"
|
||||
"uint us2us = us;\n"
|
||||
"uint ui2us = ui;\n"
|
||||
"uint h2us = uint(h);\n"
|
||||
"uint f2us = uint(f);\n"
|
||||
"uint d2fus = uint(d);\n"
|
||||
"uint s2ui = uint(s);\n"
|
||||
"uint i2ui = uint(i);\n"
|
||||
"uint us2ui = us;\n"
|
||||
"uint ui2ui = ui;\n"
|
||||
"uint h2ui = uint(h);\n"
|
||||
"uint f2ui = uint(f);\n"
|
||||
"uint d2fui = uint(d);\n"
|
||||
"float s2f = float(s);\n"
|
||||
"float i2f = float(i);\n"
|
||||
"float us2f = float(us);\n"
|
||||
"float ui2f = float(ui);\n"
|
||||
"float h2f = h;\n"
|
||||
"float f2f = f;\n"
|
||||
"float d2f = d;\n"
|
||||
"double s2d = double(s);\n"
|
||||
"double i2d = double(i);\n"
|
||||
"double us2d = double(us);\n"
|
||||
"double ui2d = double(ui);\n"
|
||||
"double h2d = h;\n"
|
||||
"double f2d = f;\n"
|
||||
"double d2d = d;\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user