diff options
author | Timothy Liang <timliang@google.com> | 2018-07-17 13:28:20 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-18 18:17:32 +0000 |
commit | 760dbc4b53499f891a9e2057524956f8381535e3 (patch) | |
tree | 1fd1d7ba614122c5532e985594c202084f635098 /src | |
parent | 8f8bf8880d9d9fe8280fa29304063ecc7207e59f (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.h | 35 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlGpu.mm | 180 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlUtil.h | 5 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlUtil.mm | 4 |
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; |