/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/ganesh/GrSPIRVVaryingHandler.h" #include "include/core/SkString.h" #include "include/private/base/SkAssert.h" #include "src/core/SkSLTypeShared.h" #include "src/gpu/ganesh/GrShaderVar.h" /** Returns the number of locations take up by a given SkSLType. We assume that all scalar values are 32 bits. */ static inline int sksltype_to_location_size(SkSLType type) { // If a new GrSL type is added, this function will need to be updated. static_assert(kSkSLTypeCount == 41); switch(type) { case SkSLType::kVoid: return 0; case SkSLType::kFloat: // fall through case SkSLType::kHalf: return 1; case SkSLType::kFloat2: // fall through case SkSLType::kHalf2: return 1; case SkSLType::kFloat3: case SkSLType::kHalf3: return 1; case SkSLType::kFloat4: case SkSLType::kHalf4: return 1; case SkSLType::kInt2: case SkSLType::kUInt2: case SkSLType::kShort2: case SkSLType::kUShort2: return 1; case SkSLType::kInt3: case SkSLType::kUInt3: case SkSLType::kShort3: case SkSLType::kUShort3: return 1; case SkSLType::kInt4: case SkSLType::kUInt4: case SkSLType::kShort4: case SkSLType::kUShort4: return 1; case SkSLType::kFloat2x2: case SkSLType::kHalf2x2: return 2; case SkSLType::kFloat3x3: case SkSLType::kHalf3x3: return 3; case SkSLType::kFloat4x4: case SkSLType::kHalf4x4: return 4; case SkSLType::kTexture2DSampler: return 0; case SkSLType::kTextureExternalSampler: return 0; case SkSLType::kTexture2DRectSampler: return 0; case SkSLType::kBool: case SkSLType::kBool2: case SkSLType::kBool3: case SkSLType::kBool4: return 1; case SkSLType::kInt: // fall through case SkSLType::kShort: return 1; case SkSLType::kUInt: // fall through case SkSLType::kUShort: return 1; case SkSLType::kTexture2D: return 0; case SkSLType::kSampler: return 0; case SkSLType::kInput: return 0; } SK_ABORT("Unexpected type"); } static void finalize_helper(GrSPIRVVaryingHandler::VarArray& vars) { int locationIndex = 0; for (GrShaderVar& var : vars.items()) { SkString location; location.appendf("location = %d", locationIndex); var.addLayoutQualifier(location.c_str()); int elementSize = sksltype_to_location_size(var.getType()); SkASSERT(elementSize > 0); int numElements = var.isArray() ? var.getArrayCount() : 1; SkASSERT(numElements > 0); locationIndex += elementSize * numElements; } // TODO: determine the layout limits for SPIR-V, and enforce them via asserts here. } void GrSPIRVVaryingHandler::onFinalize() { finalize_helper(fVertexInputs); finalize_helper(fVertexOutputs); finalize_helper(fFragInputs); finalize_helper(fFragOutputs); }