| Index: src/gpu/vk/GrVkGpu.cpp
|
| diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
|
| index 180ba3be66b85686d0a3c2e59b32b4f1c9af3e5f..16526f6613965fc3b126b3349c615bd1b59bb4b9 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;
|
| }
|
| }
|
|
|
|
|