diff --git a/gn/gpu.gni b/gn/gpu.gni index c9fd2f30082a2..774b2a70d509b 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 154e30085823e..8fc7210aa70a0 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 f0d716cad0d18..f0bbab5689ad3 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 @@ class SK_API GrBackendTexture { 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 @@ class SK_API GrBackendTexture { 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 5832fa6e0a9fb..36c26e9cdb4e7 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 421ca25bbdf96..990a15d88f71f 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 08bca6dcc8bc2..c9cd494233cf0 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 27d295ebd5c21..65dd766d8d4c8 100644 --- a/src/gpu/mock/GrMockCaps.h +++ b/src/gpu/mock/GrMockCaps.h @@ -77,12 +77,12 @@ class GrMockCaps : public GrCaps { 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 a677d63bba126..060d7bd261bc9 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 e4ff3ef09a4b3..5747cc04c318c 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 af9505821a7a4..855232badd870 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 5e0ffe240f5b8..556a088fb1df6 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 e43c2f2672202..9e99743fe7262 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 @@ class GrVkImage : SkNoncopyable { 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 @@ class GrVkImage : SkNoncopyable { } 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 @@ class GrVkImage : SkNoncopyable { // 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 @@ class GrVkImage : SkNoncopyable { 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 0000000000000..8f21fa8bfbbb8 --- /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 99b6b7632ca95..5570c0d3b4b62 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 02d4add455ea0..64be0b78e4740 100644 --- a/src/gpu/vk/GrVkRenderTarget.h +++ b/src/gpu/vk/GrVkRenderTarget.h @@ -35,7 +35,8 @@ class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage { const GrVkImage::ImageDesc&); static sk_sp MakeWrappedRenderTarget(GrVkGpu*, const GrSurfaceDesc&, - const GrVkImageInfo*); + const GrVkImageInfo&, + sk_sp); ~GrVkRenderTarget() override; @@ -81,7 +82,9 @@ class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage { 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 @@ class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage { GrVkRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* colorAttachmentView, GrBackendObjectOwnership); @@ -119,7 +123,9 @@ class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage { 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 @@ class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage { 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 139c00f3b2c5b..7c5e83e500e03 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 f6bf19af4f62b..ac70bfb508644 100644 --- a/src/gpu/vk/GrVkStencilAttachment.h +++ b/src/gpu/vk/GrVkStencilAttachment.h @@ -45,6 +45,7 @@ class GrVkStencilAttachment : public GrStencilAttachment, public GrVkImage { 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 109b10638df9a..0b9862443c586 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 f2fabc887b733..e37b53ebbf93f 100644 --- a/src/gpu/vk/GrVkTexture.h +++ b/src/gpu/vk/GrVkTexture.h @@ -24,7 +24,8 @@ class GrVkTexture : public GrTexture, public virtual GrVkImage { GrMipMapsStatus); static sk_sp MakeWrappedTexture(GrVkGpu*, const GrSurfaceDesc&, - GrWrapOwnership, const GrVkImageInfo*); + GrWrapOwnership, const GrVkImageInfo&, + sk_sp); ~GrVkTexture() override; @@ -45,8 +46,8 @@ class GrVkTexture : public GrTexture, public virtual GrVkImage { } 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 @@ class GrVkTexture : public GrTexture, public virtual GrVkImage { 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 ee31f2364a442..0fde5f9816837 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 4b3e057005c5e..0a0ba4d5ce60d 100644 --- a/src/gpu/vk/GrVkTextureRenderTarget.h +++ b/src/gpu/vk/GrVkTextureRenderTarget.h @@ -33,7 +33,8 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget { 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 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget { 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 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget { SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageView* colorAttachmentView, GrMipMapsStatus, @@ -72,8 +76,10 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget { 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 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget { GrVkTextureRenderTarget(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, + sk_sp layout, const GrVkImageView* texView, const GrVkImageView* colorAttachmentView, GrMipMapsStatus, @@ -90,6 +97,7 @@ class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget { 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 0000000000000..ec75e58e3bb50 --- /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 b44f5b2bfa547..d7f3861888639 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 4e8179950da2e..aaca9b4410acc 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 fd9baecd4b12a..55730816bbf7a 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 0000000000000..298dc38b4efdc --- /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 367fdb5c5324f..cd0b72e0fe859 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);