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 <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2018-04-10 09:34:07 -04:00 committed by Skia Commit-Bot
parent 58627cb8eb
commit 52e16d9848
29 changed files with 713 additions and 188 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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<GrVkImageLayout> getGrVkImageLayout() const;
friend class GrVkTexture;
GrBackendTexture(int width,
int height,
const GrVkImageInfo& vkInfo,
sk_sp<GrVkImageLayout> layout);
#endif
// Free and release and resources being held by the GrBackendTexture.
void cleanup();
bool fIsValid;
int fWidth; //<! width in pixels
int fHeight; //<! height in pixels
@ -192,7 +218,7 @@ private:
union {
GrGLTextureInfo fGLInfo;
#ifdef SK_VULKAN
GrVkImageInfo fVkInfo;
GrVkBackendSurfaceInfo fVkInfo;
#endif
GrMockTextureInfo fMockInfo;
};

View File

@ -75,6 +75,22 @@ struct GrVkImageInfo {
VkFormat fFormat;
uint32_t fLevelCount;
GrVkImageInfo()
: fImage(VK_NULL_HANDLE)
, fAlloc()
, fImageTiling(VK_IMAGE_TILING_OPTIMAL)
, fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED)
, fFormat(VK_FORMAT_UNDEFINED)
, fLevelCount(0) {}
GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout)
: fImage(info.fImage)
, fAlloc(info.fAlloc)
, fImageTiling(info.fImageTiling)
, fImageLayout(layout)
, fFormat(info.fFormat)
, fLevelCount(info.fLevelCount) {}
// This gives a way for a client to update the layout of the Image if they change the layout
// while we're still holding onto the wrapped texture. They will first need to get a handle
// to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.

View File

