[graphite] Add sampler creation
Bug: skia:12845 Change-Id: Iba4fcfe98adf6f0445958322d674ab3dfee87305 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/497280 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
a8ed76ac96
commit
84fecee879
@ -56,6 +56,8 @@ public:
|
||||
// to a draw.
|
||||
size_t requiredUniformBufferAlignment() const { return fRequiredUniformBufferAlignment; }
|
||||
|
||||
bool clampToBorderSupport() const { return fClampToBorderSupport; }
|
||||
|
||||
protected:
|
||||
Caps();
|
||||
|
||||
@ -64,6 +66,8 @@ protected:
|
||||
|
||||
std::unique_ptr<SkSL::ShaderCaps> fShaderCaps;
|
||||
|
||||
bool fClampToBorderSupport = true;
|
||||
|
||||
private:
|
||||
virtual bool onIsTexturable(const TextureInfo&) const = 0;
|
||||
virtual bool onAreColorTypeAndTextureInfoCompatible(SkColorType, const TextureInfo&) const = 0;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "experimental/graphite/src/ContextPriv.h"
|
||||
#include "experimental/graphite/src/Gpu.h"
|
||||
#include "experimental/graphite/src/GraphicsPipeline.h"
|
||||
#include "experimental/graphite/src/Sampler.h"
|
||||
#include "experimental/graphite/src/Texture.h"
|
||||
|
||||
namespace skgpu {
|
||||
@ -74,6 +75,12 @@ sk_sp<Texture> ResourceProvider::findOrCreateTexture(SkISize dimensions, const T
|
||||
return this->createTexture(dimensions, info);
|
||||
}
|
||||
|
||||
sk_sp<Sampler> ResourceProvider::findOrCreateCompatibleSampler(const SkSamplingOptions& smplOptions,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode) {
|
||||
return this->createSampler(smplOptions, xTileMode, yTileMode);
|
||||
}
|
||||
|
||||
sk_sp<Buffer> ResourceProvider::findOrCreateBuffer(size_t size,
|
||||
BufferType type,
|
||||
PrioritizeGpuReads prioritizeGpuReads) {
|
||||
|
@ -12,15 +12,19 @@
|
||||
#include "experimental/graphite/src/GraphicsPipelineDesc.h"
|
||||
#include "experimental/graphite/src/ResourceTypes.h"
|
||||
#include "include/core/SkSize.h"
|
||||
#include "include/core/SkTileMode.h"
|
||||
#include "src/core/SkLRUCache.h"
|
||||
#include "src/gpu/ResourceKey.h"
|
||||
|
||||
struct SkSamplingOptions;
|
||||
|
||||
namespace skgpu {
|
||||
|
||||
class BackendTexture;
|
||||
class Buffer;
|
||||
class Gpu;
|
||||
class GraphicsPipeline;
|
||||
class Sampler;
|
||||
class Texture;
|
||||
class TextureInfo;
|
||||
|
||||
@ -38,6 +42,10 @@ public:
|
||||
|
||||
sk_sp<Buffer> findOrCreateBuffer(size_t size, BufferType type, PrioritizeGpuReads);
|
||||
|
||||
sk_sp<Sampler> findOrCreateCompatibleSampler(const SkSamplingOptions&,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode);
|
||||
|
||||
protected:
|
||||
ResourceProvider(const Gpu* gpu);
|
||||
|
||||
@ -50,6 +58,10 @@ private:
|
||||
virtual sk_sp<Texture> createTexture(SkISize, const TextureInfo&) = 0;
|
||||
virtual sk_sp<Buffer> createBuffer(size_t size, BufferType type, PrioritizeGpuReads) = 0;
|
||||
|
||||
virtual sk_sp<Sampler> createSampler(const SkSamplingOptions&,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode) = 0;
|
||||
|
||||
class GraphicsPipelineCache {
|
||||
public:
|
||||
GraphicsPipelineCache(ResourceProvider* resourceProvider);
|
||||
|
@ -229,6 +229,12 @@ void Caps::initCaps(const id<MTLDevice> device) {
|
||||
} else {
|
||||
fRequiredUniformBufferAlignment = 16;
|
||||
}
|
||||
|
||||
if (@available(macOS 10.12, ios 14.0, *)) {
|
||||
fClampToBorderSupport = (this->isMac() || fFamilyGroup >= 7);
|
||||
} else {
|
||||
fClampToBorderSupport = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Caps::initShaderCaps() {
|
||||
|
@ -42,6 +42,10 @@ private:
|
||||
sk_sp<skgpu::Texture> createTexture(SkISize, const skgpu::TextureInfo&) override;
|
||||
sk_sp<skgpu::Buffer> createBuffer(size_t size, BufferType type, PrioritizeGpuReads) override;
|
||||
|
||||
sk_sp<skgpu::Sampler> createSampler(const SkSamplingOptions&,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode) override;
|
||||
|
||||
SkTHashMap<DepthStencilSettings, sk_cfp<id<MTLDepthStencilState>>> fDepthStencilStates;
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "experimental/graphite/src/mtl/MtlCommandBuffer.h"
|
||||
#include "experimental/graphite/src/mtl/MtlGpu.h"
|
||||
#include "experimental/graphite/src/mtl/MtlGraphicsPipeline.h"
|
||||
#include "experimental/graphite/src/mtl/MtlSampler.h"
|
||||
#include "experimental/graphite/src/mtl/MtlTexture.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
@ -60,6 +61,12 @@ sk_sp<skgpu::Buffer> ResourceProvider::createBuffer(size_t size,
|
||||
return Buffer::Make(this->mtlGpu(), size, type, prioritizeGpuReads);
|
||||
}
|
||||
|
||||
sk_sp<skgpu::Sampler> ResourceProvider::createSampler(const SkSamplingOptions& samplingOptions,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode) {
|
||||
return Sampler::Make(this->mtlGpu(), samplingOptions, xTileMode, yTileMode);
|
||||
}
|
||||
|
||||
namespace {
|
||||
MTLCompareFunction compare_op_to_mtl(CompareOp op) {
|
||||
switch (op) {
|
||||
|
@ -11,19 +11,23 @@
|
||||
#include "experimental/graphite/src/Sampler.h"
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTileMode.h"
|
||||
#include "include/ports/SkCFObject.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
struct SkSamplingOptions;
|
||||
|
||||
namespace skgpu::mtl {
|
||||
|
||||
class Gpu;
|
||||
|
||||
class Sampler : public skgpu::Sampler {
|
||||
public:
|
||||
static sk_cfp<id<MTLSamplerState>> MakeMtlSamplerState(const Gpu*);
|
||||
|
||||
static sk_sp<Sampler> Make(const Gpu*);
|
||||
static sk_sp<Sampler> Make(const Gpu*,
|
||||
const SkSamplingOptions& samplingOptions,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode);
|
||||
|
||||
~Sampler() override {}
|
||||
|
||||
|
@ -7,34 +7,89 @@
|
||||
|
||||
#include "experimental/graphite/src/mtl/MtlSampler.h"
|
||||
|
||||
#include "experimental/graphite/src/mtl/MtlCaps.h"
|
||||
#include "experimental/graphite/src/mtl/MtlGpu.h"
|
||||
#include "include/core/SkSamplingOptions.h"
|
||||
|
||||
namespace skgpu::mtl {
|
||||
|
||||
sk_cfp<id<MTLSamplerState>> Sampler::MakeMtlSamplerState(const Gpu* gpu) {
|
||||
sk_cfp<MTLSamplerDescriptor*> desc([[MTLSamplerDescriptor alloc] init]);
|
||||
|
||||
sk_cfp<id<MTLSamplerState>> sampler([gpu->device() newSamplerStateWithDescriptor:desc.get()]);
|
||||
// TODO: fill in fields
|
||||
#ifdef SK_ENABLE_MTL_DEBUG_INFO
|
||||
// TODO: add label
|
||||
#endif
|
||||
|
||||
return sampler;
|
||||
}
|
||||
|
||||
Sampler::Sampler(const Gpu* gpu,
|
||||
sk_cfp<id<MTLSamplerState>> samplerState)
|
||||
: skgpu::Sampler(gpu)
|
||||
, fSamplerState(std::move(samplerState)) {}
|
||||
|
||||
sk_sp<Sampler> Sampler::Make(const Gpu* gpu) {
|
||||
sk_cfp<id<MTLSamplerState>> samplerState = MakeMtlSamplerState(gpu);
|
||||
if (!samplerState) {
|
||||
static inline MTLSamplerAddressMode tile_mode_to_mtl_sampler_address(SkTileMode tileMode,
|
||||
const Caps& caps) {
|
||||
switch (tileMode) {
|
||||
case SkTileMode::kClamp:
|
||||
return MTLSamplerAddressModeClampToEdge;
|
||||
case SkTileMode::kRepeat:
|
||||
return MTLSamplerAddressModeRepeat;
|
||||
case SkTileMode::kMirror:
|
||||
return MTLSamplerAddressModeMirrorRepeat;
|
||||
case SkTileMode::kDecal:
|
||||
// For this tilemode, we should have checked that clamp-to-border support exists.
|
||||
// If it doesn't we should have fallen back to a shader instead.
|
||||
// TODO: for textures with alpha, we could use ClampToZero if there's no
|
||||
// ClampToBorderColor as they'll clamp to (0,0,0,0).
|
||||
// Unfortunately textures without alpha end up clamping to (0,0,0,1).
|
||||
if (@available(macOS 10.12, iOS 14.0, *)) {
|
||||
SkASSERT(caps.clampToBorderSupport());
|
||||
return MTLSamplerAddressModeClampToBorderColor;
|
||||
} else {
|
||||
SkASSERT(false);
|
||||
return MTLSamplerAddressModeClampToZero;
|
||||
}
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
sk_sp<Sampler> Sampler::Make(const Gpu* gpu,
|
||||
const SkSamplingOptions& samplingOptions,
|
||||
SkTileMode xTileMode,
|
||||
SkTileMode yTileMode) {
|
||||
sk_cfp<MTLSamplerDescriptor*> desc([[MTLSamplerDescriptor alloc] init]);
|
||||
|
||||
MTLSamplerMinMagFilter minMagFilter = [&] {
|
||||
switch (samplingOptions.filter) {
|
||||
case SkFilterMode::kNearest: return MTLSamplerMinMagFilterNearest;
|
||||
case SkFilterMode::kLinear: return MTLSamplerMinMagFilterLinear;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}();
|
||||
|
||||
MTLSamplerMipFilter mipFilter = [&] {
|
||||
switch (samplingOptions.mipmap) {
|
||||
case SkMipmapMode::kNone: return MTLSamplerMipFilterNotMipmapped;
|
||||
case SkMipmapMode::kNearest: return MTLSamplerMipFilterNearest;
|
||||
case SkMipmapMode::kLinear: return MTLSamplerMipFilterLinear;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}();
|
||||
|
||||
auto samplerDesc = [[MTLSamplerDescriptor alloc] init];
|
||||
samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||
samplerDesc.sAddressMode = tile_mode_to_mtl_sampler_address(xTileMode, gpu->mtlCaps());
|
||||
samplerDesc.tAddressMode = tile_mode_to_mtl_sampler_address(yTileMode, gpu->mtlCaps());
|
||||
samplerDesc.magFilter = minMagFilter;
|
||||
samplerDesc.minFilter = minMagFilter;
|
||||
samplerDesc.mipFilter = mipFilter;
|
||||
samplerDesc.lodMinClamp = 0.0f;
|
||||
samplerDesc.lodMaxClamp = FLT_MAX; // default value according to docs.
|
||||
samplerDesc.maxAnisotropy = 1.0f;
|
||||
samplerDesc.normalizedCoordinates = true;
|
||||
if (@available(macOS 10.11, iOS 9.0, *)) {
|
||||
samplerDesc.compareFunction = MTLCompareFunctionNever;
|
||||
}
|
||||
#ifdef SK_ENABLE_MTL_DEBUG_INFO
|
||||
// TODO: add label?
|
||||
#endif
|
||||
|
||||
sk_cfp<id<MTLSamplerState>> sampler([gpu->device() newSamplerStateWithDescriptor:desc.get()]);
|
||||
if (!sampler) {
|
||||
return nullptr;
|
||||
}
|
||||
return sk_sp<Sampler>(new Sampler(gpu,
|
||||
std::move(samplerState)));
|
||||
return sk_sp<Sampler>(new Sampler(gpu, std::move(sampler)));
|
||||
}
|
||||
|
||||
void Sampler::onFreeGpuData() {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "experimental/graphite/src/GraphicsPipeline.h"
|
||||
#include "experimental/graphite/src/Renderer.h"
|
||||
#include "experimental/graphite/src/ResourceProvider.h"
|
||||
#include "experimental/graphite/src/Sampler.h"
|
||||
#include "experimental/graphite/src/Texture.h"
|
||||
#include "experimental/graphite/src/TextureProxy.h"
|
||||
#include "experimental/graphite/src/UniformManager.h"
|
||||
@ -281,6 +282,11 @@ DEF_GRAPHITE_TEST_FOR_CONTEXTS(CommandBufferTest, reporter, context) {
|
||||
sk_sp<Texture> depthStencilTexture =
|
||||
gpu->resourceProvider()->findOrCreateTexture(textureSize, depthStencilInfo);
|
||||
|
||||
// Create Sampler -- for now, just to test creation
|
||||
sk_sp<Sampler> sampler = gpu->resourceProvider()->findOrCreateCompatibleSampler(
|
||||
SkSamplingOptions(SkFilterMode::kLinear), SkTileMode::kClamp, SkTileMode::kDecal);
|
||||
REPORTER_ASSERT(reporter, sampler);
|
||||
|
||||
commandBuffer->beginRenderPass(renderPassDesc, target->refTexture(), nullptr,
|
||||
depthStencilTexture);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user