#ifndef skgpu_graphite_ResourceTypes_DEFINED
#define skgpu_graphite_ResourceTypes_DEFINED
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSpan.h"
#include "include/core/SkTileMode.h"
#include "include/gpu/graphite/GraphiteTypes.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkEnumBitMask.h"
#include "src/base/SkMathPriv.h"
namespace skgpu::graphite {
class Buffer;
SK_MAKE_BITMASK_OPS(DepthStencilFlags)
enum class LoadOp : uint8_t {
kLoad,
kClear,
kDiscard,
kLast = kDiscard
};
inline static constexpr int kLoadOpCount = (int)(LoadOp::kLast) + 1;
enum class StoreOp : uint8_t {
kStore,
kDiscard,
kLast = kDiscard
};
inline static constexpr int kStoreOpCount = (int)(StoreOp::kLast) + 1;
enum class BufferType : int {
kVertex,
kIndex,
kXferCpuToGpu,
kXferGpuToCpu,
kUniform,
kStorage,
kIndirect,
kVertexStorage,
kIndexStorage,
kLast = kIndexStorage,
};
static const int kBufferTypeCount = static_cast<int>(BufferType::kLast) + 1;
enum class Layout {
kInvalid = 0,
kStd140,
kStd430,
kMetal,
};
static constexpr const char* LayoutString(Layout layout) {
switch(layout) {
case Layout::kStd140: return "std140";
case Layout::kStd430: return "std430";
case Layout::kMetal: return "metal";
case Layout::kInvalid: return "invalid";
}
SkUNREACHABLE;
}
enum class AccessPattern : int {
kGpuOnly,
kHostVisible,
};
enum class ClearBuffer : bool {
kNo = false,
kYes = true,
};
enum class Discardable : bool {
kNo = false,
kYes = true
};
enum class Ownership {
kOwned,
kWrapped,
};
using ResourceType = uint32_t;
enum class Shareable : bool {
kNo = false,
kYes = true,
};
enum class LastRemovedRef {
kUsage,
kCommandBuffer,
kCache,
};
struct BindBufferInfo {
const Buffer* fBuffer = nullptr;
uint32_t fOffset = 0;
uint32_t fSize = 0;
operator bool() const { return SkToBool(fBuffer); }
bool operator==(const BindBufferInfo& o) const {
return fBuffer == o.fBuffer && (!fBuffer || (fOffset == o.fOffset && fSize == o.fSize));
}
bool operator!=(const BindBufferInfo& o) const { return !(*this == o); }
};
struct ImmutableSamplerInfo {
uint32_t fNonFormatYcbcrConversionInfo = 0;
uint64_t fFormat = 0;
};
struct SamplerDesc {
static_assert(kSkTileModeCount <= 4 && kSkFilterModeCount <= 2 && kSkMipmapModeCount <= 4);
SamplerDesc(const SkSamplingOptions& samplingOptions,
const SkTileMode tileModes[2],
const ImmutableSamplerInfo info = {})
: fDesc((static_cast<int>(tileModes[0]) << kTileModeXShift ) |
(static_cast<int>(tileModes[1]) << kTileModeYShift ) |
(static_cast<int>(samplingOptions.filter) << kFilterModeShift ) |
(static_cast<int>(samplingOptions.mipmap) << kMipmapModeShift ) |
(info.fNonFormatYcbcrConversionInfo << kImmutableSamplerInfoShift) )
, fFormat(info.fFormat)
, fExternalFormatMostSignificantBits(info.fFormat >> 32) {
SkASSERT(!samplingOptions.useCubic || (samplingOptions.filter == SkFilterMode::kNearest &&
samplingOptions.mipmap == SkMipmapMode::kNone));
SkASSERT(info.fNonFormatYcbcrConversionInfo >> kMaxNumConversionInfoBits == 0);
}
SamplerDesc() = default;
SamplerDesc(const SamplerDesc&) = default;
bool operator==(const SamplerDesc& o) const {
return o.fDesc == fDesc && o.fFormat == fFormat &&
o.fExternalFormatMostSignificantBits == fExternalFormatMostSignificantBits;
}
bool operator!=(const SamplerDesc& o) const { return !(*this == o); }
SkTileMode tileModeX() const { return static_cast<SkTileMode>((fDesc >> 0) & 0b11); }
SkTileMode tileModeY() const { return static_cast<SkTileMode>((fDesc >> 2) & 0b11); }
uint32_t desc() const { return fDesc; }
uint32_t format() const { return fFormat; }
uint32_t externalFormatMSBs() const { return fExternalFormatMostSignificantBits; }
bool isImmutable() const { return (fDesc >> kImmutableSamplerInfoShift) != 0; }
bool usesExternalFormat() const { return (fDesc >> kImmutableSamplerInfoShift) & 0b1; }
SkSamplingOptions samplingOptions() const {
SkFilterMode filter = static_cast<SkFilterMode>((fDesc >> 4) & 0b01);
SkMipmapMode mipmap = static_cast<SkMipmapMode>((fDesc >> 5) & 0b11);
return SkSamplingOptions(filter, mipmap);
}
SkSpan<const uint32_t> asSpan() const {
return {&fDesc, 1 + this->isImmutable() + this->usesExternalFormat()};
}
static constexpr int kNumTileModeBits = SkNextLog2_portable(int(SkTileMode::kLastTileMode)+1);
static constexpr int kNumFilterModeBits = SkNextLog2_portable(int(SkFilterMode::kLast)+1);
static constexpr int kNumMipmapModeBits = SkNextLog2_portable(int(SkMipmapMode::kLast)+1);
static constexpr int kMaxNumConversionInfoBits =
32 - kNumFilterModeBits - kNumMipmapModeBits - kNumTileModeBits;
static constexpr int kTileModeXShift = 0;
static constexpr int kTileModeYShift = kTileModeXShift + kNumTileModeBits;
static constexpr int kFilterModeShift = kTileModeYShift + kNumTileModeBits;
static constexpr int kMipmapModeShift = kFilterModeShift + kNumFilterModeBits;
static constexpr int kImmutableSamplerInfoShift = kMipmapModeShift + kNumMipmapModeBits;
private:
uint32_t fDesc;
uint32_t fFormat = 0;
uint32_t fExternalFormatMostSignificantBits = 0;
};
};
#endif