aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2016-03-18 11:57:24 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-18 11:57:24 -0700
commitfd359caf0cbdefd759d1c788d72faba3f65a6386 (patch)
tree541034405d63060f5b336bd9d739dd60cb13f99b /src/gpu
parent89edf7a95ea694ba2c0a33adedf553c4183cdc19 (diff)
Implement Vulkan GrBackendObject for textures.
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/vk/GrVkGpu.cpp121
-rw-r--r--src/gpu/vk/GrVkRenderTarget.cpp29
-rw-r--r--src/gpu/vk/GrVkRenderTarget.h4
-rw-r--r--src/gpu/vk/GrVkTexture.cpp29
-rw-r--r--src/gpu/vk/GrVkTexture.h4
-rw-r--r--src/gpu/vk/GrVkTextureRenderTarget.cpp31
-rw-r--r--src/gpu/vk/GrVkTextureRenderTarget.h3
7 files changed, 156 insertions, 65 deletions
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 180ba3be66..16526f6613 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -34,6 +34,7 @@
#include "SkConfig8888.h"
#include "vk/GrVkInterface.h"
+#include "vk/GrVkTypes.h"
#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X)
#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X)
@@ -195,7 +196,8 @@ GrVkGpu::~GrVkGpu() {
fCurrentCmdBuffer->unref(this);
// wait for all commands to finish
- VK_CALL(QueueWaitIdle(fQueue));
+ VkResult res = VK_CALL(QueueWaitIdle(fQueue));
+ SkASSERT(res == VK_SUCCESS);
// must call this just before we destroy the VkDevice
fResourceProvider.destroyResources();
@@ -582,8 +584,10 @@ GrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
return nullptr;
}
- // TODO: determine what format Chrome will actually send us and turn it into a Resource
- GrVkImage::Resource* imageRsrc = reinterpret_cast<GrVkImage::Resource*>(desc.fTextureHandle);
+ const GrVkTextureInfo* info = reinterpret_cast<const GrVkTextureInfo*>(desc.fTextureHandle);
+ if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc) {
+ return nullptr;
+ }
GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership)
? GrGpuResource::kAdopted_LifeCycle
@@ -605,9 +609,10 @@ GrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
if (renderTarget) {
texture = GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(this, surfDesc,
lifeCycle, format,
- imageRsrc);
+ info);
} else {
- texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, format, imageRsrc);
+ texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, format,
+ info);
}
if (!texture) {
return nullptr;
@@ -619,9 +624,12 @@ GrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc,
GrWrapOwnership ownership) {
- // TODO: determine what format Chrome will actually send us and turn it into a Resource
- GrVkImage::Resource* imageRsrc =
- reinterpret_cast<GrVkImage::Resource*>(wrapDesc.fRenderTargetHandle);
+ const GrVkTextureInfo* info =
+ reinterpret_cast<const GrVkTextureInfo*>(wrapDesc.fRenderTargetHandle);
+ if (VK_NULL_HANDLE == info->fImage ||
+ (VK_NULL_HANDLE == info->fAlloc && kAdopt_GrWrapOwnership == ownership)) {
+ return nullptr;
+ }
GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership)
? GrGpuResource::kAdopted_LifeCycle
@@ -637,7 +645,8 @@ GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
desc.fOrigin = resolve_origin(wrapDesc.fOrigin);
GrVkRenderTarget* tgt = GrVkRenderTarget::CreateWrappedRenderTarget(this, desc,
- lifeCycle, imageRsrc);
+ lifeCycle,
+ info);
if (tgt && wrapDesc.fStencilBits) {
if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeight)) {
tgt->unref();
@@ -736,22 +745,42 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
VkFlags memProps = (srcData && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
- // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is
- // requested, this ImageDesc describes the resolved texutre. Therefore we always have samples set
- // to 1.
- GrVkImage::ImageDesc imageDesc;
- imageDesc.fImageType = VK_IMAGE_TYPE_2D;
- imageDesc.fFormat = pixelFormat;
- imageDesc.fWidth = w;
- imageDesc.fHeight = h;
- imageDesc.fLevels = 1;
- imageDesc.fSamples = 1;
- imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
- imageDesc.fUsageFlags = usageFlags;
- imageDesc.fMemProps = memProps;
+ VkImage image = VK_NULL_HANDLE;
+ VkDeviceMemory alloc = VK_NULL_HANDLE;
- const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(this, imageDesc);
- if (!imageRsrc) {
+ VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
+ VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling)
+ ? VK_IMAGE_LAYOUT_PREINITIALIZED
+ : VK_IMAGE_LAYOUT_UNDEFINED;
+
+ // Create Image
+ VkSampleCountFlagBits vkSamples;
+ if (!GrSampleCountToVkSampleCount(1, &vkSamples)) {
+ return 0;
+ }
+
+ const VkImageCreateInfo imageCreateInfo = {
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
+ NULL, // pNext
+ 0, // VkImageCreateFlags
+ VK_IMAGE_TYPE_2D, // VkImageType
+ pixelFormat, // VkFormat
+ { w, h, 1 }, // VkExtent3D
+ 1, // mipLevels
+ 1, // arrayLayers
+ vkSamples, // samples
+ imageTiling, // VkImageTiling
+ usageFlags, // VkImageUsageFlags
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode
+ 0, // queueFamilyCount
+ 0, // pQueueFamilyIndices
+ initialLayout // initialLayout
+ };
+
+ GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image));
+
+ if (!GrVkMemory::AllocAndBindImageMemory(this, image, memProps, &alloc)) {
+ VK_CALL(DestroyImage(this->device(), image, nullptr));
return 0;
}
@@ -765,22 +794,13 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
VkSubresourceLayout layout;
VkResult err;
- const GrVkInterface* interface = this->vkInterface();
-
- GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice,
- imageRsrc->fImage,
- &subres,
- &layout));
+ VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout));
void* mapPtr;
- err = GR_VK_CALL(interface, MapMemory(fDevice,
- imageRsrc->fAlloc,
- 0,
- layout.rowPitch * h,
- 0,
- &mapPtr));
+ err = VK_CALL(MapMemory(fDevice, alloc, 0, layout.rowPitch * h, 0, &mapPtr));
if (err) {
- imageRsrc->unref(this);
+ VK_CALL(FreeMemory(this->device(), alloc, nullptr));
+ VK_CALL(DestroyImage(this->device(), image, nullptr));
return 0;
}
@@ -791,21 +811,27 @@ GrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, i
if (rowCopyBytes == layout.rowPitch) {
memcpy(mapPtr, srcData, rowCopyBytes * h);
} else {
- SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcData, w, rowCopyBytes,
- h);
+ SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcData, rowCopyBytes,
+ rowCopyBytes, h);
}
- GR_VK_CALL(interface, UnmapMemory(fDevice, imageRsrc->fAlloc));
+ VK_CALL(UnmapMemory(fDevice, alloc));
} else {
// TODO: Add support for copying to optimal tiling
SkASSERT(false);
}
}
- return (GrBackendObject)imageRsrc;
+ GrVkTextureInfo* info = new GrVkTextureInfo;
+ info->fImage = image;
+ info->fAlloc = alloc;
+ info->fImageTiling = imageTiling;
+ info->fImageLayout = initialLayout;
+
+ return (GrBackendObject)info;
}
bool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const {
- GrVkImage::Resource* backend = reinterpret_cast<GrVkImage::Resource*>(id);
+ const GrVkTextureInfo* backend = reinterpret_cast<const GrVkTextureInfo*>(id);
if (backend && backend->fImage && backend->fAlloc) {
VkMemoryRequirements req;
@@ -822,14 +848,17 @@ bool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const {
}
void GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) {
- GrVkImage::Resource* backend = reinterpret_cast<GrVkImage::Resource*>(id);
+ const GrVkTextureInfo* backend = reinterpret_cast<const GrVkTextureInfo*>(id);
if (backend) {
if (!abandon) {
- backend->unref(this);
- } else {
- backend->unrefAndAbandon();
+ // something in the command buffer may still be using this, so force submit
+ this->submitCommandBuffer(kForce_SyncQueue);
+
+ VK_CALL(FreeMemory(this->device(), backend->fAlloc, nullptr));
+ VK_CALL(DestroyImage(this->device(), backend->fImage, nullptr));
}
+ delete backend;
}
}
diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp
index ee45aa30e8..7ff7f26d42 100644
--- a/src/gpu/vk/GrVkRenderTarget.cpp
+++ b/src/gpu/vk/GrVkRenderTarget.cpp
@@ -15,6 +15,8 @@
#include "GrVkResourceProvider.h"
#include "GrVkUtil.h"
+#include "vk/GrVkTypes.h"
+
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
// We're virtually derived from GrSurface (via GrRenderTarget) so its
@@ -203,12 +205,29 @@ GrVkRenderTarget*
GrVkRenderTarget::CreateWrappedRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
- const GrVkImage::Resource* imageResource) {
- SkASSERT(imageResource);
+ const GrVkTextureInfo* info) {
+ SkASSERT(info);
+ // We can wrap a rendertarget without its allocation, as long as we don't take ownership
+ SkASSERT(VK_NULL_HANDLE != info->fImage);
+ SkASSERT(VK_NULL_HANDLE != info->fAlloc || kAdopted_LifeCycle != lifeCycle);
+
+ GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
+ ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
+
+ const GrVkImage::Resource* imageResource = new GrVkImage::Resource(info->fImage,
+ info->fAlloc,
+ flags);
+ if (!imageResource) {
+ return nullptr;
+ }
- // Note: we assume the caller will unref the imageResource
- // Create() will increment the refCount, and we'll unref when we're done with it
- return GrVkRenderTarget::Create(gpu, desc, lifeCycle, imageResource);
+ GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, desc, lifeCycle, imageResource);
+ if (rt) {
+ rt->fCurrentLayout = info->fImageLayout;
+ }
+ // Create() will increment the refCount of the image resource if it succeeds
+ imageResource->unref(gpu);
+ return rt;
}
bool GrVkRenderTarget::completeStencilAttachment() {
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index b4d72eac73..21c5788aa1 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -20,6 +20,8 @@ class GrVkGpu;
class GrVkImageView;
class GrVkStencilAttachment;
+struct GrVkTextureInfo;
+
#ifdef SK_BUILD_FOR_WIN
// Windows gives bogus warnings about inheriting asTexture/asRenderTarget via dominance.
#pragma warning(push)
@@ -34,7 +36,7 @@ public:
static GrVkRenderTarget* CreateWrappedRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
- const GrVkImage::Resource* resource);
+ const GrVkTextureInfo*);
~GrVkRenderTarget() override;
diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp
index 5c4c3bd6c7..a6a89df37a 100644
--- a/src/gpu/vk/GrVkTexture.cpp
+++ b/src/gpu/vk/GrVkTexture.cpp
@@ -10,6 +10,8 @@
#include "GrVkImageView.h"
#include "GrVkUtil.h"
+#include "vk/GrVkTypes.h"
+
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
@@ -75,12 +77,29 @@ GrVkTexture* GrVkTexture::CreateNewTexture(GrVkGpu* gpu, const GrSurfaceDesc& de
GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
VkFormat format,
- const GrVkImage::Resource* imageResource) {
- SkASSERT(imageResource);
+ const GrVkTextureInfo* info) {
+ SkASSERT(info);
+ // Wrapped textures require both image and allocation (because they can be mapped)
+ SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
+
+ GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
+ ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
+
+ const GrVkImage::Resource* imageResource = new GrVkImage::Resource(info->fImage,
+ info->fAlloc,
+ flags);
+ if (!imageResource) {
+ return nullptr;
+ }
- // Note: we assume the caller will unref the imageResource
- // Create() will increment the refCount, and we'll unref when we're done with it
- return Create(gpu, desc, lifeCycle, format, imageResource);
+ GrVkTexture* texture = Create(gpu, desc, lifeCycle, format, imageResource);
+ if (texture) {
+ texture->fCurrentLayout = info->fImageLayout;
+ }
+ // Create() will increment the refCount of the image resource if it succeeds
+ imageResource->unref(gpu);
+
+ return texture;
}
GrVkTexture::~GrVkTexture() {
diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h
index 5e31c9da4b..48ec7305e4 100644
--- a/src/gpu/vk/GrVkTexture.h
+++ b/src/gpu/vk/GrVkTexture.h
@@ -14,6 +14,7 @@
class GrVkGpu;
class GrVkImageView;
+struct GrVkTextureInfo;
class GrVkTexture : public GrTexture, public virtual GrVkImage {
public:
@@ -21,10 +22,9 @@ public:
GrGpuResource::LifeCycle,
const GrVkImage::ImageDesc&);
-
static GrVkTexture* CreateWrappedTexture(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
- VkFormat, const GrVkImage::Resource*);
+ VkFormat, const GrVkTextureInfo*);
~GrVkTexture() override;
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.cpp b/src/gpu/vk/GrVkTextureRenderTarget.cpp
index 79ba90481e..fa9327c788 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.cpp
+++ b/src/gpu/vk/GrVkTextureRenderTarget.cpp
@@ -12,6 +12,8 @@
#include "GrVkImageView.h"
#include "GrVkUtil.h"
+#include "vk/GrVkTypes.h"
+
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
GrVkTextureRenderTarget*
@@ -140,11 +142,30 @@ GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
VkFormat format,
- GrVkImage::Resource* imageRsrc) {
- SkASSERT(imageRsrc);
+ const GrVkTextureInfo* info) {
+ SkASSERT(info);
+ // Wrapped textures require both image and allocation (because they can be mapped)
+ SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc);
+
+ GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
+ ? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
+
+ const GrVkImage::Resource* imageResource = new GrVkImage::Resource(info->fImage,
+ info->fAlloc,
+ flags);
+ if (!imageResource) {
+ return nullptr;
+ }
+
+ GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
+ format, imageResource);
+ if (trt) {
+ trt->fCurrentLayout = info->fImageLayout;
+ }
+ // Create() will increment the refCount of the image resource if it succeeds
+ imageResource->unref(gpu);
+
+ return trt;
- // Note: we assume the caller will unref the imageResource
- // Create() will increment the refCount, and we'll unref when we're done with it
- return GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle, format, imageRsrc);
}
diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h
index 6e0d89968f..a7aff009d3 100644
--- a/src/gpu/vk/GrVkTextureRenderTarget.h
+++ b/src/gpu/vk/GrVkTextureRenderTarget.h
@@ -20,6 +20,7 @@
#endif
class GrVkImageView;
+struct GrVkTextureInfo;
class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget {
public:
@@ -31,7 +32,7 @@ public:
const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
VkFormat,
- GrVkImage::Resource*);
+ const GrVkTextureInfo*);
protected:
void onAbandon() override {