| /* |
| * Copyright 2021 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef skgpu_graphite_DrawTypes_DEFINED |
| #define skgpu_graphite_DrawTypes_DEFINED |
| |
| #include "include/gpu/graphite/GraphiteTypes.h" |
| |
| #include "include/core/SkSamplingOptions.h" |
| #include "include/core/SkTileMode.h" |
| |
| #include "src/gpu/graphite/ResourceTypes.h" |
| |
| #include <array> |
| |
| namespace skgpu::graphite { |
| |
| class Buffer; |
| |
| enum class CType : unsigned { |
| // Any float/half, vector of floats/half, or matrices of floats/halfs are a tightly |
| // packed array of floats. Similarly, any bool/shorts/ints are a tightly packed array |
| // of int32_t. |
| kDefault, |
| // Can be used with kFloat3x3 or kHalf3x3 |
| kSkMatrix, |
| |
| kLast = kSkMatrix |
| }; |
| |
| /** |
| * Geometric primitives used for drawing. |
| */ |
| enum class PrimitiveType : uint8_t { |
| kTriangles, |
| kTriangleStrip, |
| kPoints, |
| }; |
| |
| /** |
| * Types used to describe format of vertices in buffers. |
| */ |
| enum class VertexAttribType : uint8_t { |
| kFloat = 0, |
| kFloat2, |
| kFloat3, |
| kFloat4, |
| kHalf, |
| kHalf2, |
| kHalf4, |
| |
| kInt2, // vector of 2 32-bit ints |
| kInt3, // vector of 3 32-bit ints |
| kInt4, // vector of 4 32-bit ints |
| |
| kByte, // signed byte |
| kByte2, // vector of 2 8-bit signed bytes |
| kByte4, // vector of 4 8-bit signed bytes |
| kUByte, // unsigned byte |
| kUByte2, // vector of 2 8-bit unsigned bytes |
| kUByte4, // vector of 4 8-bit unsigned bytes |
| |
| kUByte_norm, // unsigned byte, e.g. coverage, 0 -> 0.0f, 255 -> 1.0f. |
| kUByte4_norm, // vector of 4 unsigned bytes, e.g. colors, 0 -> 0.0f, 255 -> 1.0f. |
| |
| kShort2, // vector of 2 16-bit shorts. |
| kShort4, // vector of 4 16-bit shorts. |
| |
| kUShort2, // vector of 2 unsigned shorts. 0 -> 0, 65535 -> 65535. |
| kUShort2_norm, // vector of 2 unsigned shorts. 0 -> 0.0f, 65535 -> 1.0f. |
| |
| kInt, |
| kUInt, |
| |
| kUShort_norm, // unsigned short, e.g. depth, 0 -> 0.0f, 65535 -> 1.0f. |
| |
| kUShort4_norm, // vector of 4 unsigned shorts. 0 -> 0.0f, 65535 -> 1.0f. |
| |
| kLast = kUShort4_norm |
| }; |
| static const int kVertexAttribTypeCount = (int)(VertexAttribType::kLast) + 1; |
| |
| |
| /** |
| * Returns the size of the attrib type in bytes. |
| */ |
| static constexpr inline size_t VertexAttribTypeSize(VertexAttribType type) { |
| switch (type) { |
| case VertexAttribType::kFloat: |
| return sizeof(float); |
| case VertexAttribType::kFloat2: |
| return 2 * sizeof(float); |
| case VertexAttribType::kFloat3: |
| return 3 * sizeof(float); |
| case VertexAttribType::kFloat4: |
| return 4 * sizeof(float); |
| case VertexAttribType::kHalf: |
| return sizeof(uint16_t); |
| case VertexAttribType::kHalf2: |
| return 2 * sizeof(uint16_t); |
| case VertexAttribType::kHalf4: |
| return 4 * sizeof(uint16_t); |
| case VertexAttribType::kInt2: |
| return 2 * sizeof(int32_t); |
| case VertexAttribType::kInt3: |
| return 3 * sizeof(int32_t); |
| case VertexAttribType::kInt4: |
| return 4 * sizeof(int32_t); |
| case VertexAttribType::kByte: |
| return 1 * sizeof(char); |
| case VertexAttribType::kByte2: |
| return 2 * sizeof(char); |
| case VertexAttribType::kByte4: |
| return 4 * sizeof(char); |
| case VertexAttribType::kUByte: |
| return 1 * sizeof(char); |
| case VertexAttribType::kUByte2: |
| return 2 * sizeof(char); |
| case VertexAttribType::kUByte4: |
| return 4 * sizeof(char); |
| case VertexAttribType::kUByte_norm: |
| return 1 * sizeof(char); |
| case VertexAttribType::kUByte4_norm: |
| return 4 * sizeof(char); |
| case VertexAttribType::kShort2: |
| return 2 * sizeof(int16_t); |
| case VertexAttribType::kShort4: |
| return 4 * sizeof(int16_t); |
| case VertexAttribType::kUShort2: [[fallthrough]]; |
| case VertexAttribType::kUShort2_norm: |
| return 2 * sizeof(uint16_t); |
| case VertexAttribType::kInt: |
| return sizeof(int32_t); |
| case VertexAttribType::kUInt: |
| return sizeof(uint32_t); |
| case VertexAttribType::kUShort_norm: |
| return sizeof(uint16_t); |
| case VertexAttribType::kUShort4_norm: |
| return 4 * sizeof(uint16_t); |
| } |
| SkUNREACHABLE; |
| } |
| |
| /** |
| * Struct used to describe how a Texture/TextureProxy/TextureProxyView is sampled. |
| */ |
| struct SamplerDesc { |
| SkSamplingOptions fSamplingOptions; |
| SkTileMode fTileModes[2]; |
| |
| bool operator==(const SamplerDesc& o) const { |
| return fSamplingOptions == o.fSamplingOptions && |
| fTileModes[0] == o.fTileModes[0] && |
| fTileModes[1] == o.fTileModes[1]; |
| } |
| bool operator!=(const SamplerDesc& o) const { |
| return !(*this == o); |
| } |
| |
| uint32_t asKey() const { |
| static_assert(kSkTileModeCount <= 4 && kSkFilterModeCount <= 2); |
| // Cubic sampling is handled in a shader, with the actual texture sampled by with NN, |
| // but that is what a cubic SkSamplingOptions is set to if you ignore 'cubic', which let's |
| // us simplify how we construct SamplerDec's from the options passed to high-level draws. |
| SkASSERT(!fSamplingOptions.useCubic || (fSamplingOptions.filter == SkFilterMode::kNearest && |
| fSamplingOptions.mipmap == SkMipmapMode::kNone)); |
| // TODO: Add support for anisotropic filtering |
| return (static_cast<int>(fTileModes[0]) << 0) | |
| (static_cast<int>(fTileModes[1]) << 2) | |
| (static_cast<int>(fSamplingOptions.filter) << 4) | |
| (static_cast<int>(fSamplingOptions.mipmap) << 5); |
| } |
| }; |
| |
| enum class UniformSlot { |
| // TODO: Want this? |
| // Meant for uniforms that change rarely to never over the course of a render pass |
| // kStatic, |
| // Meant for uniforms that are defined and used by the RenderStep portion of the pipeline shader |
| kRenderStep, |
| // Meant for uniforms that are defined and used by the paint parameters (ie SkPaint subset) |
| kPaint, |
| }; |
| |
| /* |
| * Depth and stencil settings |
| */ |
| enum class CompareOp : uint8_t { |
| kAlways, |
| kNever, |
| kGreater, |
| kGEqual, |
| kLess, |
| kLEqual, |
| kEqual, |
| kNotEqual |
| }; |
| static constexpr int kCompareOpCount = 1 + (int)CompareOp::kNotEqual; |
| |
| enum class StencilOp : uint8_t { |
| kKeep, |
| kZero, |
| kReplace, // Replace stencil value with reference (only the bits enabled in fWriteMask). |
| kInvert, |
| kIncWrap, |
| kDecWrap, |
| // NOTE: clamping occurs before the write mask. So if the MSB is zero and masked out, stencil |
| // values will still wrap when using clamping ops. |
| kIncClamp, |
| kDecClamp |
| }; |
| static constexpr int kStencilOpCount = 1 + (int)StencilOp::kDecClamp; |
| |
| struct DepthStencilSettings { |
| // Per-face settings for stencil |
| struct Face { |
| constexpr Face() = default; |
| constexpr Face(StencilOp stencilFail, |
| StencilOp depthFail, |
| StencilOp dsPass, |
| CompareOp compare, |
| uint32_t readMask, |
| uint32_t writeMask) |
| : fStencilFailOp(stencilFail) |
| , fDepthFailOp(depthFail) |
| , fDepthStencilPassOp(dsPass) |
| , fCompareOp(compare) |
| , fReadMask(readMask) |
| , fWriteMask(writeMask) {} |
| |
| StencilOp fStencilFailOp = StencilOp::kKeep; |
| StencilOp fDepthFailOp = StencilOp::kKeep; |
| StencilOp fDepthStencilPassOp = StencilOp::kKeep; |
| CompareOp fCompareOp = CompareOp::kAlways; |
| uint32_t fReadMask = 0xffffffff; |
| uint32_t fWriteMask = 0xffffffff; |
| |
| constexpr bool operator==(const Face& that) const { |
| return this->fStencilFailOp == that.fStencilFailOp && |
| this->fDepthFailOp == that.fDepthFailOp && |
| this->fDepthStencilPassOp == that.fDepthStencilPassOp && |
| this->fCompareOp == that.fCompareOp && |
| this->fReadMask == that.fReadMask && |
| this->fWriteMask == that.fWriteMask; |
| } |
| }; |
| |
| constexpr DepthStencilSettings() = default; |
| constexpr DepthStencilSettings(Face front, |
| Face back, |
| uint32_t stencilRef, |
| bool stencilTest, |
| CompareOp depthCompare, |
| bool depthTest, |
| bool depthWrite) |
| : fFrontStencil(front) |
| , fBackStencil(back) |
| , fStencilReferenceValue(stencilRef) |
| , fDepthCompareOp(depthCompare) |
| , fStencilTestEnabled(stencilTest) |
| , fDepthTestEnabled(depthTest) |
| , fDepthWriteEnabled(depthWrite) {} |
| |
| constexpr bool operator==(const DepthStencilSettings& that) const { |
| return this->fFrontStencil == that.fFrontStencil && |
| this->fBackStencil == that.fBackStencil && |
| this->fStencilReferenceValue == that.fStencilReferenceValue && |
| this->fDepthCompareOp == that.fDepthCompareOp && |
| this->fStencilTestEnabled == that.fStencilTestEnabled && |
| this->fDepthTestEnabled == that.fDepthTestEnabled && |
| this->fDepthWriteEnabled == that.fDepthWriteEnabled; |
| } |
| |
| Face fFrontStencil; |
| Face fBackStencil; |
| uint32_t fStencilReferenceValue = 0; |
| CompareOp fDepthCompareOp = CompareOp::kAlways; |
| bool fStencilTestEnabled = false; |
| bool fDepthTestEnabled = false; |
| bool fDepthWriteEnabled = false; |
| }; |
| |
| }; // namespace skgpu::graphite |
| |
| #endif // skgpu_graphite_DrawTypes_DEFINED |