From b609e6dc6a02336aed04caaddcdd5ccfbe7ba9ec Mon Sep 17 00:00:00 2001 From: Ruiqi Mao Date: Tue, 17 Jul 2018 10:19:38 -0400 Subject: added byte and ubyte types to SKSL created new GMs for skinning Bug: skia: Change-Id: I15fb2bd02fba8beb6dd2dd3f3716da016ea92192 Reviewed-on: https://skia-review.googlesource.com/140241 Commit-Queue: Ruiqi Mao Reviewed-by: Brian Osman Reviewed-by: Ethan Nicholas --- gm/convexpolyeffect.cpp | 6 +- gm/skinning.cpp | 228 ++++++++++++++++++++++ gn/gm.gni | 1 + include/private/GrTypesPriv.h | 82 ++++++++ src/core/SkCanvas.cpp | 4 +- src/gpu/GrDefaultGeoProcFactory.cpp | 70 ++++--- src/gpu/GrDefaultGeoProcFactory.h | 10 +- src/gpu/GrPrimitiveProcessor.h | 16 ++ src/gpu/GrShaderCaps.h | 3 + src/gpu/gl/GrGLCaps.cpp | 3 + src/gpu/gl/GrGLVertexArray.cpp | 32 +++ src/gpu/glsl/GrGLSL.cpp | 16 ++ src/gpu/mtl/GrMtlCaps.mm | 3 + src/gpu/ops/GrAAConvexPathRenderer.cpp | 11 +- src/gpu/ops/GrAAFillRectOp.cpp | 3 +- src/gpu/ops/GrAAHairLinePathRenderer.cpp | 3 +- src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp | 11 +- src/gpu/ops/GrAAStrokeRectOp.cpp | 11 +- src/gpu/ops/GrDashOp.cpp | 5 +- src/gpu/ops/GrDefaultPathRenderer.cpp | 6 +- src/gpu/ops/GrDrawAtlasOp.cpp | 10 +- src/gpu/ops/GrDrawVerticesOp.cpp | 32 +-- src/gpu/ops/GrDrawVerticesOp.h | 3 +- src/gpu/ops/GrNonAAFillRectOp.cpp | 26 ++- src/gpu/ops/GrNonAAStrokeRectOp.cpp | 3 +- src/gpu/ops/GrRegionOp.cpp | 10 +- src/gpu/ops/GrTessellatingPathRenderer.cpp | 6 +- src/gpu/vk/GrVkCaps.cpp | 3 + src/gpu/vk/GrVkPipeline.cpp | 16 ++ src/gpu/vk/GrVkUniformHandler.cpp | 27 +++ src/gpu/vk/GrVkVaryingHandler.cpp | 12 +- src/sksl/SkSLCPPCodeGenerator.cpp | 4 +- src/sksl/SkSLCompiler.cpp | 10 + src/sksl/SkSLContext.h | 24 +++ src/sksl/SkSLGLSLCodeGenerator.cpp | 21 +- src/sksl/SkSLHCodeGenerator.cpp | 4 +- src/sksl/SkSLJIT.cpp | 10 +- src/sksl/SkSLSPIRVCodeGenerator.cpp | 56 ++++-- src/sksl/ir/SkSLSwizzle.h | 12 ++ src/sksl/ir/SkSLType.cpp | 22 +++ tests/OnFlushCallbackTest.cpp | 3 +- 41 files changed, 732 insertions(+), 106 deletions(-) create mode 100644 gm/skinning.cpp diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index 78dcfe1add..41d53e6241 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -80,7 +80,11 @@ private: Color color(fColor); sk_sp gp(GrDefaultGeoProcFactory::Make( - color, Coverage::kSolid_Type, LocalCoords::kUnused_Type, SkMatrix::I())); + target->caps().shaderCaps(), + color, + Coverage::kSolid_Type, + LocalCoords::kUnused_Type, + SkMatrix::I())); SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint)); QuadHelper helper; diff --git a/gm/skinning.cpp b/gm/skinning.cpp new file mode 100644 index 0000000000..101522fa48 --- /dev/null +++ b/gm/skinning.cpp @@ -0,0 +1,228 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkCanvas.h" +#include "SkVertices.h" +#include "SkPoint.h" +#include +#include + +using namespace skiagm; + +static const int kCellSize = 60; +static const int kColumnSize = 36; + +static const int kBoneCount = 7; +static const SkMatrix kBones[] = { + SkMatrix::I(), + SkMatrix::MakeTrans(10, 0), + SkMatrix::MakeTrans(0, 10), + SkMatrix::MakeTrans(-10, 0), + SkMatrix::MakeTrans(0, -10), + SkMatrix::MakeScale(0.5f), + SkMatrix::MakeScale(1.5f), +}; + +static const int kVertexCount = 4; +static const SkPoint kPositions[] = { + { 0, 0 }, + { 0, 30 }, + { 30, 30 }, + { 30, 0 }, +}; +static const SkColor kColors[] = { + 0xFFFF0000, + 0xFF00FF00, + 0xFF0000FF, + 0xFFFFFF00, +}; +static const SkVertices::BoneIndices kBoneIndices[] = { + {{ 1, 0, 0, 0 }}, + {{ 2, 1, 0, 0 }}, + {{ 3, 2, 1, 0 }}, + {{ 4, 3, 2, 1 }}, +}; +static const SkVertices::BoneWeights kBoneWeights[] = { + {{ 1.0f, 0.0f, 0.0f, 0.0f }}, + {{ 0.5f, 0.5f, 0.0f, 0.0f }}, + {{ 0.34f, 0.33f, 0.33f, 0.0f }}, + {{ 0.25f, 0.25f, 0.25f, 0.25f }}, +}; + +static const int kIndexCount = 6; +static const uint16_t kIndices[] = { + 0, 1, 2, + 2, 3, 0, +}; + +// Swap two SkMatrix pointers in place. +static void swap(const SkMatrix** x, const SkMatrix** y) { + const SkMatrix* temp = *x; + *x = *y; + *y = temp; +} + +class SkinningGM : public GM { + +public: + SkinningGM(bool deformUsingCPU) + : fPaint() + , fVertices(nullptr) + , fDeformUsingCPU(deformUsingCPU) + {} + +protected: + bool runAsBench() const override { + return true; + } + + SkString onShortName() override { + SkString name("skinning"); + if (fDeformUsingCPU) { + name.append("_cpu"); + } + return name; + } + + SkISize onISize() override { + return SkISize::Make(2400, 2400); + } + + void onOnceBeforeDraw() override { + fVertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, + kVertexCount, + kPositions, + nullptr, + kColors, + kBoneIndices, + kBoneWeights, + kIndexCount, + kIndices, + false); // Keep the vertices non-volatile. + } + + void onDraw(SkCanvas* canvas) override { + // Set the initial position. + int xpos = kCellSize; + int ypos = kCellSize; + + // Create the mutable set of bones. + const SkMatrix* bones[kBoneCount]; + for (int i = 0; i < kBoneCount; i ++) { + bones[i] = &kBones[i]; + } + + // Draw the vertices. + drawPermutations(canvas, xpos, ypos, bones, 1); + } + +private: + void drawPermutations(SkCanvas* canvas, + int& xpos, + int& ypos, + const SkMatrix** bones, + int start) { + if (start == kBoneCount) { + // Reached the end of the permutations, so draw. + canvas->save(); + + // Copy the bones. + SkMatrix copiedBones[kBoneCount]; + for (int i = 0; i < kBoneCount; i ++) { + copiedBones[i] = *bones[i]; + } + + // Set the position. + canvas->translate(xpos, ypos); + + // Draw the vertices. + if (fDeformUsingCPU) { + // Deform with CPU. + std::vector positions(kVertexCount); + for (int i = 0; i < kVertexCount; i ++) { + const SkVertices::BoneIndices& indices = kBoneIndices[i]; + const SkVertices::BoneWeights& weights = kBoneWeights[i]; + + // Apply deformations. + SkPoint& result = positions[i]; + SkPoint transformed; + for (uint32_t j = 0; j < 4; j ++) { + // Get the bone attachment data. + uint32_t index = indices.indices[j]; + float weight = weights.weights[j]; + + // Skip the bone is there is no weight. + if (weight == 0.0f) { + continue; + } + SkASSERT(index != 0); + + // transformed = M * v + copiedBones[index].mapPoints(&transformed, &kPositions[i], 1); + + // result += transformed * w + result += transformed * weight; + } + } + + sk_sp vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, + kVertexCount, + positions.data(), + nullptr, + kColors, + kIndexCount, + kIndices); + canvas->drawVertices(vertices.get(), + SkBlendMode::kSrc, + fPaint); + } else { + // Deform with GPU. + canvas->drawVertices(fVertices.get(), + copiedBones, + kBoneCount, + SkBlendMode::kSrc, + fPaint); + } + + canvas->restore(); + + // Get a new position to draw the vertices. + xpos += kCellSize; + if (xpos > kCellSize * kColumnSize) { + xpos = kCellSize; + ypos += kCellSize; + } + + return; + } + + // Find all possible permutations within the given range. + for (int i = start; i < kBoneCount; i ++) { + // Swap the start and i-th elements. + swap(bones + start, bones + i); + + // Find permutations of the sub array. + drawPermutations(canvas, xpos, ypos, bones, start + 1); + + // Swap the elements back. + swap(bones + i, bones + start); + } + } + +private: + SkPaint fPaint; + sk_sp fVertices; + bool fDeformUsingCPU; + + typedef GM INHERITED; +}; + +///////////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new SkinningGM(true);) +DEF_GM(return new SkinningGM(false);) diff --git a/gn/gm.gni b/gn/gm.gni index 1b60d5ac5c..111d68d075 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -285,6 +285,7 @@ gm_sources = [ "$_gm/skbug_4868.cpp", "$_gm/skbug_5321.cpp", "$_gm/skbug1719.cpp", + "$_gm/skinning.cpp", "$_gm/smallarc.cpp", "$_gm/smallpaths.cpp", "$_gm/spritebitmap.cpp", diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h index 1490574193..ee6bfd8097 100644 --- a/include/private/GrTypesPriv.h +++ b/include/private/GrTypesPriv.h @@ -289,6 +289,14 @@ GrAAType GrChooseAAType(GrAA, GrFSAAType, GrAllowMixedSamples, const GrCaps&); enum GrSLType { kVoid_GrSLType, kBool_GrSLType, + kByte_GrSLType, + kByte2_GrSLType, + kByte3_GrSLType, + kByte4_GrSLType, + kUByte_GrSLType, + kUByte2_GrSLType, + kUByte3_GrSLType, + kUByte4_GrSLType, kShort_GrSLType, kShort2_GrSLType, kShort3_GrSLType, @@ -389,6 +397,14 @@ static inline bool GrSLTypeIsFloatType(GrSLType type) { case kTexture2DRectSampler_GrSLType: case kBufferSampler_GrSLType: case kBool_GrSLType: + case kByte_GrSLType: + case kByte2_GrSLType: + case kByte3_GrSLType: + case kByte4_GrSLType: + case kUByte_GrSLType: + case kUByte2_GrSLType: + case kUByte3_GrSLType: + case kUByte4_GrSLType: case kShort_GrSLType: case kShort2_GrSLType: case kShort3_GrSLType: @@ -417,6 +433,8 @@ static inline int GrSLTypeVecLength(GrSLType type) { case kFloat_GrSLType: case kHalf_GrSLType: case kBool_GrSLType: + case kByte_GrSLType: + case kUByte_GrSLType: case kShort_GrSLType: case kUShort_GrSLType: case kInt_GrSLType: @@ -425,6 +443,8 @@ static inline int GrSLTypeVecLength(GrSLType type) { case kFloat2_GrSLType: case kHalf2_GrSLType: + case kByte2_GrSLType: + case kUByte2_GrSLType: case kShort2_GrSLType: case kUShort2_GrSLType: case kInt2_GrSLType: @@ -433,6 +453,8 @@ static inline int GrSLTypeVecLength(GrSLType type) { case kFloat3_GrSLType: case kHalf3_GrSLType: + case kByte3_GrSLType: + case kUByte3_GrSLType: case kShort3_GrSLType: case kUShort3_GrSLType: case kInt3_GrSLType: @@ -440,6 +462,8 @@ static inline int GrSLTypeVecLength(GrSLType type) { case kFloat4_GrSLType: case kHalf4_GrSLType: + case kByte4_GrSLType: + case kUByte4_GrSLType: case kShort4_GrSLType: case kUShort4_GrSLType: case kInt4_GrSLType: @@ -494,6 +518,14 @@ static inline bool GrSLTypeIs2DCombinedSamplerType(GrSLType type) { case kUint2_GrSLType: case kBufferSampler_GrSLType: case kBool_GrSLType: + case kByte_GrSLType: + case kByte2_GrSLType: + case kByte3_GrSLType: + case kByte4_GrSLType: + case kUByte_GrSLType: + case kUByte2_GrSLType: + case kUByte3_GrSLType: + case kUByte4_GrSLType: case kShort_GrSLType: case kShort2_GrSLType: case kShort3_GrSLType: @@ -540,6 +572,14 @@ static inline bool GrSLTypeIsCombinedSamplerType(GrSLType type) { case kUint_GrSLType: case kUint2_GrSLType: case kBool_GrSLType: + case kByte_GrSLType: + case kByte2_GrSLType: + case kByte3_GrSLType: + case kByte4_GrSLType: + case kUByte_GrSLType: + case kUByte2_GrSLType: + case kUByte3_GrSLType: + case kUByte4_GrSLType: case kShort_GrSLType: case kShort2_GrSLType: case kShort3_GrSLType: @@ -568,6 +608,14 @@ static inline bool GrSLTypeAcceptsPrecision(GrSLType type) { case kVoid_GrSLType: case kBool_GrSLType: + case kByte_GrSLType: + case kByte2_GrSLType: + case kByte3_GrSLType: + case kByte4_GrSLType: + case kUByte_GrSLType: + case kUByte2_GrSLType: + case kUByte3_GrSLType: + case kUByte4_GrSLType: case kShort_GrSLType: case kShort2_GrSLType: case kShort3_GrSLType: @@ -638,6 +686,14 @@ static inline bool GrSLTypeTemporarilyAcceptsPrecision(GrSLType type) { case kVoid_GrSLType: case kBool_GrSLType: + case kByte_GrSLType: + case kByte2_GrSLType: + case kByte3_GrSLType: + case kByte4_GrSLType: + case kUByte_GrSLType: + case kUByte2_GrSLType: + case kUByte3_GrSLType: + case kUByte4_GrSLType: case kShort2_GrSLType: case kShort3_GrSLType: case kShort4_GrSLType: @@ -669,6 +725,16 @@ enum GrVertexAttribType { kInt3_GrVertexAttribType, // vector of 3 32-bit ints kInt4_GrVertexAttribType, // vector of 4 32-bit ints + + kByte_GrVertexAttribType, // signed byte + kByte2_GrVertexAttribType, // vector of 2 8-bit signed bytes + kByte3_GrVertexAttribType, // vector of 3 8-bit signed bytes + kByte4_GrVertexAttribType, // vector of 4 8-bit signed bytes + kUByte_GrVertexAttribType, // unsigned byte + kUByte2_GrVertexAttribType, // vector of 2 8-bit unsigned bytes + kUByte3_GrVertexAttribType, // vector of 3 8-bit unsigned bytes + kUByte4_GrVertexAttribType, // vector of 4 8-bit unsigned bytes + kUByte_norm_GrVertexAttribType, // unsigned byte, e.g. coverage, 0 -> 0.0f, 255 -> 1.0f. kUByte4_norm_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors, 0 -> 0.0f, // 255 -> 1.0f. @@ -719,6 +785,22 @@ static inline GrSLType GrVertexAttribTypeToSLType(GrVertexAttribType type) { return kInt3_GrSLType; case kInt4_GrVertexAttribType: return kInt4_GrSLType; + case kByte_GrVertexAttribType: + return kByte_GrSLType; + case kByte2_GrVertexAttribType: + return kByte_GrSLType; + case kByte3_GrVertexAttribType: + return kByte_GrSLType; + case kByte4_GrVertexAttribType: + return kByte4_GrSLType; + case kUByte_GrVertexAttribType: + return kUByte_GrSLType; + case kUByte2_GrVertexAttribType: + return kUByte_GrSLType; + case kUByte3_GrVertexAttribType: + return kUByte_GrSLType; + case kUByte4_GrVertexAttribType: + return kUByte4_GrSLType; case kInt_GrVertexAttribType: return kInt_GrSLType; case kUint_GrVertexAttribType: diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index c1f81188ce..cb98b09b37 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1682,7 +1682,7 @@ void SkCanvas::drawVertices(const sk_sp& vertices, const SkMatrix* b SkBlendMode mode, const SkPaint& paint) { TRACE_EVENT0("skia", TRACE_FUNC); RETURN_ON_NULL(vertices); - SkASSERT(boneCount <= 100); + SkASSERT(boneCount <= 80); this->onDrawVerticesObject(vertices.get(), bones, boneCount, mode, paint); } @@ -1690,7 +1690,7 @@ void SkCanvas::drawVertices(const SkVertices* vertices, const SkMatrix* bones, i SkBlendMode mode, const SkPaint& paint) { TRACE_EVENT0("skia", TRACE_FUNC); RETURN_ON_NULL(vertices); - SkASSERT(boneCount <= 100); + SkASSERT(boneCount <= 80); this->onDrawVerticesObject(vertices, bones, boneCount, mode, paint); } diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index b1c423aef7..027296c7ac 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -7,6 +7,7 @@ #include "GrDefaultGeoProcFactory.h" +#include "GrCaps.h" #include "SkRefCnt.h" #include "glsl/GrGLSLColorSpaceXformHelper.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -30,12 +31,13 @@ enum GPFlag { kBonesAttribute_GPFlag = 0x10, }; -static constexpr int kMaxBones = 100; // Due to GPU memory limitations, only up to 100 bone - // matrices are accepted. +static constexpr int kMaxBones = 80; // Due to GPU memory limitations, only up to 80 bone + // matrices are accepted. class DefaultGeoProc : public GrGeometryProcessor { public: - static sk_sp Make(uint32_t gpTypeFlags, + static sk_sp Make(const GrShaderCaps* shaderCaps, + uint32_t gpTypeFlags, GrColor color, sk_sp colorSpaceXform, const SkMatrix& viewMatrix, @@ -45,8 +47,8 @@ public: const float* bones, int boneCount) { return sk_sp(new DefaultGeoProc( - gpTypeFlags, color, std::move(colorSpaceXform), viewMatrix, localMatrix, coverage, - localCoordsWillBeRead, bones, boneCount)); + shaderCaps, gpTypeFlags, color, std::move(colorSpaceXform), viewMatrix, localMatrix, + coverage, localCoordsWillBeRead, bones, boneCount)); } const char* name() const override { return "DefaultGeometryProcessor"; } @@ -118,17 +120,26 @@ public: kMaxBones, &vertBonesUniformName); vertBuilder->codeAppendf( - "float2 transformedPosition = (%s[0] * float3(%s, 1)).xy;" - "float3x3 influence = float3x3(0);" - "for (int i = 0; i < 4; i++) {" - " int index = %s[i];" - " float weight = %s[i];" - " influence += %s[index] * weight;" - "}" - "transformedPosition = (influence * float3(transformedPosition, 1)).xy;", + "float3 originalPosition = %s[0] * float3(%s, 1);" + "float2 transformedPosition = float2(0);" + "for (int i = 0; i < 4; i++) {", vertBonesUniformName, - gp.fInPosition.name(), - gp.fInBoneIndices.name(), + gp.fInPosition.name()); + + if (args.fShaderCaps->unsignedSupport()) { + vertBuilder->codeAppendf( + " byte index = %s[i];", + gp.fInBoneIndices.name()); + } else { + vertBuilder->codeAppendf( + " byte index = byte(floor(%s[i] * 255 + 0.5));", + gp.fInBoneIndices.name()); + } + + vertBuilder->codeAppendf( + " float weight = %s[i];" + " transformedPosition += (%s[index] * originalPosition * weight).xy;" + "}", gp.fInBoneWeights.name(), vertBonesUniformName); transformedPositionName = "transformedPosition"; @@ -243,7 +254,8 @@ public: } private: - DefaultGeoProc(uint32_t gpTypeFlags, + DefaultGeoProc(const GrShaderCaps* shaderCaps, + uint32_t gpTypeFlags, GrColor color, sk_sp colorSpaceXform, const SkMatrix& viewMatrix, @@ -278,9 +290,13 @@ private: } if (fFlags & kBonesAttribute_GPFlag) { SkASSERT(bones && (boneCount > 0)); - fInBoneIndices = {"inBoneIndices", kInt4_GrVertexAttribType}; + // GLSL 1.10 and 1.20 don't support integer attributes. + GrVertexAttribType indicesAttribType = + shaderCaps->unsignedSupport() ? kByte4_GrVertexAttribType : + kUByte4_norm_GrVertexAttribType; + fInBoneIndices = {"inBoneIndices", indicesAttribType}; ++cnt; - fInBoneWeights = {"inBoneWeights", kFloat4_GrVertexAttribType}; + fInBoneWeights = {"inBoneWeights", kUByte4_norm_GrVertexAttribType}; ++cnt; } this->setVertexAttributeCnt(cnt); @@ -347,7 +363,8 @@ sk_sp DefaultGeoProc::TestCreate(GrProcessorTestData* d) { flags |= kBonesAttribute_GPFlag; } - return DefaultGeoProc::Make(flags, + return DefaultGeoProc::Make(d->caps()->shaderCaps(), + flags, GrRandomColor(d->fRandom), GrTest::TestColorXform(d->fRandom), GrTest::TestMatrix(d->fRandom), @@ -359,7 +376,8 @@ sk_sp DefaultGeoProc::TestCreate(GrProcessorTestData* d) { } #endif -sk_sp GrDefaultGeoProcFactory::Make(const Color& color, +sk_sp GrDefaultGeoProcFactory::Make(const GrShaderCaps* shaderCaps, + const Color& color, const Coverage& coverage, const LocalCoords& localCoords, const SkMatrix& viewMatrix) { @@ -376,7 +394,8 @@ sk_sp GrDefaultGeoProcFactory::Make(const Color& color, bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type; GrColor inColor = color.fColor; - return DefaultGeoProc::Make(flags, + return DefaultGeoProc::Make(shaderCaps, + flags, inColor, color.fColorSpaceXform, viewMatrix, @@ -388,6 +407,7 @@ sk_sp GrDefaultGeoProcFactory::Make(const Color& color, } sk_sp GrDefaultGeoProcFactory::MakeForDeviceSpace( + const GrShaderCaps* shaderCaps, const Color& color, const Coverage& coverage, const LocalCoords& localCoords, @@ -405,10 +425,11 @@ sk_sp GrDefaultGeoProcFactory::MakeForDeviceSpace( } LocalCoords inverted(LocalCoords::kUsePosition_Type, &invert); - return Make(color, coverage, inverted, SkMatrix::I()); + return Make(shaderCaps, color, coverage, inverted, SkMatrix::I()); } -sk_sp GrDefaultGeoProcFactory::MakeWithBones(const Color& color, +sk_sp GrDefaultGeoProcFactory::MakeWithBones(const GrShaderCaps* shaderCaps, + const Color& color, const Coverage& coverage, const LocalCoords& localCoords, const Bones& bones, @@ -427,7 +448,8 @@ sk_sp GrDefaultGeoProcFactory::MakeWithBones(const Color& c bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type; GrColor inColor = color.fColor; - return DefaultGeoProc::Make(flags, + return DefaultGeoProc::Make(shaderCaps, + flags, inColor, color.fColorSpaceXform, viewMatrix, diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h index 52db807ca4..3c4bd8ea46 100644 --- a/src/gpu/GrDefaultGeoProcFactory.h +++ b/src/gpu/GrDefaultGeoProcFactory.h @@ -10,6 +10,7 @@ #include "GrColorSpaceXform.h" #include "GrGeometryProcessor.h" +#include "GrShaderCaps.h" /* * A factory for creating default Geometry Processors which simply multiply position by the uniform @@ -127,7 +128,8 @@ namespace GrDefaultGeoProcFactory { int fBoneCount; }; - sk_sp Make(const Color&, + sk_sp Make(const GrShaderCaps*, + const Color&, const Coverage&, const LocalCoords&, const SkMatrix& viewMatrix); @@ -137,7 +139,8 @@ namespace GrDefaultGeoProcFactory { * attribute. The view matrix must still be provided to compute correctly transformed * coordinates for GrFragmentProcessors. It may fail if the view matrix is not invertible. */ - sk_sp MakeForDeviceSpace(const Color&, + sk_sp MakeForDeviceSpace(const GrShaderCaps*, + const Color&, const Coverage&, const LocalCoords&, const SkMatrix& viewMatrix); @@ -147,7 +150,8 @@ namespace GrDefaultGeoProcFactory { * deformation of vertices using matrices that are passed in. This should only be called from * GrDrawVerticesOp. */ - sk_sp MakeWithBones(const Color&, + sk_sp MakeWithBones(const GrShaderCaps*, + const Color&, const Coverage&, const LocalCoords&, const Bones&, diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h index 6563ad9a7d..e47d868fc0 100644 --- a/src/gpu/GrPrimitiveProcessor.h +++ b/src/gpu/GrPrimitiveProcessor.h @@ -178,6 +178,22 @@ static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) { return 3 * sizeof(int32_t); case kInt4_GrVertexAttribType: return 4 * sizeof(int32_t); + case kByte_GrVertexAttribType: + return 1 * sizeof(char); + case kByte2_GrVertexAttribType: + return 2 * sizeof(char); + case kByte3_GrVertexAttribType: + return 3 * sizeof(char); + case kByte4_GrVertexAttribType: + return 4 * sizeof(char); + case kUByte_GrVertexAttribType: + return 1 * sizeof(char); + case kUByte2_GrVertexAttribType: + return 2 * sizeof(char); + case kUByte3_GrVertexAttribType: + return 3 * sizeof(char); + case kUByte4_GrVertexAttribType: + return 4 * sizeof(char); case kUByte_norm_GrVertexAttribType: return 1 * sizeof(char); case kUByte4_norm_GrVertexAttribType: diff --git a/src/gpu/GrShaderCaps.h b/src/gpu/GrShaderCaps.h index ee3681a0b2..a599f1deab 100644 --- a/src/gpu/GrShaderCaps.h +++ b/src/gpu/GrShaderCaps.h @@ -84,6 +84,8 @@ public: bool halfIs32Bits() const { return fHalfIs32Bits; } + bool unsignedSupport() const { return fUnsignedSupport; } + AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; } bool mustEnableAdvBlendEqs() const { @@ -252,6 +254,7 @@ private: bool fFPManipulationSupport : 1; bool fFloatIs32Bits : 1; bool fHalfIs32Bits : 1; + bool fUnsignedSupport : 1; // Used for specific driver bug work arounds bool fCanUseAnyFunctionInShader : 1; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 1f208c8978..5e34c7a3cc 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -801,6 +801,9 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT); shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT); + + // Unsigned integers only supported in and after GLSL 1.30. + shaderCaps->fUnsignedSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration; } bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp index 68bcf21e7d..deca17d2c6 100644 --- a/src/gpu/gl/GrGLVertexArray.cpp +++ b/src/gpu/gl/GrGLVertexArray.cpp @@ -41,6 +41,22 @@ static AttribLayout attrib_layout(GrVertexAttribType type) { return {false, 3, GR_GL_INT}; case kInt4_GrVertexAttribType: return {false, 4, GR_GL_INT}; + case kByte_GrVertexAttribType: + return {false, 1, GR_GL_BYTE}; + case kByte2_GrVertexAttribType: + return {false, 2, GR_GL_BYTE}; + case kByte3_GrVertexAttribType: + return {false, 3, GR_GL_BYTE}; + case kByte4_GrVertexAttribType: + return {false, 4, GR_GL_BYTE}; + case kUByte_GrVertexAttribType: + return {false, 1, GR_GL_UNSIGNED_BYTE}; + case kUByte2_GrVertexAttribType: + return {false, 2, GR_GL_UNSIGNED_BYTE}; + case kUByte3_GrVertexAttribType: + return {false, 3, GR_GL_UNSIGNED_BYTE}; + case kUByte4_GrVertexAttribType: + return {false, 4, GR_GL_UNSIGNED_BYTE}; case kUByte_norm_GrVertexAttribType: return {true, 1, GR_GL_UNSIGNED_BYTE}; case kUByte4_norm_GrVertexAttribType: @@ -85,6 +101,22 @@ static bool GrVertexAttribTypeIsIntType(const GrShaderCaps* shaderCaps, return true; case kInt4_GrVertexAttribType: return true; + case kByte_GrVertexAttribType: + return true; + case kByte2_GrVertexAttribType: + return true; + case kByte3_GrVertexAttribType: + return true; + case kByte4_GrVertexAttribType: + return true; + case kUByte_GrVertexAttribType: + return true; + case kUByte2_GrVertexAttribType: + return true; + case kUByte3_GrVertexAttribType: + return true; + case kUByte4_GrVertexAttribType: + return true; case kUByte_norm_GrVertexAttribType: return false; case kUByte4_norm_GrVertexAttribType: diff --git a/src/gpu/glsl/GrGLSL.cpp b/src/gpu/glsl/GrGLSL.cpp index 67fe2995fa..807fe94176 100644 --- a/src/gpu/glsl/GrGLSL.cpp +++ b/src/gpu/glsl/GrGLSL.cpp @@ -85,6 +85,22 @@ const char* GrGLSLTypeString(const GrShaderCaps* shaderCaps, GrSLType t) { return "ushort3"; case kUShort4_GrSLType: return "ushort4"; + case kByte_GrSLType: + return "byte"; + case kByte2_GrSLType: + return "byte2"; + case kByte3_GrSLType: + return "byte3"; + case kByte4_GrSLType: + return "byte4"; + case kUByte_GrSLType: + return "ubyte"; + case kUByte2_GrSLType: + return "ubyte2"; + case kUByte3_GrSLType: + return "ubyte3"; + case kUByte4_GrSLType: + return "ubyte4"; case kTexture2D_GrSLType: return "texture2D"; case kSampler_GrSLType: diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm index d3dc54369a..2527be9ceb 100644 --- a/src/gpu/mtl/GrMtlCaps.mm +++ b/src/gpu/mtl/GrMtlCaps.mm @@ -242,6 +242,9 @@ void GrMtlCaps::initShaderCaps() { shaderCaps->fFloatIs32Bits = true; shaderCaps->fHalfIs32Bits = false; + // Metal supports unsigned integers. + shaderCaps->fUnsignedSupport = true; + shaderCaps->fMaxVertexSamplers = shaderCaps->fMaxFragmentSamplers = 16; // For now just cap at the per stage max. If we hit this limit we can come back to adjust this diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp index 7f54357cc4..3d475b947a 100644 --- a/src/gpu/ops/GrAAConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp @@ -723,7 +723,8 @@ static void extract_lines_only_verts(const GrAAConvexTessellator& tess, } } -static sk_sp make_lines_only_gp(bool tweakAlphaForCoverage, +static sk_sp make_lines_only_gp(const GrShaderCaps* shaderCaps, + bool tweakAlphaForCoverage, const SkMatrix& viewMatrix, bool usesLocalCoords) { using namespace GrDefaultGeoProcFactory; @@ -736,7 +737,10 @@ static sk_sp make_lines_only_gp(bool tweakAlphaForCoverage, } LocalCoords::Type localCoordsType = usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; - return MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, coverageType, localCoordsType, + return MakeForDeviceSpace(shaderCaps, + Color::kPremulGrColorAttribute_Type, + coverageType, + localCoordsType, viewMatrix); } @@ -790,7 +794,8 @@ public: private: void prepareLinesOnlyDraws(Target* target) { // Setup GrGeometryProcessor - sk_sp gp(make_lines_only_gp(fHelper.compatibleWithAlphaAsCoverage(), + sk_sp gp(make_lines_only_gp(target->caps().shaderCaps(), + fHelper.compatibleWithAlphaAsCoverage(), fPaths.back().fViewMatrix, fHelper.usesLocalCoords())); if (!gp) { diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp index 0d97de493a..592c0b2774 100644 --- a/src/gpu/ops/GrAAFillRectOp.cpp +++ b/src/gpu/ops/GrAAFillRectOp.cpp @@ -255,7 +255,8 @@ private: } sk_sp gp = - GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I()); + GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), color, coverageType, + lc, SkMatrix::I()); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp index bed8cbfd34..d6f3c0664e 100644 --- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp @@ -951,7 +951,8 @@ void AAHairlineOp::onPrepareDraws(Target* target) { LocalCoords localCoords(fHelper.usesLocalCoords() ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type); localCoords.fMatrix = geometryProcessorLocalM; - lineGP = GrDefaultGeoProcFactory::Make(color, Coverage::kAttribute_Type, localCoords, + lineGP = GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), + color, Coverage::kAttribute_Type, localCoords, *geometryProcessorViewM); } diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp index 958f0f991e..75662d35fe 100644 --- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp @@ -112,7 +112,8 @@ static void extract_verts(const GrAAConvexTessellator& tess, } } -static sk_sp create_lines_only_gp(bool tweakAlphaForCoverage, +static sk_sp create_lines_only_gp(const GrShaderCaps* shaderCaps, + bool tweakAlphaForCoverage, const SkMatrix& viewMatrix, bool usesLocalCoords) { using namespace GrDefaultGeoProcFactory; @@ -125,7 +126,10 @@ static sk_sp create_lines_only_gp(bool tweakAlphaForCoverag } LocalCoords::Type localCoordsType = usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; - return MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, coverageType, localCoordsType, + return MakeForDeviceSpace(shaderCaps, + Color::kPremulGrColorAttribute_Type, + coverageType, + localCoordsType, viewMatrix); } @@ -240,7 +244,8 @@ private: void onPrepareDraws(Target* target) override { auto pipe = fHelper.makePipeline(target); // Setup GrGeometryProcessor - sk_sp gp(create_lines_only_gp(fHelper.compatibleWithAlphaAsCoverage(), + sk_sp gp(create_lines_only_gp(target->caps().shaderCaps(), + fHelper.compatibleWithAlphaAsCoverage(), this->viewMatrix(), fHelper.usesLocalCoords())); if (!gp) { diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp index 1b2ab8e2a6..92d1c01a3d 100644 --- a/src/gpu/ops/GrAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrAAStrokeRectOp.cpp @@ -94,7 +94,8 @@ static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect* } } -static sk_sp create_stroke_rect_gp(bool tweakAlphaForCoverage, +static sk_sp create_stroke_rect_gp(const GrShaderCaps* shaderCaps, + bool tweakAlphaForCoverage, const SkMatrix& viewMatrix, bool usesLocalCoords) { using namespace GrDefaultGeoProcFactory; @@ -107,7 +108,10 @@ static sk_sp create_stroke_rect_gp(bool tweakAlphaForCovera } LocalCoords::Type localCoordsType = usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; - return MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, coverageType, localCoordsType, + return MakeForDeviceSpace(shaderCaps, + Color::kPremulGrColorAttribute_Type, + coverageType, + localCoordsType, viewMatrix); } @@ -258,7 +262,8 @@ private: } // anonymous namespace void AAStrokeRectOp::onPrepareDraws(Target* target) { - sk_sp gp(create_stroke_rect_gp(fHelper.compatibleWithAlphaAsCoverage(), + sk_sp gp(create_stroke_rect_gp(target->caps().shaderCaps(), + fHelper.compatibleWithAlphaAsCoverage(), this->viewMatrix(), fHelper.usesLocalCoords())); if (!gp) { diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp index 76203e521a..61fad24bcd 100644 --- a/src/gpu/ops/GrDashOp.cpp +++ b/src/gpu/ops/GrDashOp.cpp @@ -392,7 +392,10 @@ private: Color color(this->color()); LocalCoords::Type localCoordsType = fUsesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; - gp = MakeForDeviceSpace(color, Coverage::kSolid_Type, localCoordsType, + gp = MakeForDeviceSpace(target->caps().shaderCaps(), + color, + Coverage::kSolid_Type, + localCoordsType, this->viewMatrix()); } diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index 9fb1027375..07e40f0454 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -405,7 +405,11 @@ private: Coverage coverage(this->coverage()); LocalCoords localCoords(fHelper.usesLocalCoords() ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type); - gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, this->viewMatrix()); + gp = GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), + color, + coverage, + localCoords, + this->viewMatrix()); } SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint)); diff --git a/src/gpu/ops/GrDrawAtlasOp.cpp b/src/gpu/ops/GrDrawAtlasOp.cpp index 0f94d7e548..d280ad9dff 100644 --- a/src/gpu/ops/GrDrawAtlasOp.cpp +++ b/src/gpu/ops/GrDrawAtlasOp.cpp @@ -13,7 +13,8 @@ #include "SkRandom.h" #include "SkRectPriv.h" -static sk_sp make_gp(bool hasColors, +static sk_sp make_gp(const GrShaderCaps* shaderCaps, + bool hasColors, GrColor color, const SkMatrix& viewMatrix) { using namespace GrDefaultGeoProcFactory; @@ -22,7 +23,7 @@ static sk_sp make_gp(bool hasColors, gpColor.fType = Color::kPremulGrColorAttribute_Type; } - return GrDefaultGeoProcFactory::Make(gpColor, Coverage::kSolid_Type, + return GrDefaultGeoProcFactory::Make(shaderCaps, gpColor, Coverage::kSolid_Type, LocalCoords::kHasExplicit_Type, viewMatrix); } @@ -119,7 +120,10 @@ SkString GrDrawAtlasOp::dumpInfo() const { void GrDrawAtlasOp::onPrepareDraws(Target* target) { // Setup geometry processor - sk_sp gp(make_gp(this->hasColors(), this->color(), this->viewMatrix())); + sk_sp gp(make_gp(target->caps().shaderCaps(), + this->hasColors(), + this->color(), + this->viewMatrix())); int instanceCount = fGeoData.count(); size_t vertexStride = diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp index 83a703fb54..b5d16ea83a 100644 --- a/src/gpu/ops/GrDrawVerticesOp.cpp +++ b/src/gpu/ops/GrDrawVerticesOp.cpp @@ -152,7 +152,8 @@ GrDrawOp::RequiresDstTexture GrDrawVerticesOp::finalize(const GrCaps& caps, return result; } -sk_sp GrDrawVerticesOp::makeGP(bool* hasColorAttribute, +sk_sp GrDrawVerticesOp::makeGP(const GrShaderCaps* shaderCaps, + bool* hasColorAttribute, bool* hasLocalCoordAttribute, bool* hasBoneAttribute) const { using namespace GrDefaultGeoProcFactory; @@ -191,13 +192,15 @@ sk_sp GrDrawVerticesOp::makeGP(bool* hasColorAttribute, *hasBoneAttribute = this->hasBones(); if (this->hasBones()) { - return GrDefaultGeoProcFactory::MakeWithBones(color, + return GrDefaultGeoProcFactory::MakeWithBones(shaderCaps, + color, Coverage::kSolid_Type, localCoordsType, bones, vm); } else { - return GrDefaultGeoProcFactory::Make(color, + return GrDefaultGeoProcFactory::Make(shaderCaps, + color, Coverage::kSolid_Type, localCoordsType, vm); @@ -205,7 +208,8 @@ sk_sp GrDrawVerticesOp::makeGP(bool* hasColorAttribute, } void GrDrawVerticesOp::onPrepareDraws(Target* target) { - if (fMeshes[0].fVertices->isVolatile()) { + bool hasMapBufferSupport = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags(); + if (fMeshes[0].fVertices->isVolatile() || !hasMapBufferSupport) { this->drawVolatile(target); } else { this->drawNonVolatile(target); @@ -216,7 +220,8 @@ void GrDrawVerticesOp::drawVolatile(Target* target) { bool hasColorAttribute; bool hasLocalCoordsAttribute; bool hasBoneAttribute; - sk_sp gp = this->makeGP(&hasColorAttribute, + sk_sp gp = this->makeGP(target->caps().shaderCaps(), + &hasColorAttribute, &hasLocalCoordsAttribute, &hasBoneAttribute); @@ -224,7 +229,7 @@ void GrDrawVerticesOp::drawVolatile(Target* target) { size_t vertexStride = sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) + (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0) + - (hasBoneAttribute ? 4 * (sizeof(uint32_t) + sizeof(float)) : 0); + (hasBoneAttribute ? 4 * (sizeof(int8_t) + sizeof(uint8_t)) : 0); SkASSERT(vertexStride == gp->debugOnly_vertexStride()); // Allocate buffers. @@ -265,7 +270,8 @@ void GrDrawVerticesOp::drawNonVolatile(Target* target) { bool hasColorAttribute; bool hasLocalCoordsAttribute; bool hasBoneAttribute; - sk_sp gp = this->makeGP(&hasColorAttribute, + sk_sp gp = this->makeGP(target->caps().shaderCaps(), + &hasColorAttribute, &hasLocalCoordsAttribute, &hasBoneAttribute); @@ -300,7 +306,7 @@ void GrDrawVerticesOp::drawNonVolatile(Target* target) { size_t vertexStride = sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) + (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0) + - (hasBoneAttribute ? 4 * (sizeof(uint32_t) + sizeof(float)) : 0); + (hasBoneAttribute ? 4 * (sizeof(int8_t) + sizeof(uint8_t)) : 0); SkASSERT(vertexStride == gp->debugOnly_vertexStride()); // Allocate vertex buffer. @@ -417,7 +423,7 @@ void GrDrawVerticesOp::fillBuffers(bool hasColorAttribute, } size_t boneIndexOffset = offset; if (hasBoneAttribute) { - offset += 4 * sizeof(uint32_t); + offset += 4 * sizeof(int8_t); } size_t boneWeightOffset = offset; @@ -445,10 +451,10 @@ void GrDrawVerticesOp::fillBuffers(bool hasColorAttribute, const SkVertices::BoneIndices& indices = boneIndices[j]; const SkVertices::BoneWeights& weights = boneWeights[j]; for (int k = 0; k < 4; k++) { - size_t indexOffset = boneIndexOffset + sizeof(uint32_t) * k; - size_t weightOffset = boneWeightOffset + sizeof(float) * k; - *(uint32_t*)((intptr_t)verts + indexOffset) = indices.indices[k]; - *(float*)((intptr_t)verts + weightOffset) = weights.weights[k]; + size_t indexOffset = boneIndexOffset + sizeof(int8_t) * k; + size_t weightOffset = boneWeightOffset + sizeof(uint8_t) * k; + *(int8_t*)((intptr_t)verts + indexOffset) = indices.indices[k]; + *(uint8_t*)((intptr_t)verts + weightOffset) = weights.weights[k] * 255.0f; } } verts = (void*)((intptr_t)verts + vertexStride); diff --git a/src/gpu/ops/GrDrawVerticesOp.h b/src/gpu/ops/GrDrawVerticesOp.h index 9b638b8172..7695dd9f87 100644 --- a/src/gpu/ops/GrDrawVerticesOp.h +++ b/src/gpu/ops/GrDrawVerticesOp.h @@ -86,7 +86,8 @@ private: const GrBuffer* indexBuffer, int firstIndex); - sk_sp makeGP(bool* hasColorAttribute, + sk_sp makeGP(const GrShaderCaps* shaderCaps, + bool* hasColorAttribute, bool* hasLocalCoordAttribute, bool* hasBoneAttribute) const; diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp index 1b76d4abfe..c5542328c7 100644 --- a/src/gpu/ops/GrNonAAFillRectOp.cpp +++ b/src/gpu/ops/GrNonAAFillRectOp.cpp @@ -29,13 +29,17 @@ static const int kIndicesPerRect = 6; The vertex attrib order is always pos, color, [local coords]. */ -static sk_sp make_gp() { +static sk_sp make_gp(const GrShaderCaps* shaderCaps) { using namespace GrDefaultGeoProcFactory; - return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type, - LocalCoords::kHasExplicit_Type, SkMatrix::I()); + return GrDefaultGeoProcFactory::Make(shaderCaps, + Color::kPremulGrColorAttribute_Type, + Coverage::kSolid_Type, + LocalCoords::kHasExplicit_Type, + SkMatrix::I()); } -static sk_sp make_perspective_gp(const SkMatrix& viewMatrix, +static sk_sp make_perspective_gp(const GrShaderCaps* shaderCaps, + const SkMatrix& viewMatrix, bool hasExplicitLocalCoords, const SkMatrix* localMatrix) { SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())); @@ -50,15 +54,16 @@ static sk_sp make_perspective_gp(const SkMatrix& viewMatrix LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUsePosition_Type, localMatrix); - return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, + return GrDefaultGeoProcFactory::Make(shaderCaps, Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type, localCoords, viewMatrix); } else if (hasExplicitLocalCoords) { LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix); - return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, + return GrDefaultGeoProcFactory::Make(shaderCaps, Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type, localCoords, SkMatrix::I()); } else { LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix); - return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type, + return GrDefaultGeoProcFactory::MakeForDeviceSpace(shaderCaps, + Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type, localCoords, viewMatrix); } @@ -174,7 +179,7 @@ public: private: void onPrepareDraws(Target* target) override { - sk_sp gp = make_gp(); + sk_sp gp = make_gp(target->caps().shaderCaps()); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; @@ -304,7 +309,10 @@ public: private: void onPrepareDraws(Target* target) override { sk_sp gp = make_perspective_gp( - fViewMatrix, fHasLocalRect, fHasLocalMatrix ? &fLocalMatrix : nullptr); + target->caps().shaderCaps(), + fViewMatrix, + fHasLocalRect, + fHasLocalMatrix ? &fLocalMatrix : nullptr); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp index 357d9232ff..21636b26dc 100644 --- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp @@ -147,7 +147,8 @@ private: LocalCoords::Type localCoordsType = fHelper.usesLocalCoords() ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; - gp = GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, + gp = GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), color, + Coverage::kSolid_Type, localCoordsType, fViewMatrix); } diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp index 852cd46c70..d0c24e6e73 100644 --- a/src/gpu/ops/GrRegionOp.cpp +++ b/src/gpu/ops/GrRegionOp.cpp @@ -19,10 +19,12 @@ static const int kVertsPerInstance = 4; static const int kIndicesPerInstance = 6; -static sk_sp make_gp(const SkMatrix& viewMatrix) { +static sk_sp make_gp(const GrShaderCaps* shaderCaps, + const SkMatrix& viewMatrix) { using namespace GrDefaultGeoProcFactory; - return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type, - LocalCoords::kUsePosition_Type, viewMatrix); + return GrDefaultGeoProcFactory::Make(shaderCaps, Color::kPremulGrColorAttribute_Type, + Coverage::kSolid_Type, LocalCoords::kUsePosition_Type, + viewMatrix); } static void tesselate_region(intptr_t vertices, @@ -109,7 +111,7 @@ public: private: void onPrepareDraws(Target* target) override { - sk_sp gp = make_gp(fViewMatrix); + sk_sp gp = make_gp(target->caps().shaderCaps(), fViewMatrix); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp index 475197e197..2fea9cb053 100644 --- a/src/gpu/ops/GrTessellatingPathRenderer.cpp +++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp @@ -335,10 +335,12 @@ private: coverageType = Coverage::kSolid_Type; } if (fAntiAlias) { - gp = GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverageType, + gp = GrDefaultGeoProcFactory::MakeForDeviceSpace(target->caps().shaderCaps(), + color, coverageType, localCoordsType, fViewMatrix); } else { - gp = GrDefaultGeoProcFactory::Make(color, coverageType, localCoordsType, + gp = GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), + color, coverageType, localCoordsType, fViewMatrix); } } diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 8181569af3..8503bea5d6 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -399,6 +399,9 @@ void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint shaderCaps->fFloatIs32Bits = true; shaderCaps->fHalfIs32Bits = false; + // SPIR-V supports unsigned integers. + shaderCaps->fUnsignedSupport = true; + shaderCaps->fMaxVertexSamplers = shaderCaps->fMaxGeometrySamplers = shaderCaps->fMaxFragmentSamplers = SkTMin( diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp index 91f42ade37..60e7f43259 100644 --- a/src/gpu/vk/GrVkPipeline.cpp +++ b/src/gpu/vk/GrVkPipeline.cpp @@ -34,6 +34,22 @@ static inline VkFormat attrib_type_to_vkformat(GrVertexAttribType type) { return VK_FORMAT_R32G32B32_SINT; case kInt4_GrVertexAttribType: return VK_FORMAT_R32G32B32A32_SINT; + case kByte_GrVertexAttribType: + return VK_FORMAT_R8_SINT; + case kByte2_GrVertexAttribType: + return VK_FORMAT_R8G8_SINT; + case kByte3_GrVertexAttribType: + return VK_FORMAT_R8G8B8_SINT; + case kByte4_GrVertexAttribType: + return VK_FORMAT_R8G8B8A8_SINT; + case kUByte_GrVertexAttribType: + return VK_FORMAT_R8_UINT; + case kUByte2_GrVertexAttribType: + return VK_FORMAT_R8G8_UINT; + case kUByte3_GrVertexAttribType: + return VK_FORMAT_R8G8B8_UINT; + case kUByte4_GrVertexAttribType: + return VK_FORMAT_R8G8B8A8_UINT; case kUByte_norm_GrVertexAttribType: return VK_FORMAT_R8_UNORM; case kUByte4_norm_GrVertexAttribType: diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp index d92d8d2fd6..848d52a5cd 100644 --- a/src/gpu/vk/GrVkUniformHandler.cpp +++ b/src/gpu/vk/GrVkUniformHandler.cpp @@ -18,6 +18,17 @@ // https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/html/vkspec.html#interfaces-resources-layout uint32_t grsltype_to_alignment_mask(GrSLType type) { switch(type) { + case kByte_GrSLType: // fall through + case kUByte_GrSLType: + return 0x0; + case kByte2_GrSLType: // fall through + case kUByte2_GrSLType: + return 0x1; + case kByte3_GrSLType: // fall through + case kByte4_GrSLType: + case kUByte3_GrSLType: + case kUByte4_GrSLType: + return 0x3; case kShort_GrSLType: // fall through case kUShort_GrSLType: return 0x1; @@ -80,6 +91,22 @@ uint32_t grsltype_to_alignment_mask(GrSLType type) { /** Returns the size in bytes taken up in vulkanbuffers for GrSLTypes. */ static inline uint32_t grsltype_to_vk_size(GrSLType type) { switch(type) { + case kByte_GrSLType: + return sizeof(int8_t); + case kByte2_GrSLType: + return 2 * sizeof(int8_t); + case kByte3_GrSLType: + return 3 * sizeof(int8_t); + case kByte4_GrSLType: + return 4 * sizeof(int8_t); + case kUByte_GrSLType: + return sizeof(uint8_t); + case kUByte2_GrSLType: + return 2 * sizeof(uint8_t); + case kUByte3_GrSLType: + return 3 * sizeof(uint8_t); + case kUByte4_GrSLType: + return 4 * sizeof(uint8_t); case kShort_GrSLType: return sizeof(int16_t); case kShort2_GrSLType: diff --git a/src/gpu/vk/GrVkVaryingHandler.cpp b/src/gpu/vk/GrVkVaryingHandler.cpp index c8c56c2aa2..d210aba18f 100644 --- a/src/gpu/vk/GrVkVaryingHandler.cpp +++ b/src/gpu/vk/GrVkVaryingHandler.cpp @@ -30,14 +30,20 @@ static inline int grsltype_to_location_size(GrSLType type) { case kInt2_GrSLType: case kShort2_GrSLType: case kUShort2_GrSLType: + case kByte2_GrSLType: + case kUByte2_GrSLType: return 1; case kInt3_GrSLType: case kShort3_GrSLType: case kUShort3_GrSLType: + case kByte3_GrSLType: + case kUByte3_GrSLType: return 1; case kInt4_GrSLType: case kShort4_GrSLType: case kUShort4_GrSLType: + case kByte4_GrSLType: + case kUByte4_GrSLType: return 1; case kFloat2x2_GrSLType: case kHalf2x2_GrSLType: @@ -60,9 +66,11 @@ static inline int grsltype_to_location_size(GrSLType type) { return 1; case kInt_GrSLType: // fall through case kShort_GrSLType: + case kByte_GrSLType: return 1; - case kUint_GrSLType: - case kUShort_GrSLType: // fall through + case kUint_GrSLType: // fall through + case kUShort_GrSLType: + case kUByte_GrSLType: return 1; case kTexture2D_GrSLType: return 0; diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp index fe2dc701dc..be402088cc 100644 --- a/src/sksl/SkSLCPPCodeGenerator.cpp +++ b/src/sksl/SkSLCPPCodeGenerator.cpp @@ -177,7 +177,9 @@ void CPPCodeGenerator::writeRuntimeValue(const Type& type, const Layout& layout, } else if (type.kind() == Type::kEnum_Kind) { this->write("%d"); fFormatArgs.push_back("(int) " + cppCode); - } else if (type == *fContext.fInt4_Type || type == *fContext.fShort4_Type) { + } else if (type == *fContext.fInt4_Type || + type == *fContext.fShort4_Type || + type == *fContext.fByte4_Type) { this->write(type.name() + "(%d, %d, %d, %d)"); fFormatArgs.push_back(cppCode + ".left()"); fFormatArgs.push_back(cppCode + ".top()"); diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 0cf55c26d0..feaafebc79 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -100,6 +100,14 @@ Compiler::Compiler(Flags flags) ADD_TYPE(UShort2); ADD_TYPE(UShort3); ADD_TYPE(UShort4); + ADD_TYPE(Byte); + ADD_TYPE(Byte2); + ADD_TYPE(Byte3); + ADD_TYPE(Byte4); + ADD_TYPE(UByte); + ADD_TYPE(UByte2); + ADD_TYPE(UByte3); + ADD_TYPE(UByte4); ADD_TYPE(Bool); ADD_TYPE(Bool2); ADD_TYPE(Bool3); @@ -149,6 +157,8 @@ Compiler::Compiler(Flags flags) ADD_TYPE(UVec); ADD_TYPE(SVec); ADD_TYPE(USVec); + ADD_TYPE(ByteVec); + ADD_TYPE(UByteVec); ADD_TYPE(BVec); ADD_TYPE(Sampler1D); diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h index 61dd8042e4..ef2aef089e 100644 --- a/src/sksl/SkSLContext.h +++ b/src/sksl/SkSLContext.h @@ -49,6 +49,14 @@ public: , fShort2_Type(new Type("short2", *fShort_Type, 2)) , fShort3_Type(new Type("short3", *fShort_Type, 3)) , fShort4_Type(new Type("short4", *fShort_Type, 4)) + , fUByte_Type(new Type("ubyte", Type::kUnsigned_NumberKind, 0)) + , fUByte2_Type(new Type("ubyte2", *fUByte_Type, 2)) + , fUByte3_Type(new Type("ubyte3", *fUByte_Type, 3)) + , fUByte4_Type(new Type("ubyte4", *fUByte_Type, 4)) + , fByte_Type(new Type("byte", Type::kSigned_NumberKind, 0)) + , fByte2_Type(new Type("byte2", *fByte_Type, 2)) + , fByte3_Type(new Type("byte3", *fByte_Type, 3)) + , fByte4_Type(new Type("byte4", *fByte_Type, 4)) , fBool_Type(new Type("bool", Type::kNonnumeric_NumberKind, -1)) , fBool2_Type(new Type("bool2", *fBool_Type, 2)) , fBool3_Type(new Type("bool3", *fBool_Type, 3)) @@ -180,6 +188,10 @@ public: fShort3_Type.get(), fShort4_Type.get() })) , fUSVec_Type(new Type("$usvec", { fInvalid_Type.get(), fUShort2_Type.get(), fUShort3_Type.get(), fUShort4_Type.get() })) + , fByteVec_Type(new Type("$bytevec", { fInvalid_Type.get(), fByte2_Type.get(), + fByte3_Type.get(), fByte4_Type.get() })) + , fUByteVec_Type(new Type("$ubytevec", { fInvalid_Type.get(), fUByte2_Type.get(), + fUByte3_Type.get(), fUByte4_Type.get() })) , fBVec_Type(new Type("$bvec", { fInvalid_Type.get(), fBool2_Type.get(), fBool3_Type.get(), fBool4_Type.get() })) , fSkCaps_Type(new Type("$sk_Caps")) @@ -230,6 +242,16 @@ public: const std::unique_ptr fShort3_Type; const std::unique_ptr fShort4_Type; + const std::unique_ptr fUByte_Type; + const std::unique_ptr fUByte2_Type; + const std::unique_ptr fUByte3_Type; + const std::unique_ptr fUByte4_Type; + + const std::unique_ptr fByte_Type; + const std::unique_ptr fByte2_Type; + const std::unique_ptr fByte3_Type; + const std::unique_ptr fByte4_Type; + const std::unique_ptr fBool_Type; const std::unique_ptr fBool2_Type; const std::unique_ptr fBool3_Type; @@ -328,6 +350,8 @@ public: const std::unique_ptr fUVec_Type; const std::unique_ptr fSVec_Type; const std::unique_ptr fUSVec_Type; + const std::unique_ptr fByteVec_Type; + const std::unique_ptr fUByteVec_Type; const std::unique_ptr fBVec_Type; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index aa4f8252d0..5f6fedcdb5 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -82,10 +82,14 @@ String GLSLCodeGenerator::getTypeName(const Type& type) { else if (component == *fContext.fDouble_Type) { result = "dvec"; } - else if (component == *fContext.fInt_Type || component == *fContext.fShort_Type) { + else if (component == *fContext.fInt_Type || + component == *fContext.fShort_Type || + component == *fContext.fByte_Type) { result = "ivec"; } - else if (component == *fContext.fUInt_Type || component == *fContext.fUShort_Type) { + else if (component == *fContext.fUInt_Type || + component == *fContext.fUShort_Type || + component == *fContext.fUByte_Type) { result = "uvec"; } else if (component == *fContext.fBool_Type) { @@ -134,6 +138,12 @@ String GLSLCodeGenerator::getTypeName(const Type& type) { else if (type == *fContext.fUShort_Type) { return "uint"; } + else if (type == *fContext.fByte_Type) { + return "int"; + } + else if (type == *fContext.fUByte_Type) { + return "uint"; + } else { return type.name(); } @@ -857,7 +867,9 @@ void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) { this->write(to_string(i.fValue & 0xffffffff) + "u"); } else if (i.fType == *fContext.fUShort_Type) { this->write(to_string(i.fValue & 0xffff) + "u"); - } else { + } else if (i.fType == *fContext.fUByte_Type) { + this->write(to_string(i.fValue & 0xff) + "u"); + } else { this->write(to_string((int32_t) i.fValue)); } } @@ -1018,7 +1030,8 @@ const char* GLSLCodeGenerator::getTypePrecision(const Type& type) { if (usesPrecisionModifiers()) { switch (type.kind()) { case Type::kScalar_Kind: - if (type == *fContext.fShort_Type || type == *fContext.fUShort_Type) { + if (type == *fContext.fShort_Type || type == *fContext.fUShort_Type || + type == *fContext.fByte_Type || type == *fContext.fUByte_Type) { if (fProgram.fSettings.fForceHighPrecision || fProgram.fSettings.fCaps->incompleteShortIntPrecision()) { return "highp "; diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp index d6a92d3bac..be0f1ad858 100644 --- a/src/sksl/SkSLHCodeGenerator.cpp +++ b/src/sksl/SkSLHCodeGenerator.cpp @@ -33,7 +33,9 @@ String HCodeGenerator::ParameterType(const Context& context, const Type& type, return "float"; } else if (type == *context.fFloat2_Type || type == *context.fHalf2_Type) { return "SkPoint"; - } else if (type == *context.fInt4_Type || type == *context.fShort4_Type) { + } else if (type == *context.fInt4_Type || + type == *context.fShort4_Type || + type == *context.fByte4_Type) { return "SkIRect"; } else if (type == *context.fFloat4_Type || type == *context.fHalf4_Type) { return "SkRect"; diff --git a/src/sksl/SkSLJIT.cpp b/src/sksl/SkSLJIT.cpp index 57286b53fb..115a6be3ae 100644 --- a/src/sksl/SkSLJIT.cpp +++ b/src/sksl/SkSLJIT.cpp @@ -190,13 +190,13 @@ LLVMTypeRef JIT::getType(const Type& type) { if (type.name() == "float4" || type.name() == "half4") { return fFloat32Vector4Type; } - if (type.name() == "int2" || type.name() == "short2") { + if (type.name() == "int2" || type.name() == "short2" || type.name == "byte2") { return fInt32Vector2Type; } - if (type.name() == "int3" || type.name() == "short3") { + if (type.name() == "int3" || type.name() == "short3" || type.name == "byte3") { return fInt32Vector3Type; } - if (type.name() == "int4" || type.name() == "short4") { + if (type.name() == "int4" || type.name() == "short4" || type.name == "byte3") { return fInt32Vector4Type; } // fall through @@ -402,9 +402,9 @@ JIT::TypeKind JIT::typeKind(const Type& type) { if (type.kind() == Type::kVector_Kind) { return this->typeKind(type.componentType()); } - if (type.fName == "int" || type.fName == "short") { + if (type.fName == "int" || type.fName == "short" || type.fName == "byte") { return JIT::kInt_TypeKind; - } else if (type.fName == "uint" || type.fName == "ushort") { + } else if (type.fName == "uint" || type.fName == "ushort" || type.fName == "ubyte") { return JIT::kUInt_TypeKind; } else if (type.fName == "float" || type.fName == "double") { return JIT::kFloat_TypeKind; diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 84a15f1da1..3357faaa6e 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -154,14 +154,16 @@ static bool is_signed(const Context& context, const Type& type) { if (type.kind() == Type::kVector_Kind) { return is_signed(context, type.componentType()); } - return type == *context.fInt_Type || type == *context.fShort_Type; + return type == *context.fInt_Type || type == *context.fShort_Type || + type == *context.fByte_Type; } static bool is_unsigned(const Context& context, const Type& type) { if (type.kind() == Type::kVector_Kind) { return is_unsigned(context, type.componentType()); } - return type == *context.fUInt_Type || type == *context.fUShort_Type; + return type == *context.fUInt_Type || type == *context.fUShort_Type || + type == *context.fUByte_Type; } static bool is_bool(const Context& context, const Type& type) { @@ -433,20 +435,22 @@ Type SPIRVCodeGenerator::getActualType(const Type& type) { if (type == *fContext.fHalf_Type) { return *fContext.fFloat_Type; } - if (type == *fContext.fShort_Type) { + if (type == *fContext.fShort_Type || type == *fContext.fByte_Type) { return *fContext.fInt_Type; } - if (type == *fContext.fUShort_Type) { + if (type == *fContext.fUShort_Type || type == *fContext.fUByte_Type) { return *fContext.fUInt_Type; } if (type.kind() == Type::kMatrix_Kind || type.kind() == Type::kVector_Kind) { if (type.componentType() == *fContext.fHalf_Type) { return fContext.fFloat_Type->toCompound(fContext, type.columns(), type.rows()); } - if (type.componentType() == *fContext.fShort_Type) { + if (type.componentType() == *fContext.fShort_Type || + type.componentType() == *fContext.fByte_Type) { return fContext.fInt_Type->toCompound(fContext, type.columns(), type.rows()); } - if (type.componentType() == *fContext.fUShort_Type) { + if (type.componentType() == *fContext.fUShort_Type || + type.componentType() == *fContext.fUByte_Type) { return fContext.fUInt_Type->toCompound(fContext, type.columns(), type.rows()); } } @@ -1298,31 +1302,47 @@ SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, OutputStr if (c.fArguments.size() == 1) { return vec; } - } else if (src == *fContext.fInt_Type || src == *fContext.fShort_Type) { + } else if (src == *fContext.fInt_Type || + src == *fContext.fShort_Type || + src == *fContext.fByte_Type) { op = SpvOpConvertSToF; - } else if (src == *fContext.fUInt_Type || src == *fContext.fUShort_Type) { + } else if (src == *fContext.fUInt_Type || + src == *fContext.fUShort_Type || + src == *fContext.fUByte_Type) { op = SpvOpConvertUToF; } else { SkASSERT(false); } - } else if (dst == *fContext.fInt_Type || dst == *fContext.fShort_Type) { + } else if (dst == *fContext.fInt_Type || + dst == *fContext.fShort_Type || + dst == *fContext.fByte_Type) { if (src == *fContext.fFloat_Type || src == *fContext.fHalf_Type) { op = SpvOpConvertFToS; - } else if (src == *fContext.fInt_Type || src == *fContext.fShort_Type) { + } else if (src == *fContext.fInt_Type || + src == *fContext.fShort_Type || + src == *fContext.fByte_Type) { if (c.fArguments.size() == 1) { return vec; } - } else if (src == *fContext.fUInt_Type || src == *fContext.fUShort_Type) { + } else if (src == *fContext.fUInt_Type || + src == *fContext.fUShort_Type || + src == *fContext.fUByte_Type) { op = SpvOpBitcast; } else { SkASSERT(false); } - } else if (dst == *fContext.fUInt_Type || dst == *fContext.fUShort_Type) { + } else if (dst == *fContext.fUInt_Type || + dst == *fContext.fUShort_Type || + dst == *fContext.fUByte_Type) { if (src == *fContext.fFloat_Type || src == *fContext.fHalf_Type) { op = SpvOpConvertFToS; - } else if (src == *fContext.fInt_Type || src == *fContext.fShort_Type) { + } else if (src == *fContext.fInt_Type || + src == *fContext.fShort_Type || + src == *fContext.fByte_Type) { op = SpvOpBitcast; - } else if (src == *fContext.fUInt_Type || src == *fContext.fUShort_Type) { + } else if (src == *fContext.fUInt_Type || + src == *fContext.fUShort_Type || + src == *fContext.fUByte_Type) { if (c.fArguments.size() == 1) { return vec; } @@ -1391,9 +1411,13 @@ SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, OutputStream& o } if (c.fType == *fContext.fFloat_Type || c.fType == *fContext.fHalf_Type) { return this->writeFloatConstructor(c, out); - } else if (c.fType == *fContext.fInt_Type || c.fType == *fContext.fShort_Type) { + } else if (c.fType == *fContext.fInt_Type || + c.fType == *fContext.fShort_Type || + c.fType == *fContext.fByte_Type) { return this->writeIntConstructor(c, out); - } else if (c.fType == *fContext.fUInt_Type || c.fType == *fContext.fUShort_Type) { + } else if (c.fType == *fContext.fUInt_Type || + c.fType == *fContext.fUShort_Type || + c.fType == *fContext.fUByte_Type) { return this->writeUIntConstructor(c, out); } switch (c.fType.kind()) { diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h index b90b78d916..e713a323b3 100644 --- a/src/sksl/ir/SkSLSwizzle.h +++ b/src/sksl/ir/SkSLSwizzle.h @@ -56,6 +56,12 @@ static const Type& get_type(const Context& context, Expression& value, size_t co case 3: return *context.fShort3_Type; case 4: return *context.fShort4_Type; } + } else if (base == *context.fByte_Type) { + switch (count) { + case 2: return *context.fByte2_Type; + case 3: return *context.fByte3_Type; + case 4: return *context.fByte4_Type; + } } else if (base == *context.fUInt_Type) { switch (count) { case 2: return *context.fUInt2_Type; @@ -68,6 +74,12 @@ static const Type& get_type(const Context& context, Expression& value, size_t co case 3: return *context.fUShort3_Type; case 4: return *context.fUShort4_Type; } + } else if (base == *context.fUByte_Type) { + switch (count) { + case 2: return *context.fUByte2_Type; + case 3: return *context.fUByte3_Type; + case 4: return *context.fUByte4_Type; + } } else if (base == *context.fBool_Type) { switch (count) { case 2: return *context.fBool2_Type; diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp index d5698189b8..eb3a64f872 100644 --- a/src/sksl/ir/SkSLType.cpp +++ b/src/sksl/ir/SkSLType.cpp @@ -169,6 +169,17 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons } default: ABORT("unsupported row count (%d)", rows); } + } else if (*this == *context.fByte_Type) { + switch (rows) { + case 1: + switch (columns) { + case 2: return *context.fByte2_Type; + case 3: return *context.fByte3_Type; + case 4: return *context.fByte4_Type; + default: ABORT("unsupported vector column count (%d)", columns); + } + default: ABORT("unsupported row count (%d)", rows); + } } else if (*this == *context.fUInt_Type) { switch (rows) { case 1: @@ -191,6 +202,17 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons } default: ABORT("unsupported row count (%d)", rows); } + } else if (*this == *context.fUByte_Type) { + switch (rows) { + case 1: + switch (columns) { + case 2: return *context.fUByte2_Type; + case 3: return *context.fUByte3_Type; + case 4: return *context.fUByte4_Type; + default: ABORT("unsupported vector column count (%d)", columns); + } + default: ABORT("unsupported row count (%d)", rows); + } } else if (*this == *context.fBool_Type) { switch (rows) { case 1: diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp index ea871fbf44..efbc43a6ef 100644 --- a/tests/OnFlushCallbackTest.cpp +++ b/tests/OnFlushCallbackTest.cpp @@ -99,7 +99,8 @@ private: static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); sk_sp gp = - GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, + GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), + Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type, fHasLocalRect ? LocalCoords::kHasExplicit_Type : LocalCoords::kUnused_Type, -- cgit v1.2.3