aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Timothy Liang <timliang@google.com>2018-07-17 13:28:20 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-18 18:17:32 +0000
commit760dbc4b53499f891a9e2057524956f8381535e3 (patch)
tree1fd1d7ba614122c5532e985594c202084f635098 /src
parent8f8bf8880d9d9fe8280fa29304063ecc7207e59f (diff)
Reland "implemented metal gpu backend texture upload testing"
This reverts commit a80a012456a95a6996a8901268ec34ed0cc3aecb. Reason for revert: Fix bot failure. Original change's description: > Revert "implemented metal gpu backend texture upload testing" > > This reverts commit 36848f6b30ddaca461c98e13b9976b2c449ca547. > > Reason for revert: Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR failing. > > Original change's description: > > implemented metal gpu backend texture upload testing > > > > Bug: skia: > > Change-Id: Ia3af58a0710f7f9792b37682a3cc45dd14282b71 > > Reviewed-on: https://skia-review.googlesource.com/140248 > > Commit-Queue: Timothy Liang <timliang@google.com> > > Reviewed-by: Greg Daniel <egdaniel@google.com> > > TBR=egdaniel@google.com,ethannicholas@google.com,timliang@google.com > > Change-Id: Idf40fc78b82aec1efbcc64221b6d2bbf63353960 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia: > Reviewed-on: https://skia-review.googlesource.com/141182 > Reviewed-by: Timothy Liang <timliang@google.com> > Commit-Queue: Timothy Liang <timliang@google.com> Bug: skia: Change-Id: Ib8c5b2e0cf9de25c11c14741a32846bcc874d712 Reviewed-on: https://skia-review.googlesource.com/141183 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Timothy Liang <timliang@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/mtl/GrMtlGpu.h35
-rw-r--r--src/gpu/mtl/GrMtlGpu.mm180
-rw-r--r--src/gpu/mtl/GrMtlUtil.h5
-rw-r--r--src/gpu/mtl/GrMtlUtil.mm4
4 files changed, 194 insertions, 30 deletions
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index be922e5fdb..8a68b763eb 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -39,6 +39,23 @@ public:
kSkip_SyncQueue
};
+#ifdef GR_TEST_UTILS
+ GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
+ GrPixelConfig config, bool isRT,
+ GrMipMapped) override;
+
+ bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
+
+ void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;
+
+ GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType,
+ GrSRGBEncoded) override;
+
+ void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
+
+ void testingOnly_flushGpuAndSync() override;
+#endif
+
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect,
@@ -135,21 +152,9 @@ private:
void clearStencil(GrRenderTarget* target, int clearValue) override {}
#if GR_TEST_UTILS
- GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
- GrPixelConfig config, bool isRT,
- GrMipMapped) override {
- return GrBackendTexture();
- }
- bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override { return false; }
- void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override {}
-
- GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType,
- GrSRGBEncoded) override {
- return {};
- }
- void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override {}
-
- void testingOnly_flushGpuAndSync() override {}
+ bool createTestingOnlyMtlTextureInfo(GrPixelConfig config, int w, int h, bool texturable,
+ bool renderable, GrMipMapped mipMapped,
+ const void* srcData, GrMtlTextureInfo* info);
#endif
sk_sp<GrMtlCaps> fMtlCaps;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 41ed23e3a5..0295659b36 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -95,21 +95,6 @@ GrMtlGpu::GrMtlGpu(GrContext* context, const GrContextOptions& options,
fCaps = fMtlCaps;
fCmdBuffer = [fQueue commandBuffer];
-
- MTLTextureDescriptor* txDesc = [[MTLTextureDescriptor alloc] init];
- txDesc.textureType = MTLTextureType3D;
- txDesc.height = 64;
- txDesc.width = 64;
- txDesc.depth = 64;
- txDesc.pixelFormat = MTLPixelFormatRGBA8Unorm;
- txDesc.arrayLength = 1;
- txDesc.mipmapLevelCount = 1;
- id<MTLTexture> testTexture = [fDevice newTextureWithDescriptor:txDesc];
- // To get ride of unused var warning
- int width = [testTexture width];
- SkDebugf("width: %d\n", width);
- // Unused queue warning fix
- SkDebugf("ptr to queue: %p\n", fQueue);
}
void GrMtlGpu::submitCommandBuffer(SyncQueue sync) {
@@ -364,6 +349,171 @@ sk_sp<GrRenderTarget> GrMtlGpu::onWrapBackendTextureAsRenderTarget(
return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, mtlTexture);
}
+#ifdef GR_TEST_UTILS
+bool GrMtlGpu::createTestingOnlyMtlTextureInfo(GrPixelConfig config, int w, int h, bool texturable,
+ bool renderable, GrMipMapped mipMapped,
+ const void* srcData, GrMtlTextureInfo* info) {
+ SkASSERT(texturable || renderable);
+ if (!texturable) {
+ SkASSERT(GrMipMapped::kNo == mipMapped);
+ SkASSERT(!srcData);
+ }
+
+ MTLPixelFormat format;
+ if (!GrPixelConfigToMTLFormat(config, &format)) {
+ return false;
+ }
+ if (texturable && !fMtlCaps->isConfigTexturable(config)) {
+ return false;
+ }
+ if (renderable && !fMtlCaps->isConfigRenderable(config)) {
+ return false;
+ }
+ // Currently we don't support uploading pixel data when mipped.
+ if (srcData && GrMipMapped::kYes == mipMapped) {
+ return false;
+ }
+ if(!check_max_blit_width(w)) {
+ return false;
+ }
+
+ bool mipmapped = mipMapped == GrMipMapped::kYes ? true : false;
+ MTLTextureDescriptor* desc =
+ [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: format
+ width: w
+ height: h
+ mipmapped: mipmapped];
+ desc.cpuCacheMode = MTLCPUCacheModeWriteCombined;
+ desc.storageMode = MTLStorageModePrivate;
+ desc.usage = texturable ? MTLTextureUsageShaderRead : 0;
+ desc.usage |= renderable ? MTLTextureUsageRenderTarget : 0;
+ id<MTLTexture> testTexture = [fDevice newTextureWithDescriptor: desc];
+
+ SkAutoTMalloc<GrColor> srcBuffer;
+ if (!srcData) {
+ srcBuffer.reset(w * h);
+ memset(srcBuffer, 0, w * h * sizeof(GrColor));
+ srcData = srcBuffer;
+ }
+ SkASSERT(srcData);
+
+ desc.storageMode = MTLStorageModeManaged;
+ id<MTLTexture> transferTexture = [fDevice newTextureWithDescriptor: desc];
+ auto colorType = GrPixelConfigToColorType(config);
+ int rowBytes = w * GrColorTypeBytesPerPixel(colorType);
+ MTLOrigin origin = MTLOriginMake(0, 0, 0);
+
+ SkASSERT(testTexture.pixelFormat == transferTexture.pixelFormat);
+ SkASSERT(testTexture.sampleCount == transferTexture.sampleCount);
+
+ id<MTLCommandBuffer> cmdBuffer = [fQueue commandBuffer];
+ id<MTLBlitCommandEncoder> blitCmdEncoder = [cmdBuffer blitCommandEncoder];
+ int currentWidth = w;
+ int currentHeight = h;
+ for (int mipLevel = 0; mipLevel < (int)testTexture.mipmapLevelCount; mipLevel++) {
+ [transferTexture replaceRegion: MTLRegionMake2D(0, 0, currentWidth, currentHeight)
+ mipmapLevel: mipLevel
+ withBytes: srcData
+ bytesPerRow: rowBytes];
+
+ [blitCmdEncoder copyFromTexture: transferTexture
+ sourceSlice: 0
+ sourceLevel: mipLevel
+ sourceOrigin: origin
+ sourceSize: MTLSizeMake(currentWidth, currentHeight, 1)
+ toTexture: testTexture
+ destinationSlice: 0
+ destinationLevel: mipLevel
+ destinationOrigin: origin];
+ currentWidth = SkTMax(1, currentWidth/2);
+ currentHeight = SkTMax(1, currentHeight/2);
+ }
+ [blitCmdEncoder endEncoding];
+ [cmdBuffer commit];
+ [cmdBuffer waitUntilCompleted];
+
+ info->fTexture = GrReleaseId(testTexture);
+ return true;
+}
+
+GrBackendTexture GrMtlGpu::createTestingOnlyBackendTexture(const void* pixels, int w, int h,
+ GrPixelConfig config, bool isRT,
+ GrMipMapped mipMapped) {
+ if (w > this->caps()->maxTextureSize() || h > this->caps()->maxTextureSize()) {
+ return GrBackendTexture();
+ }
+ GrMtlTextureInfo info;
+ if (!this->createTestingOnlyMtlTextureInfo(config, w, h, true, isRT, mipMapped, pixels,
+ &info)) {
+ return {};
+ }
+
+ GrBackendTexture backendTex(w, h, mipMapped, info);
+ backendTex.fConfig = config;
+ return backendTex;
+}
+
+bool GrMtlGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
+ SkASSERT(kMetal_GrBackend == tex.backend());
+
+ GrMtlTextureInfo info;
+ if (!tex.getMtlTextureInfo(&info)) {
+ return false;
+ }
+ id<MTLTexture> mtlTexture = GrGetMTLTexture(info.fTexture,
+ GrWrapOwnership::kBorrow_GrWrapOwnership);
+ if (!mtlTexture) {
+ return false;
+ }
+ return mtlTexture.usage & MTLTextureUsageShaderRead;
+}
+
+void GrMtlGpu::deleteTestingOnlyBackendTexture(const GrBackendTexture& tex) {
+ SkASSERT(kMetal_GrBackend == tex.fBackend);
+
+ GrMtlTextureInfo info;
+ if (tex.getMtlTextureInfo(&info)) {
+ // Adopts the metal texture so that ARC will clean it up.
+ GrGetMTLTexture(info.fTexture, GrWrapOwnership::kAdopt_GrWrapOwnership);
+ }
+}
+
+GrBackendRenderTarget GrMtlGpu::createTestingOnlyBackendRenderTarget(int w, int h, GrColorType ct,
+ GrSRGBEncoded srgbEncoded) {
+ if (w > this->caps()->maxRenderTargetSize() || h > this->caps()->maxRenderTargetSize()) {
+ return GrBackendRenderTarget();
+ }
+ auto config = GrColorTypeToPixelConfig(ct, srgbEncoded);
+ if (kUnknown_GrPixelConfig == config) {
+ return {};
+ }
+ GrMtlTextureInfo info;
+ if (!this->createTestingOnlyMtlTextureInfo(config, w, h, false, true, GrMipMapped::kNo, nullptr,
+ &info)) {
+ return {};
+ }
+
+ GrBackendRenderTarget backendRT(w, h, 1, info);
+ backendRT.fConfig = config;
+ return backendRT;
+}
+
+void GrMtlGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& rt) {
+ SkASSERT(kMetal_GrBackend == rt.fBackend);
+
+ GrMtlTextureInfo info;
+ if (rt.getMtlTextureInfo(&info)) {
+ this->testingOnly_flushGpuAndSync();
+ // Adopts the metal texture so that ARC will clean it up.
+ GrGetMTLTexture(info.fTexture, GrWrapOwnership::kAdopt_GrWrapOwnership);
+ }
+}
+
+void GrMtlGpu::testingOnly_flushGpuAndSync() {
+ this->submitCommandBuffer(kForce_SyncQueue);
+}
+#endif // GR_TEST_UTILS
+
bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
GrColorType dstColorType, void* buffer, size_t rowBytes) {
SkASSERT(surface);
diff --git a/src/gpu/mtl/GrMtlUtil.h b/src/gpu/mtl/GrMtlUtil.h
index a184bfa421..b3a7829531 100644
--- a/src/gpu/mtl/GrMtlUtil.h
+++ b/src/gpu/mtl/GrMtlUtil.h
@@ -35,6 +35,11 @@ id<MTLTexture> GrGetMTLTexture(const void* mtlTexture, GrWrapOwnership);
const void* GrGetPtrFromId(id idObject);
/**
+ * Returns a const void* to whatever the id object is pointing to. Always uses __bridge_retained.
+ */
+const void* GrReleaseId(id idObject);
+
+/**
* Returns a MTLTextureDescriptor which describes the MTLTexture. Useful when creating a duplicate
* MTLTexture without the same storage allocation.
*/
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index b658920191..5a58a259d4 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -126,6 +126,10 @@ const void* GrGetPtrFromId(id idObject) {
return (__bridge const void*)idObject;
}
+const void* GrReleaseId(id idObject) {
+ return (__bridge_retained const void*)idObject;
+}
+
MTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture) {
MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
texDesc.textureType = mtlTexture.textureType;