From 52e16d984898f18c84de773507da875a7954b922 Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Tue, 10 Apr 2018 09:34:07 -0400 Subject: [PATCH] Update getBackendInfo calls on GrBackendTexture to support VkImageLayout better. The big api level change here is that the getBackendInfo calls now return by value instead of a pointer. These changes are being made in support of Vulkan so that the client can update the VkImageLayout on the GrBackendTexture and have that update get reflected in our internal tracking of the image. This is done by storing a ref counted GrVkImageLayout object on the GrBackendTexture and the GrVkImage. Bug: skia: Change-Id: I8c6158fd3a66eb61fef97ebf09ea5364bca3f1ae Reviewed-on: https://skia-review.googlesource.com/119101 Reviewed-by: Brian Salomon Reviewed-by: Robert Phillips Commit-Queue: Greg Daniel --- gn/gpu.gni | 3 + gn/tests.gni | 1 + include/gpu/GrBackendSurface.h | 46 +++++++-- include/gpu/vk/GrVkTypes.h | 16 +++ include/private/GrVkTypesPriv.h | 49 +++++++++ src/gpu/GrBackendSurface.cpp | 116 +++++++++++++++++---- src/gpu/gl/GrGLCaps.cpp | 6 +- src/gpu/gl/GrGLGpu.cpp | 30 +++--- src/gpu/mock/GrMockCaps.h | 6 +- src/gpu/mock/GrMockGpu.cpp | 27 ++--- src/gpu/vk/GrVkCaps.cpp | 6 +- src/gpu/vk/GrVkGpu.cpp | 56 ++++++++--- src/gpu/vk/GrVkImage.cpp | 2 +- src/gpu/vk/GrVkImage.h | 50 ++++++++-- src/gpu/vk/GrVkImageLayout.h | 32 ++++++ src/gpu/vk/GrVkRenderTarget.cpp | 40 +++++--- src/gpu/vk/GrVkRenderTarget.h | 12 ++- src/gpu/vk/GrVkStencilAttachment.cpp | 6 +- src/gpu/vk/GrVkStencilAttachment.h | 1 + src/gpu/vk/GrVkTexture.cpp | 35 ++++--- src/gpu/vk/GrVkTexture.h | 15 +-- src/gpu/vk/GrVkTextureRenderTarget.cpp | 69 +++++++------ src/gpu/vk/GrVkTextureRenderTarget.h | 10 +- src/gpu/vk/GrVkTypesPriv.cpp | 50 ++++++++++ tests/EGLImageTest.cpp | 14 ++- tests/GrMipMappedTest.cpp | 36 ++++--- tests/ImageTest.cpp | 7 +- tests/VkBackendSurfaceTest.cpp | 133 +++++++++++++++++++++++++ tests/VkWrapTests.cpp | 27 ++--- 29 files changed, 713 insertions(+), 188 deletions(-) create mode 100644 include/private/GrVkTypesPriv.h create mode 100644 src/gpu/vk/GrVkImageLayout.h create mode 100644 src/gpu/vk/GrVkTypesPriv.cpp create mode 100644 tests/VkBackendSurfaceTest.cpp diff --git a/gn/gpu.gni b/gn/gpu.gni index c9fd2f3008..774b2a70d5 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -523,6 +523,7 @@ skia_vk_sources = [ "$_include/gpu/vk/GrVkDefines.h", "$_include/gpu/vk/GrVkInterface.h", "$_include/gpu/vk/GrVkTypes.h", + "$_include/private/GrVkTypesPriv.h", "$_src/gpu/vk/GrVkBackendContext.cpp", "$_src/gpu/vk/GrVkBuffer.cpp", "$_src/gpu/vk/GrVkBuffer.h", @@ -552,6 +553,7 @@ skia_vk_sources = [ "$_src/gpu/vk/GrVkGpuCommandBuffer.h", "$_src/gpu/vk/GrVkImage.cpp", "$_src/gpu/vk/GrVkImage.h", + "$_src/gpu/vk/GrVkImageLayout.h", "$_src/gpu/vk/GrVkImageView.cpp", "$_src/gpu/vk/GrVkImageView.h", "$_src/gpu/vk/GrVkIndexBuffer.cpp", @@ -589,6 +591,7 @@ skia_vk_sources = [ "$_src/gpu/vk/GrVkTextureRenderTarget.h", "$_src/gpu/vk/GrVkTransferBuffer.cpp", "$_src/gpu/vk/GrVkTransferBuffer.h", + "$_src/gpu/vk/GrVkTypesPriv.cpp", "$_src/gpu/vk/GrVkUniformBuffer.cpp", "$_src/gpu/vk/GrVkUniformBuffer.h", "$_src/gpu/vk/GrVkUniformHandler.cpp", diff --git a/gn/tests.gni b/gn/tests.gni index 154e300858..8fc7210aa7 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -274,6 +274,7 @@ tests_sources = [ "$_tests/UnicodeTest.cpp", "$_tests/UtilsTest.cpp", "$_tests/VerticesTest.cpp", + "$_tests/VkBackendSurfaceTest.cpp", "$_tests/VkHeapTests.cpp", "$_tests/VkMakeCopyPipelineTest.cpp", "$_tests/VkUploadPixelsTests.cpp", diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h index f0d716cad0..f0bbab5689 100644 --- a/include/gpu/GrBackendSurface.h +++ b/include/gpu/GrBackendSurface.h @@ -14,6 +14,9 @@ #ifdef SK_VULKAN #include "vk/GrVkTypes.h" +#include "../private/GrVkTypesPriv.h" + +class GrVkImageLayout; #endif #if !SK_SUPPORT_GPU @@ -136,24 +139,33 @@ public: GrMipMapped, const GrMockTextureInfo& mockInfo); + GrBackendTexture(const GrBackendTexture& that); + + ~GrBackendTexture(); + + GrBackendTexture& operator=(const GrBackendTexture& that); + int width() const { return fWidth; } int height() const { return fHeight; } bool hasMipMaps() const { return GrMipMapped::kYes == fMipMapped; } GrBackend backend() const {return fBackend; } - // If the backend API is GL, this returns a pointer to the GrGLTextureInfo struct. Otherwise - // it returns nullptr. - const GrGLTextureInfo* getGLTextureInfo() const; + // If the backend API is GL, copies a snapshot of the GrGLTextureInfo struct into the passed in + // pointer and returns true. Otherwise returns false if the backend API is not GL. + bool getGLTextureInfo(GrGLTextureInfo*) const; #ifdef SK_VULKAN - // If the backend API is Vulkan, this returns a pointer to the GrVkImageInfo struct. Otherwise - // it returns nullptr. - const GrVkImageInfo* getVkImageInfo() const; + // If the backend API is Vulkan, copies a snapshot of the GrGLImageInfo struct into the passed + // in pointer and returns true. This snapshot will set the fImageLayout to the current layout + // state. Otherwise returns false if the backend API is not Vulkan. + bool getVkImageInfo(GrVkImageInfo*) const; + + void setVkImageLayout(VkImageLayout); #endif - // If the backend API is Mock, this returns a pointer to the GrMockTextureInfo struct. Otherwise - // it returns nullptr. - const GrMockTextureInfo* getMockTextureInfo() const; + // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed + // in pointer and returns true. Otherwise returns false if the backend API is not Mock. + bool getMockTextureInfo(GrMockTextureInfo*) const; // Returns true if the backend texture has been initialized. bool isValid() const { return fIsValid; } @@ -182,6 +194,20 @@ private: GrPixelConfig config() const { return fConfig; } +#ifdef SK_VULKAN + // Requires friending of GrVkGpu (done above already) + sk_sp getGrVkImageLayout() const; + + friend class GrVkTexture; + GrBackendTexture(int width, + int height, + const GrVkImageInfo& vkInfo, + sk_sp layout); +#endif + + // Free and release and resources being held by the GrBackendTexture. + void cleanup(); + bool fIsValid; int fWidth; // getGrVkImageLayout() const; + + GrVkImageInfo snapImageInfo() const; + +#if GR_TEST_UTILS + bool operator==(const GrVkBackendSurfaceInfo& that) const; +#endif + +private: + GrVkImageInfo fImageInfo; + GrVkImageLayout* fLayout; +}; + +#endif diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp index 5832fa6e0a..36c26e9cdb 100644 --- a/src/gpu/GrBackendSurface.cpp +++ b/src/gpu/GrBackendSurface.cpp @@ -10,6 +10,7 @@ #include "gl/GrGLUtil.h" #ifdef SK_VULKAN +#include "vk/GrVkImageLayout.h" #include "vk/GrVkTypes.h" #include "vk/GrVkUtil.h" #endif @@ -67,13 +68,21 @@ const GrPixelConfig* GrBackendFormat::getMockFormat() const { GrBackendTexture::GrBackendTexture(int width, int height, const GrVkImageInfo& vkInfo) + : GrBackendTexture(width, height, vkInfo, + sk_sp(new GrVkImageLayout(vkInfo.fImageLayout))) {} + +GrBackendTexture::GrBackendTexture(int width, + int height, + const GrVkImageInfo& vkInfo, + sk_sp layout) : fIsValid(true) , fWidth(width) , fHeight(height) , fConfig(GrVkFormatToPixelConfig(vkInfo.fFormat)) , fMipMapped(GrMipMapped(vkInfo.fLevelCount > 1)) , fBackend(kVulkan_GrBackend) - , fVkInfo(vkInfo) {} + , fVkInfo(vkInfo, layout.release()) { +} #endif #if GR_TEST_UTILS @@ -122,47 +131,118 @@ GrBackendTexture::GrBackendTexture(int width, , fBackend(kMock_GrBackend) , fMockInfo(mockInfo) {} +GrBackendTexture::~GrBackendTexture() { + this->cleanup(); +} + +void GrBackendTexture::cleanup() { #ifdef SK_VULKAN -const GrVkImageInfo* GrBackendTexture::getVkImageInfo() const { if (this->isValid() && kVulkan_GrBackend == fBackend) { - return &fVkInfo; + fVkInfo.cleanup(); + } +#endif +} + +GrBackendTexture::GrBackendTexture(const GrBackendTexture& that) : fIsValid(false) { + *this = that; +} + +GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) { + if (!that.isValid()) { + this->cleanup(); + fIsValid = false; + return *this; + } + fWidth = that.fWidth; + fHeight = that.fHeight; + fConfig = that.fConfig; + fMipMapped = that.fMipMapped; + fBackend = that.fBackend; + + switch (that.fBackend) { + case kOpenGL_GrBackend: + fGLInfo = that.fGLInfo; + break; +#ifdef SK_VULKAN + case kVulkan_GrBackend: + fVkInfo.assign(that.fVkInfo, this->isValid()); + break; +#endif +#ifdef SK_METAL + case kMetal_GrBackend: + break; +#endif + case kMock_GrBackend: + fMockInfo = that.fMockInfo; + break; + default: + SK_ABORT("Unknown GrBackend"); + } + fIsValid = that.fIsValid; + return *this; +} + +#ifdef SK_VULKAN +bool GrBackendTexture::getVkImageInfo(GrVkImageInfo* outInfo) const { + if (this->isValid() && kVulkan_GrBackend == fBackend) { + *outInfo = fVkInfo.snapImageInfo(); + return true; + } + return false; +} + +void GrBackendTexture::setVkImageLayout(VkImageLayout layout) { + if (this->isValid() && kVulkan_GrBackend == fBackend) { + fVkInfo.setImageLayout(layout); + } +} + +sk_sp GrBackendTexture::getGrVkImageLayout() const { + if (this->isValid() && kVulkan_GrBackend == fBackend) { + return fVkInfo.getGrVkImageLayout(); } return nullptr; } #endif -const GrGLTextureInfo* GrBackendTexture::getGLTextureInfo() const { +bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const { if (this->isValid() && kOpenGL_GrBackend == fBackend) { - return &fGLInfo; + *outInfo = fGLInfo; + return true; } - return nullptr; + return false; } -const GrMockTextureInfo* GrBackendTexture::getMockTextureInfo() const { +bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const { if (this->isValid() && kMock_GrBackend == fBackend) { - return &fMockInfo; + *outInfo = fMockInfo; + return true; } - return nullptr; + return false; } GrBackendFormat GrBackendTexture::format() const { + if (!this->isValid()) { + return GrBackendFormat(); + } + switch (this->backend()) { #ifdef SK_VULKAN case kVulkan_GrBackend: { - const GrVkImageInfo* vkInfo = this->getVkImageInfo(); - SkASSERT(vkInfo); - return GrBackendFormat::MakeVk(vkInfo->fFormat); + GrVkImageInfo vkInfo; + SkAssertResult(this->getVkImageInfo(&vkInfo)); + return GrBackendFormat::MakeVk(vkInfo.fFormat); } #endif case kOpenGL_GrBackend: { - const GrGLTextureInfo* glInfo = this->getGLTextureInfo(); - SkASSERT(glInfo); - return GrBackendFormat::MakeGL(glInfo->fFormat, glInfo->fTarget); + GrGLTextureInfo glInfo; + SkAssertResult(this->getGLTextureInfo(&glInfo)); + return GrBackendFormat::MakeGL(glInfo.fFormat, glInfo.fTarget); } case kMock_GrBackend: { - const GrMockTextureInfo* mockInfo = this->getMockTextureInfo(); - SkASSERT(mockInfo); - return GrBackendFormat::MakeMock(mockInfo->fConfig); + GrMockTextureInfo mockInfo; + SkAssertResult(this->getMockTextureInfo(&mockInfo)); + return GrBackendFormat::MakeMock(mockInfo.fConfig); } default: return GrBackendFormat(); diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 421ca25bbd..990a15d88f 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -2669,11 +2669,11 @@ bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* confi bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct, GrPixelConfig* config) const { - const GrGLTextureInfo* texInfo = tex.getGLTextureInfo(); - if (!texInfo) { + GrGLTextureInfo texInfo; + if (!tex.getGLTextureInfo(&texInfo)) { return false; } - return validate_sized_format(texInfo->fFormat, ct, config, fStandard); + return validate_sized_format(texInfo.fFormat, ct, config, fStandard); } bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct, diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 08bca6dcc8..c9cd494233 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -497,12 +497,12 @@ void GrGLGpu::onResetContext(uint32_t resetBits) { static bool check_backend_texture(const GrBackendTexture& backendTex, const GrGLCaps& caps, GrGLTexture::IDDesc* idDesc) { - const GrGLTextureInfo* info = backendTex.getGLTextureInfo(); - if (!info || !info->fID) { + GrGLTextureInfo info; + if (!backendTex.getGLTextureInfo(&info) || !info.fID) { return false; } - idDesc->fInfo = *info; + idDesc->fInfo = info; if (GR_GL_TEXTURE_EXTERNAL == idDesc->fInfo.fTarget) { if (!caps.shaderCaps()->externalTextureSupport()) { @@ -618,16 +618,13 @@ sk_sp GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTa sk_sp GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex, int sampleCnt) { - const GrGLTextureInfo* info = tex.getGLTextureInfo(); - if (!info || !info->fID) { + GrGLTextureInfo info; + if (!tex.getGLTextureInfo(&info) || !info.fID) { return nullptr; } - GrGLTextureInfo texInfo; - texInfo = *info; - - if (GR_GL_TEXTURE_RECTANGLE != texInfo.fTarget && - GR_GL_TEXTURE_2D != texInfo.fTarget) { + if (GR_GL_TEXTURE_RECTANGLE != info.fTarget && + GR_GL_TEXTURE_2D != info.fTarget) { // Only texture rectangle and texture 2d are supported. We do not check whether texture // rectangle is supported by Skia - if the caller provided us with a texture rectangle, // we assume the necessary support exists. @@ -642,7 +639,7 @@ sk_sp GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBacken surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config()); GrGLRenderTarget::IDDesc rtIDDesc; - if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) { + if (!this->createRenderTargetObjects(surfDesc, info, &rtIDDesc)) { return nullptr; } return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0); @@ -4413,13 +4410,13 @@ GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(const void* pixels, in bool GrGLGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { SkASSERT(kOpenGL_GrBackend == tex.backend()); - const GrGLTextureInfo* info = tex.getGLTextureInfo(); - if (!info) { + GrGLTextureInfo info; + if (!tex.getGLTextureInfo(&info)) { return false; } GrGLboolean result; - GL_CALL_RET(result, IsTexture(info->fID)); + GL_CALL_RET(result, IsTexture(info.fID)); return (GR_GL_TRUE == result); } @@ -4427,8 +4424,9 @@ bool GrGLGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { void GrGLGpu::deleteTestingOnlyBackendTexture(const GrBackendTexture& tex) { SkASSERT(kOpenGL_GrBackend == tex.backend()); - if (const auto* info = tex.getGLTextureInfo()) { - GL_CALL(DeleteTextures(1, &info->fID)); + GrGLTextureInfo info; + if (tex.getGLTextureInfo(&info)) { + GL_CALL(DeleteTextures(1, &info.fID)); } } diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h index 27d295ebd5..65dd766d8d 100644 --- a/src/gpu/mock/GrMockCaps.h +++ b/src/gpu/mock/GrMockCaps.h @@ -77,12 +77,12 @@ public: bool validateBackendTexture(const GrBackendTexture& tex, SkColorType, GrPixelConfig* config) const override { - const GrMockTextureInfo* texInfo = tex.getMockTextureInfo(); - if (!texInfo) { + GrMockTextureInfo texInfo; + if (!tex.getMockTextureInfo(&texInfo)) { return false; } - *config = texInfo->fConfig; + *config = texInfo.fConfig; return true; } diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp index a677d63bba..060d7bd261 100644 --- a/src/gpu/mock/GrMockGpu.cpp +++ b/src/gpu/mock/GrMockGpu.cpp @@ -95,8 +95,9 @@ sk_sp GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex, GrSurfaceDesc desc; desc.fWidth = tex.width(); desc.fHeight = tex.height(); - SkASSERT(tex.getMockTextureInfo()); - GrMockTextureInfo info = *tex.getMockTextureInfo(); + + GrMockTextureInfo info; + SkAssertResult(tex.getMockTextureInfo(&info)); desc.fConfig = info.fConfig; GrMipMapsStatus mipMapsStatus = tex.hasMipMaps() ? GrMipMapsStatus::kValid @@ -113,8 +114,9 @@ sk_sp GrMockGpu::onWrapRenderableBackendTexture(const GrBackendTextur desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = tex.width(); desc.fHeight = tex.height(); - SkASSERT(tex.getMockTextureInfo()); - GrMockTextureInfo texInfo = *tex.getMockTextureInfo(); + + GrMockTextureInfo texInfo; + SkAssertResult(tex.getMockTextureInfo(&texInfo)); desc.fConfig = texInfo.fConfig; GrMipMapsStatus mipMapsStatus = @@ -148,8 +150,9 @@ sk_sp GrMockGpu::onWrapBackendTextureAsRenderTarget(const GrBack desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = tex.width(); desc.fHeight = tex.height(); - SkASSERT(tex.getMockTextureInfo()); - const GrMockTextureInfo texInfo = *tex.getMockTextureInfo(); + + GrMockTextureInfo texInfo; + SkAssertResult(tex.getMockTextureInfo(&texInfo)); desc.fConfig = texInfo.fConfig; desc.fSampleCnt = sampleCnt; @@ -189,20 +192,20 @@ GrBackendTexture GrMockGpu::createTestingOnlyBackendTexture(const void* pixels, bool GrMockGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { SkASSERT(kMock_GrBackend == tex.backend()); - const GrMockTextureInfo* info = tex.getMockTextureInfo(); - if (!info) { + GrMockTextureInfo info; + if (!tex.getMockTextureInfo(&info)) { return false; } - return fOutstandingTestingOnlyTextureIDs.contains(info->fID); + return fOutstandingTestingOnlyTextureIDs.contains(info.fID); } void GrMockGpu::deleteTestingOnlyBackendTexture(const GrBackendTexture& tex) { SkASSERT(kMock_GrBackend == tex.backend()); - const GrMockTextureInfo* info = tex.getMockTextureInfo(); - if (info) { - fOutstandingTestingOnlyTextureIDs.remove(info->fID); + GrMockTextureInfo info; + if (tex.getMockTextureInfo(&info)) { + fOutstandingTestingOnlyTextureIDs.remove(info.fID); } } diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index e4ff3ef09a..5747cc04c3 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -500,12 +500,12 @@ bool validate_image_info(VkFormat format, SkColorType ct, GrPixelConfig* config) bool GrVkCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct, GrPixelConfig* config) const { - const GrVkImageInfo* imageInfo = tex.getVkImageInfo(); - if (!imageInfo) { + GrVkImageInfo imageInfo; + if (!tex.getVkImageInfo(&imageInfo)) { return false; } - return validate_image_info(imageInfo->fFormat, ct, config); + return validate_image_info(imageInfo.fFormat, ct, config); } bool GrVkCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct, diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index af9505821a..855232badd 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -864,16 +864,16 @@ bool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src, static bool check_backend_texture(const GrBackendTexture& backendTex, GrPixelConfig config) { - const GrVkImageInfo* info = backendTex.getVkImageInfo(); - if (!info) { + GrVkImageInfo info; + if (!backendTex.getVkImageInfo(&info)) { return false; } - if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc.fMemory) { + if (VK_NULL_HANDLE == info.fImage || VK_NULL_HANDLE == info.fAlloc.fMemory) { return false; } - SkASSERT(GrVkFormatPixelConfigPairIsValid(info->fFormat, config)); + SkASSERT(GrVkFormatPixelConfigPairIsValid(info.fFormat, config)); return true; } @@ -890,7 +890,13 @@ sk_sp GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTe surfDesc.fConfig = backendTex.config(); surfDesc.fSampleCnt = 1; - return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, backendTex.getVkImageInfo()); + GrVkImageInfo imageInfo; + if (!backendTex.getVkImageInfo(&imageInfo)) { + return nullptr; + } + sk_sp layout = backendTex.getGrVkImageLayout(); + SkASSERT(layout); + return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, imageInfo, std::move(layout)); } sk_sp GrVkGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex, @@ -907,8 +913,15 @@ sk_sp GrVkGpu::onWrapRenderableBackendTexture(const GrBackendTexture& surfDesc.fConfig = backendTex.config(); surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); + GrVkImageInfo imageInfo; + if (!backendTex.getVkImageInfo(&imageInfo)) { + return nullptr; + } + sk_sp layout = backendTex.getGrVkImageLayout(); + SkASSERT(layout); + return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership, - backendTex.getVkImageInfo()); + imageInfo, std::move(layout)); } sk_sp GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT){ @@ -935,7 +948,10 @@ sk_sp GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTa desc.fConfig = backendRT.config(); desc.fSampleCnt = 1; - sk_sp tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info); + sk_sp layout(new GrVkImageLayout(info->fImageLayout)); + + sk_sp tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, *info, + std::move(layout)); // We don't allow the client to supply a premade stencil buffer. We always create one if needed. SkASSERT(!backendRT.stencilBits()); @@ -949,11 +965,11 @@ sk_sp GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTa sk_sp GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex, int sampleCnt) { - const GrVkImageInfo* info = tex.getVkImageInfo(); - if (!info) { + GrVkImageInfo imageInfo; + if (!tex.getVkImageInfo(&imageInfo)) { return nullptr; } - if (VK_NULL_HANDLE == info->fImage) { + if (VK_NULL_HANDLE == imageInfo.fImage) { return nullptr; } @@ -967,7 +983,11 @@ sk_sp GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBacken return nullptr; } - sk_sp tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info); + sk_sp layout = tex.getGrVkImageLayout(); + SkASSERT(layout); + + sk_sp tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, imageInfo, + std::move(layout)); return tgt; } @@ -1499,13 +1519,16 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(const void* srcData, i bool GrVkGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { SkASSERT(kVulkan_GrBackend == tex.fBackend); - const GrVkImageInfo* backend = tex.getVkImageInfo(); + GrVkImageInfo backend; + if (!tex.getVkImageInfo(&backend)) { + return false; + } - if (backend && backend->fImage && backend->fAlloc.fMemory) { + if (backend.fImage && backend.fAlloc.fMemory) { VkMemoryRequirements req; memset(&req, 0, sizeof(req)); GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, - backend->fImage, + backend.fImage, &req)); // TODO: find a better check // This will probably fail with a different driver @@ -1518,10 +1541,11 @@ bool GrVkGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { void GrVkGpu::deleteTestingOnlyBackendTexture(const GrBackendTexture& tex) { SkASSERT(kVulkan_GrBackend == tex.fBackend); - if (const auto* info = tex.getVkImageInfo()) { + GrVkImageInfo info; + if (tex.getVkImageInfo(&info)) { // something in the command buffer may still be using this, so force submit this->submitCommandBuffer(kForce_SyncQueue); - GrVkImage::DestroyImageInfo(this, const_cast(info)); + GrVkImage::DestroyImageInfo(this, const_cast(&info)); } } diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp index 5e0ffe240f..556a088fb1 100644 --- a/src/gpu/vk/GrVkImage.cpp +++ b/src/gpu/vk/GrVkImage.cpp @@ -61,7 +61,7 @@ void GrVkImage::setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout, gpu->addImageMemoryBarrier(srcStageMask, dstStageMask, byRegion, &imageMemoryBarrier); - fInfo.fImageLayout = newLayout; + this->updateImageLayout(newLayout); } bool GrVkImage::InitImageInfo(const GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo* info) { diff --git a/src/gpu/vk/GrVkImage.h b/src/gpu/vk/GrVkImage.h index e43c2f2672..9e99743fe7 100644 --- a/src/gpu/vk/GrVkImage.h +++ b/src/gpu/vk/GrVkImage.h @@ -11,6 +11,7 @@ #include "GrVkResource.h" #include "GrTypesPriv.h" +#include "GrVkImageLayout.h" #include "SkTypes.h" #include "vk/GrVkDefines.h" @@ -23,9 +24,13 @@ private: class Resource; public: - GrVkImage(const GrVkImageInfo& info, GrBackendObjectOwnership ownership) - : fInfo(info) - , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) { + GrVkImage(const GrVkImageInfo& info, sk_sp layout, + GrBackendObjectOwnership ownership) + : fInfo(info) + , fLayout(std::move(layout)) + , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) { + SkASSERT(fLayout->getImageLayout() == fInfo.fImageLayout); + fTempLayoutTracker = fLayout->getImageLayout(); if (fIsBorrowed) { fResource = new BorrowedResource(info.fImage, info.fAlloc, info.fImageTiling); } else { @@ -44,7 +49,28 @@ public: } bool isBorrowed() const { return fIsBorrowed; } - VkImageLayout currentLayout() const { return fInfo.fImageLayout; } + sk_sp grVkImageLayout() const { return fLayout; } + + VkImageLayout currentLayout() const { + // This check and set is temporary since clients can still change the layout using + // the old GrBackendObject call and we need a way to respect those changes. This only works + // if the client isn't using GrBackendObjects and GrBackendTextures to update the layout + // at the same time. This check and set should all be made atomic but the plan is to remove + // the use of fInfo.fImageLayout so ignoring this issue for now. + // TODO: Delete all this ugliness as soon as we get rid of GrBackendObject getters. + if (fInfo.fImageLayout != fLayout->getImageLayout()) { + if (fLayout->getImageLayout() == fTempLayoutTracker) { + fLayout->setImageLayout(fInfo.fImageLayout); + } else { + SkASSERT(fInfo.fImageLayout == fTempLayoutTracker); + *const_cast(&fInfo.fImageLayout) = fLayout->getImageLayout(); + } + *const_cast(&fTempLayoutTracker) = fLayout->getImageLayout(); + } + SkASSERT(fInfo.fImageLayout == fTempLayoutTracker && + fLayout->getImageLayout() == fTempLayoutTracker); + return fLayout->getImageLayout(); + } void setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout, @@ -55,7 +81,11 @@ public: // This simply updates our tracking of the image layout and does not actually do any gpu work. // This is only used for mip map generation where we are manually changing the layouts as we // blit each layer, and then at the end need to update our tracking. - void updateImageLayout(VkImageLayout newLayout) { fInfo.fImageLayout = newLayout; } + void updateImageLayout(VkImageLayout newLayout) { + fLayout->setImageLayout(newLayout); + fInfo.fImageLayout = newLayout; + fTempLayoutTracker = newLayout; + } struct ImageDesc { VkImageType fImageType; @@ -96,8 +126,14 @@ protected: void setNewResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling); - GrVkImageInfo fInfo; - bool fIsBorrowed; + GrVkImageInfo fInfo; + sk_sp fLayout; + // This is used while we still have GrBackendObjects around that are able to change our image + // layout without using the ref count method. This helps us determine which value has gotten out + // of sync. + // TODO: Delete this when get rid of a GrBackendObject getters + VkImageLayout fTempLayoutTracker; + bool fIsBorrowed; private: class Resource : public GrVkResource { diff --git a/src/gpu/vk/GrVkImageLayout.h b/src/gpu/vk/GrVkImageLayout.h new file mode 100644 index 0000000000..8f21fa8bfb --- /dev/null +++ b/src/gpu/vk/GrVkImageLayout.h @@ -0,0 +1,32 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrVkImageLayout_DEFINED +#define GrVkImageLayout_DEFINED + +#include "SkRefCnt.h" +#include "vk/GrVkTypes.h" + +class GrVkImageLayout : public SkRefCnt { +public: + GrVkImageLayout(VkImageLayout layout) : fLayout(layout) {} + + void setImageLayout(VkImageLayout layout) { + // Defaulting to use std::memory_order_seq_cst + fLayout.store(layout); + } + + VkImageLayout getImageLayout() const { + // Defaulting to use std::memory_order_seq_cst + return fLayout.load(); + } + +private: + std::atomic fLayout; +}; + +#endif diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp index 99b6b7632c..5570c0d3b4 100644 --- a/src/gpu/vk/GrVkRenderTarget.cpp +++ b/src/gpu/vk/GrVkRenderTarget.cpp @@ -26,16 +26,18 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) + , GrVkImage(info, std::move(layout), ownership) // for the moment we only support 1:1 color to stencil , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) - , fMSAAImage(new GrVkImage(msaaInfo, GrBackendObjectOwnership::kOwned)) + , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout), GrBackendObjectOwnership::kOwned)) , fResolveAttachmentView(resolveAttachmentView) , fFramebuffer(nullptr) , fCachedSimpleRenderPass(nullptr) { @@ -49,16 +51,18 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) + , GrVkImage(info, std::move(layout), ownership) // for the moment we only support 1:1 color to stencil , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) - , fMSAAImage(new GrVkImage(msaaInfo, GrBackendObjectOwnership::kOwned)) + , fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout), GrBackendObjectOwnership::kOwned)) , fResolveAttachmentView(resolveAttachmentView) , fFramebuffer(nullptr) , fCachedSimpleRenderPass(nullptr) { @@ -72,10 +76,11 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* colorAttachmentView, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) + , GrVkImage(info, std::move(layout), ownership) , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) , fMSAAImage(nullptr) @@ -92,10 +97,11 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* colorAttachmentView, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) + , GrVkImage(info, std::move(layout), ownership) , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) , fMSAAImage(nullptr) @@ -111,6 +117,7 @@ GrVkRenderTarget::Create(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, GrBackendObjectOwnership ownership) { SkASSERT(1 == info.fLevelCount); VkFormat pixelFormat; @@ -120,6 +127,7 @@ GrVkRenderTarget::Create(GrVkGpu* gpu, // create msaa surface if necessary GrVkImageInfo msInfo; + sk_sp msLayout; const GrVkImageView* resolveAttachmentView = nullptr; if (desc.fSampleCnt > 1) { GrVkImage::ImageDesc msImageDesc; @@ -149,6 +157,7 @@ GrVkRenderTarget::Create(GrVkGpu* gpu, GrVkImage::DestroyImageInfo(gpu, &msInfo); return nullptr; } + msLayout.reset(new GrVkImageLayout(msInfo.fImageLayout)); } else { // Set color attachment image colorImage = info.fImage; @@ -167,10 +176,12 @@ GrVkRenderTarget::Create(GrVkGpu* gpu, GrVkRenderTarget* texRT; if (desc.fSampleCnt > 1) { - texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, msInfo, - colorAttachmentView, resolveAttachmentView, ownership); + texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, std::move(layout), msInfo, + std::move(msLayout), colorAttachmentView, + resolveAttachmentView, ownership); } else { - texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, colorAttachmentView, ownership); + texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, std::move(layout), + colorAttachmentView, ownership); } return texRT; @@ -188,7 +199,8 @@ GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu, return nullptr; } - GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, budgeted, desc, info, + sk_sp layout(new GrVkImageLayout(info.fImageLayout)); + GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, budgeted, desc, info, std::move(layout), GrBackendObjectOwnership::kOwned); if (!rt) { GrVkImage::DestroyImageInfo(gpu, &info); @@ -199,12 +211,12 @@ GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu, sk_sp GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, - const GrVkImageInfo* info) { - SkASSERT(info); - SkASSERT(VK_NULL_HANDLE != info->fImage); + const GrVkImageInfo& info, + sk_sp layout) { + SkASSERT(VK_NULL_HANDLE != info.fImage); return sk_sp( - GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, *info, + GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, info, std::move(layout), GrBackendObjectOwnership::kBorrowed)); } diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h index 02d4add455..64be0b78e4 100644 --- a/src/gpu/vk/GrVkRenderTarget.h +++ b/src/gpu/vk/GrVkRenderTarget.h @@ -35,7 +35,8 @@ public: const GrVkImage::ImageDesc&); static sk_sp MakeWrappedRenderTarget(GrVkGpu*, const GrSurfaceDesc&, - const GrVkImageInfo*); + const GrVkImageInfo&, + sk_sp); ~GrVkRenderTarget() override; @@ -81,7 +82,9 @@ protected: GrVkRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrBackendObjectOwnership); @@ -89,6 +92,7 @@ protected: GrVkRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* colorAttachmentView, GrBackendObjectOwnership); @@ -119,7 +123,9 @@ private: SkBudgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrBackendObjectOwnership); @@ -128,11 +134,13 @@ private: SkBudgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* colorAttachmentView, GrBackendObjectOwnership); static GrVkRenderTarget* Create(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&, - const GrVkImageInfo&, GrBackendObjectOwnership); + const GrVkImageInfo&, sk_sp, + GrBackendObjectOwnership); bool completeStencilAttachment() override; diff --git a/src/gpu/vk/GrVkStencilAttachment.cpp b/src/gpu/vk/GrVkStencilAttachment.cpp index 139c00f3b2..7c5e83e500 100644 --- a/src/gpu/vk/GrVkStencilAttachment.cpp +++ b/src/gpu/vk/GrVkStencilAttachment.cpp @@ -17,9 +17,10 @@ GrVkStencilAttachment::GrVkStencilAttachment(GrVkGpu* gpu, const Format& format, const GrVkImage::ImageDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* stencilView) : GrStencilAttachment(gpu, desc.fWidth, desc.fHeight, format.fStencilBits, desc.fSamples) - , GrVkImage(info, GrBackendObjectOwnership::kOwned) + , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kOwned) , fFormat(format) , fStencilView(stencilView) { this->registerWithCache(SkBudgeted::kYes); @@ -56,8 +57,9 @@ GrVkStencilAttachment* GrVkStencilAttachment::Create(GrVkGpu* gpu, return nullptr; } + sk_sp layout(new GrVkImageLayout(info.fImageLayout)); GrVkStencilAttachment* stencil = new GrVkStencilAttachment(gpu, format, imageDesc, - info, imageView); + info, std::move(layout), imageView); imageView->unref(gpu); return stencil; diff --git a/src/gpu/vk/GrVkStencilAttachment.h b/src/gpu/vk/GrVkStencilAttachment.h index f6bf19af4f..ac70bfb508 100644 --- a/src/gpu/vk/GrVkStencilAttachment.h +++ b/src/gpu/vk/GrVkStencilAttachment.h @@ -45,6 +45,7 @@ private: const Format& format, const GrVkImage::ImageDesc&, const GrVkImageInfo&, + sk_sp layout, const GrVkImageView* stencilView); GrVkGpu* getVkGpu() const; diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp index 109b10638d..0b9862443c 100644 --- a/src/gpu/vk/GrVkTexture.cpp +++ b/src/gpu/vk/GrVkTexture.cpp @@ -27,10 +27,11 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* view, GrMipMapsStatus mipMapsStatus) : GrSurface(gpu, desc) - , GrVkImage(info, GrBackendObjectOwnership::kOwned) + , GrVkImage(info, std::move(layout), GrBackendObjectOwnership::kOwned) , INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig), mipMapsStatus) , fTextureView(view) @@ -43,11 +44,12 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu, Wrapped, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* view, GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) + , GrVkImage(info, std::move(layout), ownership) , INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig), mipMapsStatus) , fTextureView(view) @@ -60,11 +62,12 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu, GrVkTexture::GrVkTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* view, GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) + , GrVkImage(info, layout, ownership) , INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig), mipMapsStatus) , fTextureView(view) @@ -90,33 +93,34 @@ sk_sp GrVkTexture::CreateNewTexture(GrVkGpu* gpu, SkBudgeted budget GrVkImage::DestroyImageInfo(gpu, &info); return nullptr; } + sk_sp layout(new GrVkImageLayout(info.fImageLayout)); - return sk_sp(new GrVkTexture(gpu, budgeted, desc, info, imageView, - mipMapsStatus)); + return sk_sp(new GrVkTexture(gpu, budgeted, desc, info, std::move(layout), + imageView, mipMapsStatus)); } sk_sp GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc, GrWrapOwnership wrapOwnership, - const GrVkImageInfo* info) { - SkASSERT(info); + const GrVkImageInfo& info, + sk_sp layout) { // Wrapped textures require both image and allocation (because they can be mapped) - SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc.fMemory); + SkASSERT(VK_NULL_HANDLE != info.fImage && VK_NULL_HANDLE != info.fAlloc.fMemory); - const GrVkImageView* imageView = GrVkImageView::Create(gpu, info->fImage, info->fFormat, + const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage, info.fFormat, GrVkImageView::kColor_Type, - info->fLevelCount); + info.fLevelCount); if (!imageView) { return nullptr; } - GrMipMapsStatus mipMapsStatus = info->fLevelCount > 1 ? GrMipMapsStatus::kValid - : GrMipMapsStatus::kNotAllocated; + GrMipMapsStatus mipMapsStatus = info.fLevelCount > 1 ? GrMipMapsStatus::kValid + : GrMipMapsStatus::kNotAllocated; GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership ? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned; - return sk_sp(new GrVkTexture(gpu, kWrapped, desc, *info, imageView, - mipMapsStatus, ownership)); + return sk_sp(new GrVkTexture(gpu, kWrapped, desc, info, std::move(layout), + imageView, mipMapsStatus, ownership)); } GrVkTexture::~GrVkTexture() { @@ -162,7 +166,7 @@ GrBackendObject GrVkTexture::getTextureHandle() const { } GrBackendTexture GrVkTexture::getBackendTexture() const { - return GrBackendTexture(this->width(), this->height(), fInfo); + return GrBackendTexture(this->width(), this->height(), fInfo, this->grVkImageLayout()); } GrVkGpu* GrVkTexture::getVkGpu() const { @@ -251,6 +255,7 @@ bool GrVkTexture::reallocForMipmap(GrVkGpu* gpu, uint32_t mipLevels) { this->setNewResource(info.fImage, info.fAlloc, info.fImageTiling); fTextureView = textureView; fInfo = info; + this->updateImageLayout(info.fImageLayout); // SetMaxMipMapLevel stores the max level not the number of levels this->texturePriv().setMaxMipMapLevel(mipLevels-1); diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h index f2fabc887b..e37b53ebbf 100644 --- a/src/gpu/vk/GrVkTexture.h +++ b/src/gpu/vk/GrVkTexture.h @@ -24,7 +24,8 @@ public: GrMipMapsStatus); static sk_sp MakeWrappedTexture(GrVkGpu*, const GrSurfaceDesc&, - GrWrapOwnership, const GrVkImageInfo*); + GrWrapOwnership, const GrVkImageInfo&, + sk_sp); ~GrVkTexture() override; @@ -45,8 +46,8 @@ public: } protected: - GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, const GrVkImageView*, - GrMipMapsStatus, GrBackendObjectOwnership); + GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, sk_sp, + const GrVkImageView*, GrMipMapsStatus, GrBackendObjectOwnership); GrVkGpu* getVkGpu() const; @@ -59,11 +60,11 @@ protected: private: enum Wrapped { kWrapped }; - GrVkTexture(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&, - const GrVkImageInfo&, const GrVkImageView* imageView, + GrVkTexture(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&, const GrVkImageInfo&, + sk_sp layout, const GrVkImageView* imageView, GrMipMapsStatus); - GrVkTexture(GrVkGpu*, Wrapped, const GrSurfaceDesc&, - const GrVkImageInfo&, const GrVkImageView* imageView, GrMipMapsStatus, + GrVkTexture(GrVkGpu*, Wrapped, const GrSurfaceDesc&, const GrVkImageInfo&, + sk_sp layout, const GrVkImageView* imageView, GrMipMapsStatus, GrBackendObjectOwnership); const GrVkImageView* fTextureView; diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp index ee31f2364a..0fde5f9816 100644 --- a/src/gpu/vk/GrVkTextureRenderTarget.cpp +++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp @@ -22,17 +22,20 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) - , GrVkTexture(gpu, desc, info, texView, mipMapsStatus, ownership) - , GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView, - resolveAttachmentView, GrBackendObjectOwnership::kOwned) { + , GrVkImage(info, layout, ownership) + , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership) + , GrVkRenderTarget(gpu, desc, info, layout, msaaInfo, std::move(msaaLayout), + colorAttachmentView, resolveAttachmentView, + GrBackendObjectOwnership::kOwned) { this->registerWithCache(budgeted); } @@ -40,51 +43,57 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageView* colorAttachmentView, GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) - , GrVkTexture(gpu, desc, info, texView, mipMapsStatus, ownership) - , GrVkRenderTarget(gpu, desc, info, colorAttachmentView, GrBackendObjectOwnership::kOwned) { + , GrVkImage(info, layout, ownership) + , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership) + , GrVkRenderTarget(gpu, desc, info, layout, colorAttachmentView, + GrBackendObjectOwnership::kOwned) { this->registerWithCache(budgeted); } GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) - , GrVkTexture(gpu, desc, info, texView, mipMapsStatus, ownership) - , GrVkRenderTarget(gpu, desc, info, msaaInfo, colorAttachmentView, - resolveAttachmentView, ownership) { + , GrVkImage(info, layout, ownership) + , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership) + , GrVkRenderTarget(gpu, desc, info, layout, msaaInfo, std::move(msaaLayout), + colorAttachmentView, resolveAttachmentView, ownership) { this->registerWithCacheWrapped(); } GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageView* colorAttachmentView, GrMipMapsStatus mipMapsStatus, GrBackendObjectOwnership ownership) : GrSurface(gpu, desc) - , GrVkImage(info, ownership) - , GrVkTexture(gpu, desc, info, texView, mipMapsStatus, ownership) - , GrVkRenderTarget(gpu, desc, info, colorAttachmentView, ownership) { + , GrVkImage(info, layout, ownership) + , GrVkTexture(gpu, desc, info, layout, texView, mipMapsStatus, ownership) + , GrVkRenderTarget(gpu, desc, info, layout, colorAttachmentView, ownership) { this->registerWithCacheWrapped(); } sk_sp GrVkTextureRenderTarget::Make(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, GrMipMapsStatus mipMapsStatus, SkBudgeted budgeted, GrBackendObjectOwnership ownership, @@ -105,6 +114,7 @@ sk_sp GrVkTextureRenderTarget::Make(GrVkGpu* gpu, // create msaa surface if necessary GrVkImageInfo msInfo; + sk_sp msLayout; const GrVkImageView* resolveAttachmentView = nullptr; if (desc.fSampleCnt > 1) { GrVkImage::ImageDesc msImageDesc; @@ -137,6 +147,7 @@ sk_sp GrVkTextureRenderTarget::Make(GrVkGpu* gpu, imageView->unref(gpu); return nullptr; } + msLayout.reset(new GrVkImageLayout(msInfo.fImageLayout)); } else { // Set color attachment image colorImage = info.fImage; @@ -158,15 +169,15 @@ sk_sp GrVkTextureRenderTarget::Make(GrVkGpu* gpu, if (!isWrapped) { texRT = sk_sp(new GrVkTextureRenderTarget( gpu, budgeted, desc, - info, imageView, msInfo, - colorAttachmentView, + info, std::move(layout), imageView, msInfo, + std::move(msLayout), colorAttachmentView, resolveAttachmentView, mipMapsStatus, ownership)); } else { texRT = sk_sp(new GrVkTextureRenderTarget( gpu, desc, - info, imageView, msInfo, - colorAttachmentView, + info, std::move(layout), imageView, msInfo, + std::move(msLayout), colorAttachmentView, resolveAttachmentView, mipMapsStatus, ownership)); } @@ -174,13 +185,13 @@ sk_sp GrVkTextureRenderTarget::Make(GrVkGpu* gpu, if (!isWrapped) { texRT = sk_sp(new GrVkTextureRenderTarget( gpu, budgeted, desc, - info, imageView, + info, std::move(layout), imageView, colorAttachmentView, mipMapsStatus, ownership)); } else { texRT = sk_sp(new GrVkTextureRenderTarget( gpu, desc, - info, imageView, + info, std::move(layout), imageView, colorAttachmentView, mipMapsStatus, ownership)); } @@ -201,9 +212,10 @@ GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu, if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) { return nullptr; } + sk_sp layout(new GrVkImageLayout(info.fImageLayout)); - sk_sp trt = Make(gpu, desc, info, mipMapsStatus, budgeted, - GrBackendObjectOwnership::kOwned, false); + sk_sp trt = Make(gpu, desc, info, std::move(layout), mipMapsStatus, + budgeted, GrBackendObjectOwnership::kOwned, false); if (!trt) { GrVkImage::DestroyImageInfo(gpu, &info); } @@ -215,18 +227,19 @@ sk_sp GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, GrWrapOwnership wrapOwnership, - const GrVkImageInfo* info) { - SkASSERT(info); + const GrVkImageInfo& info, + sk_sp layout) { // Wrapped textures require both image and allocation (because they can be mapped) - SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc.fMemory); + SkASSERT(VK_NULL_HANDLE != info.fImage && VK_NULL_HANDLE != info.fAlloc.fMemory); - GrMipMapsStatus mipMapsStatus = info->fLevelCount > 1 ? GrMipMapsStatus::kDirty - : GrMipMapsStatus::kNotAllocated; + GrMipMapsStatus mipMapsStatus = info.fLevelCount > 1 ? GrMipMapsStatus::kDirty + : GrMipMapsStatus::kNotAllocated; GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership ? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned; - return Make(gpu, desc, *info, mipMapsStatus, SkBudgeted::kNo, ownership, true); + return Make(gpu, desc, info, std::move(layout), mipMapsStatus, SkBudgeted::kNo, ownership, + true); } bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) { diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h index 4b3e057005..0a0ba4d5ce 100644 --- a/src/gpu/vk/GrVkTextureRenderTarget.h +++ b/src/gpu/vk/GrVkTextureRenderTarget.h @@ -33,7 +33,8 @@ public: static sk_sp MakeWrappedTextureRenderTarget(GrVkGpu*, const GrSurfaceDesc&, GrWrapOwnership, - const GrVkImageInfo*); + const GrVkImageInfo&, + sk_sp); bool updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo); @@ -53,8 +54,10 @@ private: SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrMipMapsStatus, @@ -64,6 +67,7 @@ private: SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageView* colorAttachmentView, GrMipMapsStatus, @@ -72,8 +76,10 @@ private: GrVkTextureRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageInfo& msaaInfo, + sk_sp msaaLayout, const GrVkImageView* colorAttachmentView, const GrVkImageView* resolveAttachmentView, GrMipMapsStatus, @@ -82,6 +88,7 @@ private: GrVkTextureRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageView* colorAttachmentView, GrMipMapsStatus, @@ -90,6 +97,7 @@ private: static sk_sp Make(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, + sk_sp, GrMipMapsStatus, SkBudgeted budgeted, GrBackendObjectOwnership, diff --git a/src/gpu/vk/GrVkTypesPriv.cpp b/src/gpu/vk/GrVkTypesPriv.cpp new file mode 100644 index 0000000000..ec75e58e3b --- /dev/null +++ b/src/gpu/vk/GrVkTypesPriv.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrVkTypesPriv.h" + +#include "GrVkImageLayout.h" + +void GrVkBackendSurfaceInfo::cleanup() { + SkSafeUnref(fLayout); + fLayout = nullptr; +}; + +void GrVkBackendSurfaceInfo::assign(const GrVkBackendSurfaceInfo& that, bool isThisValid) { + fImageInfo = that.fImageInfo; + GrVkImageLayout* oldLayout = fLayout; + fLayout = SkSafeRef(that.fLayout); + if (isThisValid) { + SkSafeUnref(oldLayout); + } +} + +void GrVkBackendSurfaceInfo::setImageLayout(VkImageLayout layout) { + SkASSERT(fLayout); + fLayout->setImageLayout(layout); +} + +sk_sp GrVkBackendSurfaceInfo::getGrVkImageLayout() const { + SkASSERT(fLayout); + return sk_ref_sp(fLayout); +} + +GrVkImageInfo GrVkBackendSurfaceInfo::snapImageInfo() const { + return GrVkImageInfo(fImageInfo, fLayout->getImageLayout()); +} + +#if GR_TEST_UTILS +bool GrVkBackendSurfaceInfo::operator==(const GrVkBackendSurfaceInfo& that) const { + GrVkImageInfo cpyInfoThis = fImageInfo; + GrVkImageInfo cpyInfoThat = that.fImageInfo; + // We don't care about the fImageLayout here since we require they use the same + // GrVkImageLayout. + cpyInfoThis.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + cpyInfoThat.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + return cpyInfoThis == cpyInfoThat && fLayout == that.fLayout; +} +#endif diff --git a/tests/EGLImageTest.cpp b/tests/EGLImageTest.cpp index b44f5b2bfa..d7f3861888 100644 --- a/tests/EGLImageTest.cpp +++ b/tests/EGLImageTest.cpp @@ -98,16 +98,20 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) { return; } - const GrGLTextureInfo* texInfo = backendTexture1.getGLTextureInfo(); + GrGLTextureInfo texInfo; + if (!backendTexture1.getGLTextureInfo(&texInfo)) { + ERRORF(reporter, "Failed to get GrGLTextureInfo"); + return; + } - if (GR_GL_TEXTURE_2D != texInfo->fTarget) { + if (GR_GL_TEXTURE_2D != texInfo.fTarget) { ERRORF(reporter, "Expected backend texture to be 2D"); cleanup(glCtx0, externalTexture.fID, glCtx1.get(), context1, &backendTexture1, image); return; } // Wrap the texture in an EGLImage - image = glCtx1->texture2DToEGLImage(texInfo->fID); + image = glCtx1->texture2DToEGLImage(texInfo.fID); if (GR_EGL_NO_IMAGE == image) { ERRORF(reporter, "Error creating EGL Image from texture"); cleanup(glCtx0, externalTexture.fID, glCtx1.get(), context1, &backendTexture1, image); @@ -128,8 +132,8 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) { pixels.get()[i] = 0xDDAABBCC; } GR_GL_CALL(glCtx1->gl(), ActiveTexture(GR_GL_TEXTURE0)); - GR_GL_CALL(glCtx1->gl(), BindTexture(texInfo->fTarget, texInfo->fID)); - GR_GL_CALL(glCtx1->gl(), TexSubImage2D(texInfo->fTarget, 0, 0, 0, kSize, kSize, + GR_GL_CALL(glCtx1->gl(), BindTexture(texInfo.fTarget, texInfo.fID)); + GR_GL_CALL(glCtx1->gl(), TexSubImage2D(texInfo.fTarget, 0, 0, 0, kSize, kSize, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, pixels.get())); GR_GL_CALL(glCtx1->gl(), Finish()); // We've been making direct GL calls in GL context 1, let GrContext 1 know its internal diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp index 4e8179950d..aaca9b4410 100644 --- a/tests/GrMipMappedTest.cpp +++ b/tests/GrMipMappedTest.cpp @@ -181,22 +181,34 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, GrBackendTexture genBackendTex = genTexture->getBackendTexture(); - if (const GrGLTextureInfo* genTexInfo = genBackendTex.getGLTextureInfo()) { - const GrGLTextureInfo* origTexInfo = backendTex.getGLTextureInfo(); - if (willUseMips && GrMipMapped::kNo == mipMapped) { - // We did a copy so the texture IDs should be different - REPORTER_ASSERT(reporter, origTexInfo->fID != genTexInfo->fID); + if (kOpenGL_GrBackend == genBackendTex.backend()) { + GrGLTextureInfo genTexInfo; + GrGLTextureInfo origTexInfo; + if (genBackendTex.getGLTextureInfo(&genTexInfo) && + backendTex.getGLTextureInfo(&origTexInfo)) { + if (willUseMips && GrMipMapped::kNo == mipMapped) { + // We did a copy so the texture IDs should be different + REPORTER_ASSERT(reporter, origTexInfo.fID != genTexInfo.fID); + } else { + REPORTER_ASSERT(reporter, origTexInfo.fID == genTexInfo.fID); + } } else { - REPORTER_ASSERT(reporter, origTexInfo->fID == genTexInfo->fID); + ERRORF(reporter, "Failed to get GrGLTextureInfo"); } #ifdef SK_VULKAN - } else if (const GrVkImageInfo* genImageInfo = genBackendTex.getVkImageInfo()) { - const GrVkImageInfo* origImageInfo = backendTex.getVkImageInfo(); - if (willUseMips && GrMipMapped::kNo == mipMapped) { - // We did a copy so the texture IDs should be different - REPORTER_ASSERT(reporter, origImageInfo->fImage != genImageInfo->fImage); + } else if (kVulkan_GrBackend == genBackendTex.backend()) { + GrVkImageInfo genImageInfo; + GrVkImageInfo origImageInfo; + if (genBackendTex.getVkImageInfo(&genImageInfo) && + backendTex.getVkImageInfo(&origImageInfo)) { + if (willUseMips && GrMipMapped::kNo == mipMapped) { + // We did a copy so the texture IDs should be different + REPORTER_ASSERT(reporter, origImageInfo.fImage != genImageInfo.fImage); + } else { + REPORTER_ASSERT(reporter, origImageInfo.fImage == genImageInfo.fImage); + } } else { - REPORTER_ASSERT(reporter, origImageInfo->fImage == genImageInfo->fImage); + ERRORF(reporter, "Failed to get GrVkImageInfo"); } #endif } else { diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index fd9baecd4b..55730816bb 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -1065,7 +1065,12 @@ static uint32_t GetIdForBackendTexture(GrBackendTexture texture) { return 0; } - return texture.getGLTextureInfo()->fID; + GrGLTextureInfo info; + if (!texture.getGLTextureInfo(&info)) { + return 0; + } + + return info.fID; } DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(makeBackendTexture, reporter, ctxInfo) { diff --git a/tests/VkBackendSurfaceTest.cpp b/tests/VkBackendSurfaceTest.cpp new file mode 100644 index 0000000000..298dc38b4e --- /dev/null +++ b/tests/VkBackendSurfaceTest.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// This is a GPU-backend specific test. It relies on static intializers to work + +#include "SkTypes.h" + +#if SK_SUPPORT_GPU && defined(SK_VULKAN) + +#include "GrTest.h" +#include "Test.h" + +#include "GrBackendSurface.h" +#include "GrContextPriv.h" +#include "GrTextureProxy.h" +#include "GrTexture.h" +#include "SkImage.h" +#include "SkImage_Base.h" +#include "vk/GrVkGpu.h" +#include "vk/GrVkImageLayout.h" +#include "vk/GrVkTexture.h" +#include "vk/GrVkTypes.h" + +DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkImageLayoutTest, reporter, ctxInfo) { + GrContext* context = ctxInfo.grContext(); + GrVkGpu* gpu = static_cast(context->contextPriv().getGpu()); + + GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(nullptr, 1, 1, + kRGBA_8888_GrPixelConfig, + false, + GrMipMapped::kNo); + REPORTER_ASSERT(reporter, backendTex.isValid()); + + GrVkImageInfo info; + REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); + VkImageLayout initLayout = info.fImageLayout; + + // Verify that setting that layout via a copy of a backendTexture is reflected in all the + // backendTextures. + GrBackendTexture backendTexCopy = backendTex; + REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); + + backendTexCopy.setVkImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); + + REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); + + // Setting back the layout since we didn't actually change it + backendTex.setVkImageLayout(initLayout); + + sk_sp wrappedImage = SkImage::MakeFromTexture(context, backendTex, + kTopLeft_GrSurfaceOrigin, + kRGBA_8888_SkColorType, + kPremul_SkAlphaType, nullptr); + REPORTER_ASSERT(reporter, wrappedImage.get()); + + sk_sp texProxy = as_IB(wrappedImage)->asTextureProxyRef(); + REPORTER_ASSERT(reporter, texProxy.get()); + REPORTER_ASSERT(reporter, texProxy->priv().isInstantiated()); + GrTexture* texture = texProxy->priv().peekTexture(); + REPORTER_ASSERT(reporter, texture); + + // Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture + GrVkTexture* vkTexture = static_cast(texture); + REPORTER_ASSERT(reporter, initLayout == vkTexture->currentLayout()); + vkTexture->updateImageLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout); + + GrBackendTexture backendTexImage = wrappedImage->getBackendTexture(false); + REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout); + + // Verify that modifying the layout via the GrBackendTexutre is reflected in the GrVkTexture + backendTexImage.setVkImageLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == vkTexture->currentLayout()); + + // Verify that modifying the layout via the old textureHandle sitll works in is reflected in the + // GrVkTexture and GrBackendTexture. + GrVkImageInfo* backendInfo = (GrVkImageInfo*)wrappedImage->getTextureHandle(false); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == backendInfo->fImageLayout); + + backendInfo->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + REPORTER_ASSERT(reporter, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == vkTexture->currentLayout()); + REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == info.fImageLayout); + + vkTexture->updateImageLayout(initLayout); + + REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); + + REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); + + REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); + + // Check that we can do things like assigning the backend texture to invalid one, assign an + // invalid one, assin a backend texture to inself etc. Success here is that we don't hit any of + // our ref counting asserts. + REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(backendTex, backendTexCopy)); + + GrBackendTexture invalidTexture; + REPORTER_ASSERT(reporter, !invalidTexture.isValid()); + REPORTER_ASSERT(reporter, !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy)); + + backendTexCopy = invalidTexture; + REPORTER_ASSERT(reporter, !backendTexCopy.isValid()); + REPORTER_ASSERT(reporter, !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy)); + + invalidTexture = backendTex; + REPORTER_ASSERT(reporter, invalidTexture.isValid()); + REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTex)); + + invalidTexture = invalidTexture; + REPORTER_ASSERT(reporter, invalidTexture.isValid()); + REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, invalidTexture)); + + gpu->deleteTestingOnlyBackendTexture(backendTex); +} + +#endif diff --git a/tests/VkWrapTests.cpp b/tests/VkWrapTests.cpp index 367fdb5c53..cd0b72e0fe 100644 --- a/tests/VkWrapTests.cpp +++ b/tests/VkWrapTests.cpp @@ -36,14 +36,15 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) { GrBackendTexture origBackendTex = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig, false, GrMipMapped::kNo); - const GrVkImageInfo* imageInfo = origBackendTex.getVkImageInfo(); + GrVkImageInfo imageInfo; + SkAssertResult(origBackendTex.getVkImageInfo(&imageInfo)); sk_sp tex = gpu->wrapBackendTexture(origBackendTex, kBorrow_GrWrapOwnership); REPORTER_ASSERT(reporter, tex); // image is null { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; backendCopy.fImage = VK_NULL_HANDLE; GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy); tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership); @@ -54,7 +55,7 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) { // alloc is null { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; backendCopy.fAlloc = GrVkAlloc(); GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy); tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership); @@ -65,7 +66,7 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) { // check adopt creation { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy); tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership); @@ -79,16 +80,17 @@ void wrap_rt_test(skiatest::Reporter* reporter, GrContext* context) { GrBackendTexture origBackendTex = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig, true, GrMipMapped::kNo); - const GrVkImageInfo* imageInfo = origBackendTex.getVkImageInfo(); + GrVkImageInfo imageInfo; + SkAssertResult(origBackendTex.getVkImageInfo(&imageInfo)); - GrBackendRenderTarget origBackendRT(kW, kH, 1, 0, *imageInfo); + GrBackendRenderTarget origBackendRT(kW, kH, 1, 0, imageInfo); sk_sp rt = gpu->wrapBackendRenderTarget(origBackendRT); REPORTER_ASSERT(reporter, rt); // image is null { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; backendCopy.fImage = VK_NULL_HANDLE; GrBackendRenderTarget backendRT(kW, kH, 1, 0, backendCopy); rt = gpu->wrapBackendRenderTarget(backendRT); @@ -97,7 +99,7 @@ void wrap_rt_test(skiatest::Reporter* reporter, GrContext* context) { // alloc is null { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; backendCopy.fAlloc = GrVkAlloc(); // can wrap null alloc GrBackendRenderTarget backendRT(kW, kH, 1, 0, backendCopy); @@ -116,7 +118,8 @@ void wrap_trt_test(skiatest::Reporter* reporter, GrContext* context) { GrBackendTexture origBackendTex = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kPixelConfig, true, GrMipMapped::kNo); - const GrVkImageInfo* imageInfo = origBackendTex.getVkImageInfo(); + GrVkImageInfo imageInfo; + SkAssertResult(origBackendTex.getVkImageInfo(&imageInfo)); sk_sp tex = gpu->wrapRenderableBackendTexture(origBackendTex, 1, kBorrow_GrWrapOwnership); @@ -124,7 +127,7 @@ void wrap_trt_test(skiatest::Reporter* reporter, GrContext* context) { // image is null { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; backendCopy.fImage = VK_NULL_HANDLE; GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy); tex = gpu->wrapRenderableBackendTexture(backendTex, 1, kBorrow_GrWrapOwnership); @@ -135,7 +138,7 @@ void wrap_trt_test(skiatest::Reporter* reporter, GrContext* context) { // alloc is null { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; backendCopy.fAlloc = GrVkAlloc(); GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy); tex = gpu->wrapRenderableBackendTexture(backendTex, 1, kBorrow_GrWrapOwnership); @@ -146,7 +149,7 @@ void wrap_trt_test(skiatest::Reporter* reporter, GrContext* context) { // check adopt creation { - GrVkImageInfo backendCopy = *imageInfo; + GrVkImageInfo backendCopy = imageInfo; GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy); tex = gpu->wrapRenderableBackendTexture(backendTex, 1, kAdopt_GrWrapOwnership); REPORTER_ASSERT(reporter, tex);