@ -0,0 +1,49 @@
/*
* 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 GrVkTypesPriv_DEFINED
#define GrVkTypesPriv_DEFINED
#include "GrVkTypes.h"
#include "SkRefCnt.h"
class GrVkImageLayout;
// This struct is to used to store the the actual information about the vulkan backend image on the
// GrBackendTexture and GrBackendRenderTarget. When a client calls getVkImageInfo on a
// GrBackendTexture/RenderTarget, we use the GrVkBackendSurfaceInfo to create a snapshot
// GrVkImgeInfo object. Internally, this uses a ref count GrVkImageLayout object to track the
// current VkImageLayout which can be shared with an internal GrVkImage so that layout updates can
// be seen by all users of the image.
struct GrVkBackendSurfaceInfo {
GrVkBackendSurfaceInfo(GrVkImageInfo info, GrVkImageLayout* layout)
: fImageInfo(info), fLayout(layout) {}
void cleanup();
GrVkBackendSurfaceInfo& operator=(const GrVkBackendSurfaceInfo&) = delete;
// Assigns the passed in GrVkBackendSurfaceInfo to this object. if isValid is true we will also
// attempt to unref the old fLayout on this object.
void assign(const GrVkBackendSurfaceInfo&, bool isValid);
void setImageLayout(VkImageLayout layout);
sk_sp<GrVkImageLayout> getGrVkImageLayout() const;
GrVkImageInfo snapImageInfo() const;
#if GR_TEST_UTILS
bool operator==(const GrVkBackendSurfaceInfo& that) const;
#endif
private:
GrVkImageInfo fImageInfo;
GrVkImageLayout* fLayout;
};
#endif

View File

@ -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<GrVkImageLayout>(new GrVkImageLayout(vkInfo.fImageLayout))) {}
GrBackendTexture::GrBackendTexture(int width,
int height,
const GrVkImageInfo& vkInfo,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> 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();

View File

@ -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,

View File

@ -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<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTa
sk_sp<GrRenderTarget> 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<GrRenderTarget> 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));
}
}

View File

@ -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;
}

View File

@ -95,8 +95,9 @@ sk_sp<GrTexture> 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<GrTexture> 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<GrRenderTarget> 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);
}
}

View File

@ -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,

View File

@ -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<GrTexture> 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<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
SkASSERT(layout);
return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, imageInfo, std::move(layout));
}
sk_sp<GrTexture> GrVkGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex,
@ -907,8 +913,15 @@ sk_sp<GrTexture> 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<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
SkASSERT(layout);
return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership,
backendTex.getVkImageInfo());
imageInfo, std::move(layout));
}
sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT){
@ -935,7 +948,10 @@ sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTa
desc.fConfig = backendRT.config();
desc.fSampleCnt = 1;
sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info);
sk_sp<GrVkImageLayout> layout(new GrVkImageLayout(info->fImageLayout));
sk_sp<GrVkRenderTarget> 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<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTa
sk_sp<GrRenderTarget> 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<GrRenderTarget> GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBacken
return nullptr;
}
sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info);
sk_sp<GrVkImageLayout> layout = tex.getGrVkImageLayout();
SkASSERT(layout);
sk_sp<GrVkRenderTarget> 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<GrVkImageInfo*>(info));
GrVkImage::DestroyImageInfo(this, const_cast<GrVkImageInfo*>(&info));
}
}

View File

@ -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) {

View File

@ -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<GrVkImageLayout> 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> 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<VkImageLayout*>(&fInfo.fImageLayout) = fLayout->getImageLayout();
}
*const_cast<VkImageLayout*>(&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<GrVkImageLayout> 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 {

View File

@ -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<VkImageLayout> fLayout;
};
#endif

View File

@ -26,16 +26,18 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> layout,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> 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<GrVkImageLayout> 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<GrVkImageLayout> 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<GrVkImageLayout> 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<GrVkImageLayout> 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>
GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo* info) {
SkASSERT(info);
SkASSERT(VK_NULL_HANDLE != info->fImage);
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout) {
SkASSERT(VK_NULL_HANDLE != info.fImage);
return sk_sp<GrVkRenderTarget>(
GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, *info,
GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, info, std::move(layout),
GrBackendObjectOwnership::kBorrowed));
}

View File

@ -35,7 +35,8 @@ public:
const GrVkImage::ImageDesc&);
static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
const GrVkImageInfo*);
const GrVkImageInfo&,
sk_sp<GrVkImageLayout>);
~GrVkRenderTarget() override;
@ -81,7 +82,9 @@ protected:
GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> msaaLayout,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
GrBackendObjectOwnership);
@ -89,6 +92,7 @@ protected:
GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* colorAttachmentView,
GrBackendObjectOwnership);
@ -119,7 +123,9 @@ private:
SkBudgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> msaaLayout,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
GrBackendObjectOwnership);
@ -128,11 +134,13 @@ private:
SkBudgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* colorAttachmentView,
GrBackendObjectOwnership);
static GrVkRenderTarget* Create(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&,
const GrVkImageInfo&, GrBackendObjectOwnership);
const GrVkImageInfo&, sk_sp<GrVkImageLayout>,
GrBackendObjectOwnership);
bool completeStencilAttachment() override;

View File

@ -17,9 +17,10 @@ GrVkStencilAttachment::GrVkStencilAttachment(GrVkGpu* gpu,
const Format& format,
const GrVkImage::ImageDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> layout(new GrVkImageLayout(info.fImageLayout));
GrVkStencilAttachment* stencil = new GrVkStencilAttachment(gpu, format, imageDesc,
info, imageView);
info, std::move(layout), imageView);
imageView->unref(gpu);
return stencil;

View File

@ -45,6 +45,7 @@ private:
const Format& format,
const GrVkImage::ImageDesc&,
const GrVkImageInfo&,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* stencilView);
GrVkGpu* getVkGpu() const;

View File

@ -27,10 +27,11 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> 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<GrVkImageLayout> 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> GrVkTexture::CreateNewTexture(GrVkGpu* gpu, SkBudgeted budget
GrVkImage::DestroyImageInfo(gpu, &info);
return nullptr;
}
sk_sp<GrVkImageLayout> layout(new GrVkImageLayout(info.fImageLayout));
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, budgeted, desc, info, imageView,
mipMapsStatus));
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, budgeted, desc, info, std::move(layout),
imageView, mipMapsStatus));
}
sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrWrapOwnership wrapOwnership,
const GrVkImageInfo* info) {
SkASSERT(info);
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> 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<GrVkTexture>(new GrVkTexture(gpu, kWrapped, desc, *info, imageView,
mipMapsStatus, ownership));
return sk_sp<GrVkTexture>(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);

View File

@ -24,7 +24,8 @@ public:
GrMipMapsStatus);
static sk_sp<GrVkTexture> MakeWrappedTexture(GrVkGpu*, const GrSurfaceDesc&,
GrWrapOwnership, const GrVkImageInfo*);
GrWrapOwnership, const GrVkImageInfo&,
sk_sp<GrVkImageLayout>);
~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<GrVkImageLayout>,
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<GrVkImageLayout> 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<GrVkImageLayout> layout, const GrVkImageView* imageView, GrMipMapsStatus,
GrBackendObjectOwnership);
const GrVkImageView* fTextureView;

View File

@ -22,17 +22,20 @@ GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* texView,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> 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<GrVkImageLayout> layout,
const GrVkImageView* texView,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> 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<GrVkImageLayout> 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> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
GrMipMapsStatus mipMapsStatus,
SkBudgeted budgeted,
GrBackendObjectOwnership ownership,
@ -105,6 +114,7 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
// create msaa surface if necessary
GrVkImageInfo msInfo;
sk_sp<GrVkImageLayout> msLayout;
const GrVkImageView* resolveAttachmentView = nullptr;
if (desc.fSampleCnt > 1) {
GrVkImage::ImageDesc msImageDesc;
@ -137,6 +147,7 @@ sk_sp<GrVkTextureRenderTarget> 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> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
if (!isWrapped) {
texRT = sk_sp<GrVkTextureRenderTarget>(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<GrVkTextureRenderTarget>(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> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
if (!isWrapped) {
texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(
gpu, budgeted, desc,
info, imageView,
info, std::move(layout), imageView,
colorAttachmentView, mipMapsStatus,
ownership));
} else {
texRT = sk_sp<GrVkTextureRenderTarget>(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<GrVkImageLayout> layout(new GrVkImageLayout(info.fImageLayout));
sk_sp<GrVkTextureRenderTarget> trt = Make(gpu, desc, info, mipMapsStatus, budgeted,
GrBackendObjectOwnership::kOwned, false);
sk_sp<GrVkTextureRenderTarget> 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>
GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrWrapOwnership wrapOwnership,
const GrVkImageInfo* info) {
SkASSERT(info);
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> 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) {

View File

@ -33,7 +33,8 @@ public:
static sk_sp<GrVkTextureRenderTarget> MakeWrappedTextureRenderTarget(GrVkGpu*,
const GrSurfaceDesc&,
GrWrapOwnership,
const GrVkImageInfo*);
const GrVkImageInfo&,
sk_sp<GrVkImageLayout>);
bool updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo);
@ -53,8 +54,10 @@ private:
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* texView,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> msaaLayout,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
GrMipMapsStatus,
@ -64,6 +67,7 @@ private:
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* texView,
const GrVkImageView* colorAttachmentView,
GrMipMapsStatus,
@ -72,8 +76,10 @@ private:
GrVkTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* texView,
const GrVkImageInfo& msaaInfo,
sk_sp<GrVkImageLayout> msaaLayout,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
GrMipMapsStatus,
@ -82,6 +88,7 @@ private:
GrVkTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout,
const GrVkImageView* texView,
const GrVkImageView* colorAttachmentView,
GrMipMapsStatus,
@ -90,6 +97,7 @@ private:
static sk_sp<GrVkTextureRenderTarget> Make(GrVkGpu*,
const GrSurfaceDesc&,
const GrVkImageInfo&,
sk_sp<GrVkImageLayout>,
GrMipMapsStatus,
SkBudgeted budgeted,
GrBackendObjectOwnership,

View File

@ -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<GrVkImageLayout> 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

View File

@ -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

View File

@ -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 {

View File

@ -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) {

View File

@ -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<GrVkGpu*>(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<SkImage> wrappedImage = SkImage::MakeFromTexture(context, backendTex,
kTopLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType,
kPremul_SkAlphaType, nullptr);
REPORTER_ASSERT(reporter, wrappedImage.get());
sk_sp<GrTextureProxy> 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<GrVkTexture*>(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

View File

@ -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<GrTexture> 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<GrRenderTarget> 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<GrTexture> 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);