Add GrMtlTexture classes
Adds support for basic Texture creation. Bug: skia: Change-Id: I9a3f15bef1c88054c19e952e231cad94ad69f296 Reviewed-on: https://skia-review.googlesource.com/30781 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
21c3fb94de
commit
4a081e2475
@ -585,6 +585,8 @@ skia_metal_sources = [
|
|||||||
"$_src/gpu/mtl/GrMtlCaps.mm",
|
"$_src/gpu/mtl/GrMtlCaps.mm",
|
||||||
"$_src/gpu/mtl/GrMtlGpu.h",
|
"$_src/gpu/mtl/GrMtlGpu.h",
|
||||||
"$_src/gpu/mtl/GrMtlGpu.mm",
|
"$_src/gpu/mtl/GrMtlGpu.mm",
|
||||||
|
"$_src/gpu/mtl/GrMtlTexture.mm",
|
||||||
|
"$_src/gpu/mtl/GrMtlTexture.h",
|
||||||
"$_src/gpu/mtl/GrMtlTrampoline.h",
|
"$_src/gpu/mtl/GrMtlTrampoline.h",
|
||||||
"$_src/gpu/mtl/GrMtlTrampoline.mm",
|
"$_src/gpu/mtl/GrMtlTrampoline.mm",
|
||||||
"$_src/gpu/mtl/GrMtlUtil.h",
|
"$_src/gpu/mtl/GrMtlUtil.h",
|
||||||
|
@ -26,9 +26,11 @@ public:
|
|||||||
id<MTLDevice> device, id<MTLCommandQueue> queue);
|
id<MTLDevice> device, id<MTLCommandQueue> queue);
|
||||||
|
|
||||||
~GrMtlGpu() override {}
|
~GrMtlGpu() override {}
|
||||||
|
|
||||||
const GrMtlCaps& mtlCaps() const { return *fMtlCaps.get(); }
|
const GrMtlCaps& mtlCaps() const { return *fMtlCaps.get(); }
|
||||||
|
|
||||||
|
id<MTLDevice> device() const { return fDevice; }
|
||||||
|
|
||||||
bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
|
bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
|
||||||
GrPixelConfig readConfig, DrawPreference*,
|
GrPixelConfig readConfig, DrawPreference*,
|
||||||
ReadPixelTempDrawInfo*) override { return false; }
|
ReadPixelTempDrawInfo*) override { return false; }
|
||||||
@ -72,9 +74,7 @@ private:
|
|||||||
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
|
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
|
||||||
|
|
||||||
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
|
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
|
||||||
const GrMipLevel texels[], int mipLevelCount) override {
|
const GrMipLevel texels[], int mipLevelCount) override;
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
|
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
|
||||||
GrSurfaceOrigin,
|
GrSurfaceOrigin,
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "GrMtlGpu.h"
|
#include "GrMtlGpu.h"
|
||||||
|
|
||||||
|
#include "GrMtlTexture.h"
|
||||||
|
|
||||||
#if !__has_feature(objc_arc)
|
#if !__has_feature(objc_arc)
|
||||||
#error This file must be compiled with Arc. Use -fobjc-arc flag
|
#error This file must be compiled with Arc. Use -fobjc-arc flag
|
||||||
#endif
|
#endif
|
||||||
@ -103,3 +105,42 @@ GrMtlGpu::GrMtlGpu(GrContext* context, const GrContextOptions& options,
|
|||||||
// Unused queue warning fix
|
// Unused queue warning fix
|
||||||
SkDebugf("ptr to queue: %p\n", fQueue);
|
SkDebugf("ptr to queue: %p\n", fQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
|
||||||
|
const GrMipLevel texels[], int mipLevelCount) {
|
||||||
|
int mipLevels = !mipLevelCount ? 1 : mipLevelCount;
|
||||||
|
|
||||||
|
if (!fMtlCaps->isConfigTexturable(desc.fConfig)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
|
||||||
|
if (renderTarget) {
|
||||||
|
// Current we don't have render target support
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_sp<GrMtlTexture> tex;
|
||||||
|
if (renderTarget) {
|
||||||
|
// Enable once we have render target support
|
||||||
|
#if 0
|
||||||
|
tex = GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted,
|
||||||
|
desc, mipLevels);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
tex = GrMtlTexture::CreateNewTexture(this, budgeted, desc, mipLevels);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tex) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mipLevelCount) {
|
||||||
|
// Perform initial data upload here
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.fFlags & kPerformInitialClear_GrSurfaceFlag) {
|
||||||
|
// Do initial clear of the texture
|
||||||
|
}
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
68
src/gpu/mtl/GrMtlTexture.h
Normal file
68
src/gpu/mtl/GrMtlTexture.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GrMtlTexture_DEFINED
|
||||||
|
#define GrMtlTexture_DEFINED
|
||||||
|
|
||||||
|
#include "GrTexture.h"
|
||||||
|
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
|
class GrMtlGpu;
|
||||||
|
|
||||||
|
class GrMtlTexture : public GrTexture {
|
||||||
|
public:
|
||||||
|
static sk_sp<GrMtlTexture> CreateNewTexture(GrMtlGpu*, SkBudgeted budgeted,
|
||||||
|
const GrSurfaceDesc&, int mipLevels);
|
||||||
|
|
||||||
|
static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&,
|
||||||
|
GrWrapOwnership);
|
||||||
|
|
||||||
|
~GrMtlTexture() override;
|
||||||
|
|
||||||
|
id<MTLTexture> mtlTexture() const { return fTexture; }
|
||||||
|
|
||||||
|
GrBackendObject getTextureHandle() const override;
|
||||||
|
|
||||||
|
void textureParamsModified() override {}
|
||||||
|
|
||||||
|
bool reallocForMipmap(GrMtlGpu* gpu, uint32_t mipLevels);
|
||||||
|
|
||||||
|
void setRelease(GrTexture::ReleaseProc proc, GrTexture::ReleaseCtx ctx) override {
|
||||||
|
// Since all MTLResources are inherently ref counted, we can call the Release proc when we
|
||||||
|
// delete the GrMtlTexture without worry of the MTLTexture getting deleted before it is done
|
||||||
|
// on the GPU.
|
||||||
|
fReleaseProc = proc;
|
||||||
|
fReleaseCtx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GrMtlTexture(GrMtlGpu*, const GrSurfaceDesc&);
|
||||||
|
|
||||||
|
GrMtlGpu* getMtlGpu() const;
|
||||||
|
|
||||||
|
void onAbandon() override {
|
||||||
|
fTexture = nil;
|
||||||
|
}
|
||||||
|
void onRelease() override {
|
||||||
|
fTexture = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Wrapped { kWrapped };
|
||||||
|
GrMtlTexture(GrMtlGpu*, SkBudgeted, const GrSurfaceDesc&, id<MTLTexture>, bool isMipMapped);
|
||||||
|
// GrMtlTexture(GrMtlGpu*, Wrapped, const GrSurfaceDesc&, GrMtlImage::Wrapped wrapped);
|
||||||
|
|
||||||
|
id<MTLTexture> fTexture;
|
||||||
|
|
||||||
|
ReleaseProc fReleaseProc = nullptr;
|
||||||
|
ReleaseCtx fReleaseCtx = nullptr;
|
||||||
|
|
||||||
|
typedef GrTexture INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
78
src/gpu/mtl/GrMtlTexture.mm
Normal file
78
src/gpu/mtl/GrMtlTexture.mm
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GrMtlTexture.h"
|
||||||
|
|
||||||
|
#include "GrMtlGpu.h"
|
||||||
|
#include "GrMtlUtil.h"
|
||||||
|
#include "GrTexturePriv.h"
|
||||||
|
|
||||||
|
sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted budgeted,
|
||||||
|
const GrSurfaceDesc& desc, int mipLevels) {
|
||||||
|
MTLPixelFormat format;
|
||||||
|
if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLTextureDescriptor* descriptor = [[MTLTextureDescriptor alloc] init];
|
||||||
|
descriptor.textureType = MTLTextureType2D;
|
||||||
|
descriptor.pixelFormat = format;
|
||||||
|
descriptor.width = desc.fWidth;
|
||||||
|
descriptor.height = desc.fHeight;
|
||||||
|
descriptor.depth = 1;
|
||||||
|
descriptor.mipmapLevelCount = mipLevels;
|
||||||
|
descriptor.sampleCount = 1;
|
||||||
|
descriptor.arrayLength = 1;
|
||||||
|
// descriptor.resourceOptions This looks to be set by setting cpuCacheMode and storageModes
|
||||||
|
descriptor.cpuCacheMode = MTLCPUCacheModeWriteCombined;
|
||||||
|
// Shared is not available on MacOS. Is there a reason to want managed to allow mapping?
|
||||||
|
descriptor.storageMode = MTLStorageModePrivate;
|
||||||
|
|
||||||
|
MTLTextureUsage texUsage = MTLTextureUsageShaderRead;
|
||||||
|
if (GrMTLFormatIsSRGB(format, nullptr)) {
|
||||||
|
texUsage |= MTLTextureUsagePixelFormatView;
|
||||||
|
}
|
||||||
|
descriptor.usage = texUsage;
|
||||||
|
|
||||||
|
id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:descriptor];
|
||||||
|
|
||||||
|
return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, desc, texture, mipLevels > 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method parallels GrTextureProxy::highestFilterMode
|
||||||
|
static inline GrSamplerParams::FilterMode highest_filter_mode(GrPixelConfig config) {
|
||||||
|
if (GrPixelConfigIsSint(config)) {
|
||||||
|
// We only ever want to nearest-neighbor sample signed int textures.
|
||||||
|
return GrSamplerParams::kNone_FilterMode;
|
||||||
|
}
|
||||||
|
return GrSamplerParams::kMipMap_FilterMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
|
||||||
|
SkBudgeted budgeted,
|
||||||
|
const GrSurfaceDesc& desc,
|
||||||
|
id<MTLTexture> texture,
|
||||||
|
bool isMipMapped)
|
||||||
|
: GrSurface(gpu, desc)
|
||||||
|
, INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
|
||||||
|
isMipMapped)
|
||||||
|
, fTexture(texture) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GrMtlTexture::~GrMtlTexture() {
|
||||||
|
SkASSERT(nil == fTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
GrMtlGpu* GrMtlTexture::getMtlGpu() const {
|
||||||
|
SkASSERT(!this->wasDestroyed());
|
||||||
|
return static_cast<GrMtlGpu*>(this->getGpu());
|
||||||
|
}
|
||||||
|
|
||||||
|
GrBackendObject GrMtlTexture::getTextureHandle() const {
|
||||||
|
void* voidTex = (__bridge_retained void*)fTexture;
|
||||||
|
return (GrBackendObject)voidTex;
|
||||||
|
}
|
@ -22,5 +22,10 @@ bool GrPixelConfigToMTLFormat(GrPixelConfig config, MTLPixelFormat* format);
|
|||||||
*/
|
*/
|
||||||
GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format);
|
GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given vulkan texture format is sRGB encoded.
|
||||||
|
* Also provides the non-sRGB version, if there is one.
|
||||||
|
*/
|
||||||
|
bool GrMTLFormatIsSRGB(MTLPixelFormat format, MTLPixelFormat* linearFormat);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,3 +101,23 @@ GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format) {
|
|||||||
return kUnknown_GrPixelConfig;
|
return kUnknown_GrPixelConfig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GrMTLFormatIsSRGB(MTLPixelFormat format, MTLPixelFormat* linearFormat) {
|
||||||
|
MTLPixelFormat linearFmt = format;
|
||||||
|
switch (format) {
|
||||||
|
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||||
|
linearFmt = MTLPixelFormatRGBA8Unorm;
|
||||||
|
break;
|
||||||
|
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||||
|
linearFmt = MTLPixelFormatBGRA8Unorm;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linearFormat) {
|
||||||
|
*linearFormat = linearFmt;
|
||||||
|
}
|
||||||
|
return (linearFmt != format);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user