1164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/*
2164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * Copyright 2015 Google Inc.
3164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel *
4164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * Use of this source code is governed by a BSD-style license that can be
5164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * found in the LICENSE file.
6164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel */
7164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
8164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkGpu.h"
9164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
10a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel#include "GrBackendSemaphore.h"
117ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel#include "GrBackendSurface.h"
12164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrContextOptions.h"
13164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGeometryProcessor.h"
14164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGpuResourceCacheAccess.h"
150e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel#include "GrMesh.h"
16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrPipeline.h"
17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrRenderTargetPriv.h"
18164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrSurfacePriv.h"
19164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrTexturePriv.h"
20164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
21164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkCommandBuffer.h"
22066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpuCommandBuffer.h"
23164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkImage.h"
24164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkIndexBuffer.h"
25164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkMemory.h"
26164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkPipeline.h"
2722281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel#include "GrVkPipelineState.h"
28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkRenderPass.h"
29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkResourceProvider.h"
306be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel#include "GrVkSemaphore.h"
31c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel#include "GrVkTexelBuffer.h"
32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h"
33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTextureRenderTarget.h"
34164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTransferBuffer.h"
35164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkVertexBuffer.h"
36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
37485c499a2797c1eb0e750fa4aaec57192799b424Matt Sarett#include "SkConvertPixels.h"
38900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth#include "SkMipMap.h"
39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
40164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vk/GrVkInterface.h"
41fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth#include "vk/GrVkTypes.h"
42164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
43b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#include "SkSLCompiler.h"
44b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
4544f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling#if !defined(SK_BUILD_FOR_WIN)
4644f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling#include <unistd.h>
4744f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling#endif // !defined(SK_BUILD_FOR_WIN)
4844f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling
49164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X)
50164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X)
51164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X)
52164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
53735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS
54d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverthVKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
55d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    VkDebugReportFlagsEXT       flags,
56d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    VkDebugReportObjectTypeEXT  objectType,
57d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    uint64_t                    object,
58d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    size_t                      location,
59d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    int32_t                     messageCode,
60d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    const char*                 pLayerPrefix,
61d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    const char*                 pMessage,
62d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    void*                       pUserData) {
63d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
64d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
65ce3fe23c04e93d2aa8d4c09c0c99088207edd509Jim Van Verth        return VK_TRUE; // skip further layers
66d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
67d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
68d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
69d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
70d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    } else {
71d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
72d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    }
73d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    return VK_FALSE;
74d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth}
75d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif
76d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth
77633b35657c964c32e7010b14bb2d396b4a764c52jvanverthGrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
78633b35657c964c32e7010b14bb2d396b4a764c52jvanverth                       GrContext* context) {
79dc0fcd41e75682a8bfd5e285d684461475226330bsalomon    const GrVkBackendContext* vkBackendContext =
80dc0fcd41e75682a8bfd5e285d684461475226330bsalomon        reinterpret_cast<const GrVkBackendContext*>(backendContext);
81633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    if (!vkBackendContext) {
82c1889823de68ffd2ef08b5c1969d41c98034ec6aBrian Salomon        return nullptr;
83633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    } else {
84633b35657c964c32e7010b14bb2d396b4a764c52jvanverth        vkBackendContext->ref();
85164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
86164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
87fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel    if (!vkBackendContext->fInterface->validate(vkBackendContext->fExtensions)) {
88fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel        return nullptr;
89fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel    }
90fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel
91633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    return new GrVkGpu(context, options, vkBackendContext);
92164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
93164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
94164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
95164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
969d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanaryGrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
97633b35657c964c32e7010b14bb2d396b4a764c52jvanverth                 const GrVkBackendContext* backendCtx)
98164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    : INHERITED(context)
99633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    , fDevice(backendCtx->fDevice)
100633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    , fQueue(backendCtx->fQueue)
1018606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    , fResourceProvider(this)
1028606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    , fDisconnected(false) {
103633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fBackendContext.reset(backendCtx);
104164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
105735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS
106419ca64f0f800dc098369b5aa5a604acd017b240brianosman    fCallback = VK_NULL_HANDLE;
107fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth    if (backendCtx->fExtensions & kEXT_debug_report_GrVkExtensionFlag) {
108fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth        // Setup callback creation information
109d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        VkDebugReportCallbackCreateInfoEXT callbackCreateInfo;
110d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
111d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.pNext = nullptr;
112d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
113ef0c10cffefef90646ff2e238d7c2d82247a0370egdaniel                                   VK_DEBUG_REPORT_WARNING_BIT_EXT |
114d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth                                   //VK_DEBUG_REPORT_INFORMATION_BIT_EXT |
115d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth                                   //VK_DEBUG_REPORT_DEBUG_BIT_EXT |
116b4aa36211ca66ef127ac2954108742af1ead5082egdaniel                                   VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
117d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.pfnCallback = &DebugReportCallback;
118d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.pUserData = nullptr;
119d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth
120fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth        // Register the callback
121a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth        GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateDebugReportCallbackEXT(
122a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth                            backendCtx->fInstance, &callbackCreateInfo, nullptr, &fCallback));
123d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    }
124d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif
125633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
126b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas    fCompiler = new SkSL::Compiler();
127633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
128fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth    fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice,
129c5ec1408298510410270ea67e895570ccfa76e54egdaniel                               backendCtx->fFeatures, backendCtx->fExtensions));
130633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fCaps.reset(SkRef(fVkCaps.get()));
131633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
132633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps));
133633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
134633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    const VkCommandPoolCreateInfo cmdPoolInfo = {
1357ec92413307c9da43c013d1e4e15716a44059810jvanverth        VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
1367ec92413307c9da43c013d1e4e15716a44059810jvanverth        nullptr,                                         // pNext
1377ec92413307c9da43c013d1e4e15716a44059810jvanverth        VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
1387ec92413307c9da43c013d1e4e15716a44059810jvanverth        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // CmdPoolCreateFlags
1397ec92413307c9da43c013d1e4e15716a44059810jvanverth        backendCtx->fGraphicsQueueIndex,                 // queueFamilyIndex
140633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    };
1419d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateCommandPool(fDevice, &cmdPoolInfo, nullptr,
142633b35657c964c32e7010b14bb2d396b4a764c52jvanverth                                                               &fCmdPool));
143633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
144633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    // must call this after creating the CommandPool
145633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fResourceProvider.init();
1467ec92413307c9da43c013d1e4e15716a44059810jvanverth    fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer();
147633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    SkASSERT(fCurrentCmdBuffer);
148633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fCurrentCmdBuffer->begin(this);
1496b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth
1506b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    // set up our heaps
1516b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kLinearImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024));
1524f7d97c16fd159f72d2ad9c105542e2c6c097ad6Greg Daniel    fHeaps[kOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 64*1024*1024));
1536b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kSmallOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 2*1024*1024));
1546b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kVertexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1556b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kIndexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1564c6e47a8a827077e36fa5feb4ab5ac7435d8276bjvanverth    fHeaps[kUniformBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 256*1024));
157c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel    fHeaps[kTexelBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1586b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kCopyReadBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1596b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kCopyWriteBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024));
160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1628606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Danielvoid GrVkGpu::destroyResources() {
1638606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    if (fCurrentCmdBuffer) {
1648606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fCurrentCmdBuffer->end(this);
1658606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fCurrentCmdBuffer->unref(this);
1668606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    }
167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // wait for all commands to finish
169ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth    fResourceProvider.checkCommandBuffers();
17009557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    VkResult res = VK_CALL(QueueWaitIdle(fQueue));
171f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel
172f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel    // On windows, sometimes calls to QueueWaitIdle return before actually signalling the fences
173f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel    // on the command buffers even though they have completed. This causes an assert to fire when
174f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel    // destroying the command buffers. Currently this ony seems to happen on windows, so we add a
17509557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    // sleep to make sure the fence signals.
176f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#ifdef SK_DEBUG
17780a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    if (this->vkCaps().mustSleepOnTearDown()) {
178f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#if defined(SK_BUILD_FOR_WIN)
17980a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel        Sleep(10); // In milliseconds
180f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#else
18180a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel        sleep(1);  // In seconds
182f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif
18380a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    }
184f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif
185f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel
186be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#ifdef SK_DEBUG
1878a8668b4721097de657ad8b30d45f60f62433c6fGreg Daniel    SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res);
188be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#endif
1899d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
1906be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
1916be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel        fSemaphoresToWaitOn[i]->unref(this);
1926be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    }
1936be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fSemaphoresToWaitOn.reset();
1946be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
195a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
196a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        fSemaphoresToSignal[i]->unref(this);
197a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    }
198a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    fSemaphoresToSignal.reset();
199a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel
200a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel
201bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    fCopyManager.destroyResources(this);
202bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel
20309557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    // must call this just before we destroy the command pool and VkDevice
20409557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    fResourceProvider.destroyResources(VK_ERROR_DEVICE_LOST == res);
205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
2068606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    if (fCmdPool != VK_NULL_HANDLE) {
2078606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr));
2088606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    }
209633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
210735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS
211a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth    if (fCallback) {
212a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth        VK_CALL(DestroyDebugReportCallbackEXT(fBackendContext->fInstance, fCallback, nullptr));
213a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth    }
214d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif
2158606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel
2168606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel}
2178606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel
2188606cf836e2cdbabe7fd917b7cba88b6673c9175Greg DanielGrVkGpu::~GrVkGpu() {
2198606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    if (!fDisconnected) {
2208606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        this->destroyResources();
2218606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    }
2228606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    delete fCompiler;
2238606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel}
2248606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel
2258606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel
2268606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Danielvoid GrVkGpu::disconnect(DisconnectType type) {
2278606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    INHERITED::disconnect(type);
2288606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    if (!fDisconnected) {
2298606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        if (DisconnectType::kCleanup == type) {
2308606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            this->destroyResources();
2318606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        } else {
2328606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            fCurrentCmdBuffer->unrefAndAbandon();
2338606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
2348606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel                fSemaphoresToWaitOn[i]->unrefAndAbandon();
2358606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            }
236a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
237a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                fSemaphoresToSignal[i]->unrefAndAbandon();
238a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel            }
2398606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            fCopyManager.abandonResources();
2408606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel
2418606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            // must call this just before we destroy the command pool and VkDevice
2428606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel            fResourceProvider.abandonResources();
2438606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        }
2448606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fSemaphoresToWaitOn.reset();
245a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        fSemaphoresToSignal.reset();
2468606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel#ifdef SK_ENABLE_VK_LAYERS
2478606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fCallback = VK_NULL_HANDLE;
2488606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel#endif
2498606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fCurrentCmdBuffer = nullptr;
2508606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fCmdPool = VK_NULL_HANDLE;
2518606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel        fDisconnected = true;
2528606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel    }
253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel///////////////////////////////////////////////////////////////////////////////
256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
2579cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpuCommandBuffer* GrVkGpu::createCommandBuffer(
2589cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
2599cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) {
260c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    return new GrVkGpuCommandBuffer(this, colorInfo, stencilInfo);
261066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
262066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
263a5cb781c17c09e01655defd0a84b431996b6a015Greg Danielvoid GrVkGpu::submitCommandBuffer(SyncQueue sync) {
264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->end(this);
266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
267a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    fCurrentCmdBuffer->submitToQueue(this, fQueue, sync, fSemaphoresToSignal, fSemaphoresToWaitOn);
2686be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
2696be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
2706be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel        fSemaphoresToWaitOn[i]->unref(this);
2716be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    }
2726be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fSemaphoresToWaitOn.reset();
273a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
274a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        fSemaphoresToSignal[i]->unref(this);
275a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    }
276a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    fSemaphoresToSignal.reset();
2776be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fResourceProvider.checkCommandBuffers();
279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Release old command buffer and create a new one
281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->unref(this);
2827ec92413307c9da43c013d1e4e15716a44059810jvanverth    fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer();
283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->begin(this);
286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel///////////////////////////////////////////////////////////////////////////////
2891bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdaltonGrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern accessPattern,
2901bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton                                  const void* data) {
2911bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    GrBuffer* buff;
292397536cabe12a9936659870dd220c869789424bacdalton    switch (type) {
293397536cabe12a9936659870dd220c869789424bacdalton        case kVertex_GrBufferType:
294397536cabe12a9936659870dd220c869789424bacdalton            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
295397536cabe12a9936659870dd220c869789424bacdalton                     kStatic_GrAccessPattern == accessPattern);
2961bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
297e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
298397536cabe12a9936659870dd220c869789424bacdalton        case kIndex_GrBufferType:
299397536cabe12a9936659870dd220c869789424bacdalton            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
300397536cabe12a9936659870dd220c869789424bacdalton                     kStatic_GrAccessPattern == accessPattern);
3011bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
302e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
303397536cabe12a9936659870dd220c869789424bacdalton        case kXferCpuToGpu_GrBufferType:
3042e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
3052e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                     kStream_GrAccessPattern == accessPattern);
3061bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type);
307e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
308397536cabe12a9936659870dd220c869789424bacdalton        case kXferGpuToCpu_GrBufferType:
3092e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
3102e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                     kStream_GrAccessPattern == accessPattern);
3111bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type);
312e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
313c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel        case kTexel_GrBufferType:
3146b65b98996ebc0a511aa46042607a291e6836bedChris Dalton            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
3156b65b98996ebc0a511aa46042607a291e6836bedChris Dalton                     kStatic_GrAccessPattern == accessPattern);
3166b65b98996ebc0a511aa46042607a291e6836bedChris Dalton            buff = GrVkTexelBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
317c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel            break;
318c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel        case kDrawIndirect_GrBufferType:
319c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel            SkFAIL("DrawIndirect Buffers not supported  in vulkan backend.");
320c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel            return nullptr;
321397536cabe12a9936659870dd220c869789424bacdalton        default:
322397536cabe12a9936659870dd220c869789424bacdalton            SkFAIL("Unknown buffer type.");
323397536cabe12a9936659870dd220c869789424bacdalton            return nullptr;
324397536cabe12a9936659870dd220c869789424bacdalton    }
3251bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    if (data && buff) {
3261bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton        buff->updateData(data, size);
3271bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    }
3281bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    return buff;
329164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
330164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
331164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
332164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
333164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                   GrPixelConfig srcConfig, DrawPreference* drawPreference,
334164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                   WritePixelTempDrawInfo* tempDrawInfo) {
3354583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    GrRenderTarget* renderTarget = dstSurface->asRenderTarget();
3364583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
3374583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    // Start off assuming no swizzling
3384583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
3394583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fWriteConfig = srcConfig;
3404583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
3414583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    // These settings we will always want if a temp draw is performed. Initially set the config
3424583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    // to srcConfig, though that may be modified if we decide to do a R/B swap
3434583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
3444583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
3454583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
3464583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
3474583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
3484583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
3494583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
350d66110f5972169dbcda8932c3a9a001adff23df4egdaniel    if (dstSurface->config() == srcConfig) {
35133910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        // We only support writing pixels to textures. Forcing a draw lets us write to pure RTs.
35233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        if (!dstSurface->asTexture()) {
35333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
35433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        }
35533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target.
35633910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        if (renderTarget && renderTarget->numColorSamples() > 1) {
35733910297e032b9af4336bc146c7fbb0f35918de9Brian Osman            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
35833910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        }
359d66110f5972169dbcda8932c3a9a001adff23df4egdaniel        return true;
360d66110f5972169dbcda8932c3a9a001adff23df4egdaniel    }
361d66110f5972169dbcda8932c3a9a001adff23df4egdaniel
36233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    // Any config change requires a draw
36333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
3644583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
36533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
3664583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
36733910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) {
36833910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
36933910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
37033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        tempDrawInfo->fWriteConfig = dstSurface->config();
371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
37233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    return true;
373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
374164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
375164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onWritePixels(GrSurface* surface,
376164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            int left, int top, int width, int height,
377a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon                            GrPixelConfig config,
378590533f066035a48df9f78395a80314b559f4714Robert Phillips                            const GrMipLevel texels[], int mipLevelCount) {
379164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture());
380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!vkTex) {
381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
382164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
383164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
384900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Make sure we have at least the base level
385590533f066035a48df9f78395a80314b559f4714Robert Phillips    if (!mipLevelCount || !texels[0].fPixels) {
38603509eafa3e25819ff69f4d4f339d46264820c38jvanverth        return false;
38703509eafa3e25819ff69f4d4f339d46264820c38jvanverth    }
388a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon
389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool success = false;
39592de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips    bool linearTiling = vkTex->isLinearTiled();
39692de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips    if (linearTiling) {
397590533f066035a48df9f78395a80314b559f4714Robert Phillips        if (mipLevelCount > 1) {
39892de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips            SkDebugf("Can't upload mipmap data to linear tiled texture");
39992de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips            return false;
40092de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips        }
40192de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips        if (VK_IMAGE_LAYOUT_PREINITIALIZED != vkTex->currentLayout()) {
40292de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips            // Need to change the layout to general in order to perform a host write
40392de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips            vkTex->setImageLayout(this,
40492de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips                                  VK_IMAGE_LAYOUT_GENERAL,
40592de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips                                  VK_ACCESS_HOST_WRITE_BIT,
40692de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips                                  VK_PIPELINE_STAGE_HOST_BIT,
40792de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips                                  false);
40892de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips            this->submitCommandBuffer(kForce_SyncQueue);
40992de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips        }
41092de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips        success = this->uploadTexDataLinear(vkTex, left, top, width, height, config,
411590533f066035a48df9f78395a80314b559f4714Robert Phillips                                            texels[0].fPixels, texels[0].fRowBytes);
412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    } else {
41392de631edd3eb9b3430332d1f1d566e903ea2ea9Robert Phillips        int currentMipLevels = vkTex->texturePriv().maxMipMapLevel() + 1;
414590533f066035a48df9f78395a80314b559f4714Robert Phillips        if (mipLevelCount > currentMipLevels) {
415590533f066035a48df9f78395a80314b559f4714Robert Phillips            if (!vkTex->reallocForMipmap(this, mipLevelCount)) {
416900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                return false;
417900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            }
418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
419590533f066035a48df9f78395a80314b559f4714Robert Phillips        success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config,
420590533f066035a48df9f78395a80314b559f4714Robert Phillips                                             texels, mipLevelCount);
421164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
4224583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
423900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    return success;
424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
425164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
4262e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verthbool GrVkGpu::onTransferPixels(GrTexture* texture,
4272e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                               int left, int top, int width, int height,
4282e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                               GrPixelConfig config, GrBuffer* transferBuffer,
4292e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                               size_t bufferOffset, size_t rowBytes) {
4302e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    // Vulkan only supports 4-byte aligned offsets
4312e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    if (SkToBool(bufferOffset & 0x2)) {
4322e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth        return false;
4332e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    }
4342e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    GrVkTexture* vkTex = static_cast<GrVkTexture*>(texture);
4352e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    if (!vkTex) {
4362e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth        return false;
4372e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    }
4382e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    GrVkTransferBuffer* vkBuffer = static_cast<GrVkTransferBuffer*>(transferBuffer);
4392e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    if (!vkBuffer) {
4402e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth        return false;
4412e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    }
4422e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
4432e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
4442e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    if (GrPixelConfigIsSRGB(texture->config()) != GrPixelConfigIsSRGB(config)) {
4452e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth        return false;
4462e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    }
4472e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
448660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel    SkDEBUGCODE(
449660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
450660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
451660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        SkASSERT(bounds.contains(subRect));
452660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel    )
4532e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    size_t bpp = GrBytesPerPixel(config);
4542e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    if (rowBytes == 0) {
4552e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth        rowBytes = bpp*width;
4562e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    }
4572e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
4582e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    // Set up copy region
4592e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    VkBufferImageCopy region;
4602e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    memset(&region, 0, sizeof(VkBufferImageCopy));
4612e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    region.bufferOffset = bufferOffset;
4622e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    region.bufferRowLength = (uint32_t)(rowBytes/bpp);
4632e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    region.bufferImageHeight = 0;
4642e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
4652e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    region.imageOffset = { left, top, 0 };
4662e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
4672e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
4682e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    // Change layout of our target so it can be copied to
4692e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    vkTex->setImageLayout(this,
4702e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4712e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                          VK_ACCESS_TRANSFER_WRITE_BIT,
4722e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                          VK_PIPELINE_STAGE_TRANSFER_BIT,
4732e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                          false);
4742e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
4752e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    // Copy the buffer to the image
4762e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    fCurrentCmdBuffer->copyBufferToImage(this,
4772e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                                         vkBuffer,
4782e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                                         vkTex,
4792e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4802e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                                         1,
4812e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth                                         &region);
4822e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
4832e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    vkTex->texturePriv().dirtyMipMaps(true);
4842e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth    return true;
4852e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth}
4862e5eaf022e9389b1382cc856fcd7a8e90a078e13Jim Van Verth
487bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Danielvoid GrVkGpu::resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect,
4884bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                           const SkIPoint& dstPoint) {
4894bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkASSERT(dst);
4904bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage());
4914bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
492fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) {
493fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel        this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue);
494fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    }
495fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel
4964bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // Flip rect if necessary
4974bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkIRect srcVkRect = srcRect;
4984bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    int32_t dstY = dstPoint.fY;
4994bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
5004bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
5014bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin());
5024bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcVkRect.fTop = src->height() - srcRect.fBottom;
5034bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcVkRect.fBottom = src->height() - srcRect.fTop;
5044bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        dstY = dst->height() - dstPoint.fY - srcVkRect.height();
5054bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
5064bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
5074bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    VkImageResolve resolveInfo;
5084bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
5094bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
5104bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
5114bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.dstOffset = { dstPoint.fX, dstY, 0 };
5124bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 };
5134bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
514bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    GrVkImage* dstImage;
515bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    GrRenderTarget* dstRT = dst->asRenderTarget();
516bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    if (dstRT) {
517bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT);
518bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel        dstImage = vkRT;
519bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    } else {
520bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel        SkASSERT(dst->asTexture());
521bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel        dstImage = static_cast<GrVkTexture*>(dst->asTexture());
522bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    }
523bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    dstImage->setImageLayout(this,
524bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
525bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel                             VK_ACCESS_TRANSFER_WRITE_BIT,
526bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel                             VK_PIPELINE_STAGE_TRANSFER_BIT,
527bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel                             false);
5284bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
5294bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    src->msaaImage()->setImageLayout(this,
5304bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5314bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     VK_ACCESS_TRANSFER_READ_BIT,
5324bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     VK_PIPELINE_STAGE_TRANSFER_BIT,
5334bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     false);
5344bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
535bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    fCurrentCmdBuffer->resolveImage(this, *src->msaaImage(), *dstImage, 1, &resolveInfo);
5364bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel}
5374bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
53869d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Danielvoid GrVkGpu::internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit) {
53966933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (target->needsResolve()) {
54066933552f1723c4a2b248711ab3d43921401e8e6egdaniel        SkASSERT(target->numColorSamples() > 1);
54152ad25151a1c7d1ac3872971f56adf15200c437eegdaniel        GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target);
54252ad25151a1c7d1ac3872971f56adf15200c437eegdaniel        SkASSERT(rt->msaaImage());
54369d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel
5444bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        const SkIRect& srcRect = rt->getResolveRect();
54552ad25151a1c7d1ac3872971f56adf15200c437eegdaniel
546bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel        this->resolveImage(target, rt, srcRect, SkIPoint::Make(srcRect.fLeft, srcRect.fTop));
54752ad25151a1c7d1ac3872971f56adf15200c437eegdaniel
54852ad25151a1c7d1ac3872971f56adf15200c437eegdaniel        rt->flagAsResolved();
54969d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel
55069d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel        if (requiresSubmit) {
55169d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel            this->submitCommandBuffer(kSkip_SyncQueue);
55269d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel        }
55352ad25151a1c7d1ac3872971f56adf15200c437eegdaniel    }
55452ad25151a1c7d1ac3872971f56adf15200c437eegdaniel}
55552ad25151a1c7d1ac3872971f56adf15200c437eegdaniel
556900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex,
557900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  int left, int top, int width, int height,
558900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  GrPixelConfig dataConfig,
559900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  const void* data,
560900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  size_t rowBytes) {
561164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(data);
562900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(tex->isLinearTiled());
563164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
564660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel    SkDEBUGCODE(
565660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
566660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        SkIRect bounds = SkIRect::MakeWH(tex->width(), tex->height());
567660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        SkASSERT(bounds.contains(subRect));
568660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel    )
569164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    size_t bpp = GrBytesPerPixel(dataConfig);
570164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    size_t trimRowBytes = width * bpp;
571660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel    if (!rowBytes) {
572660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        rowBytes = trimRowBytes;
573660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel    }
574164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
575900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == tex->currentLayout() ||
576900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth             VK_IMAGE_LAYOUT_GENERAL == tex->currentLayout());
577900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    const VkImageSubresource subres = {
578900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        VK_IMAGE_ASPECT_COLOR_BIT,
579900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        0,  // mipLevel
580900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        0,  // arraySlice
581900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    };
582900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    VkSubresourceLayout layout;
583900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    VkResult err;
584900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
585900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    const GrVkInterface* interface = this->vkInterface();
586900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
587900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice,
588b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                                    tex->image(),
589900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                    &subres,
590900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                    &layout));
591900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
592d1eaf49e0b8b2776b1558ffd3ee1d3d9f9592b6bBrian Salomon    int texTop = kBottomLeft_GrSurfaceOrigin == tex->origin() ? tex->height() - top - height : top;
5931e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    const GrVkAlloc& alloc = tex->alloc();
5941e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    VkDeviceSize offset = alloc.fOffset + texTop*layout.rowPitch + left*bpp;
595900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    VkDeviceSize size = height*layout.rowPitch;
596900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    void* mapPtr;
5971e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    err = GR_VK_CALL(interface, MapMemory(fDevice, alloc.fMemory, offset, size, 0, &mapPtr));
598900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    if (err) {
599900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        return false;
600900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
601164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
602d1eaf49e0b8b2776b1558ffd3ee1d3d9f9592b6bBrian Salomon    if (kBottomLeft_GrSurfaceOrigin == tex->origin()) {
603900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        // copy into buffer by rows
604900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        const char* srcRow = reinterpret_cast<const char*>(data);
605900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*layout.rowPitch;
606900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        for (int y = 0; y < height; y++) {
607900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            memcpy(dstRow, srcRow, trimRowBytes);
608900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            srcRow += rowBytes;
609900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            dstRow -= layout.rowPitch;
610900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        }
611900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    } else {
612cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett        SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, trimRowBytes,
613cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett                     height);
614900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
615164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
6169d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkMemory::FlushMappedAlloc(this, alloc);
6171e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    GR_VK_CALL(interface, UnmapMemory(fDevice, alloc.fMemory));
618900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
619900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    return true;
620900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth}
621900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
622900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
623a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth                                   int left, int top, int width, int height,
624a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth                                   GrPixelConfig dataConfig,
625590533f066035a48df9f78395a80314b559f4714Robert Phillips                                   const GrMipLevel texels[], int mipLevelCount) {
626900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(!tex->isLinearTiled());
627900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // The assumption is either that we have no mipmaps, or that our rect is the entire texture
628590533f066035a48df9f78395a80314b559f4714Robert Phillips    SkASSERT(1 == mipLevelCount ||
629900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth             (0 == left && 0 == top && width == tex->width() && height == tex->height()));
630900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
631dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel    // We assume that if the texture has mip levels, we either upload to all the levels or just the
632dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel    // first.
633590533f066035a48df9f78395a80314b559f4714Robert Phillips    SkASSERT(1 == mipLevelCount || mipLevelCount == (tex->texturePriv().maxMipMapLevel() + 1));
634dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel
635900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    if (width == 0 || height == 0) {
636900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        return false;
637900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
638900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
639d1eaf49e0b8b2776b1558ffd3ee1d3d9f9592b6bBrian Salomon    SkASSERT(this->caps()->isConfigTexturable(tex->config()));
640900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    size_t bpp = GrBytesPerPixel(dataConfig);
641900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
642900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // texels is const.
643c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // But we may need to adjust the fPixels ptr based on the copyRect, or fRowBytes.
644c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // Because of this we need to make a non-const shallow copy of texels.
6450f9927712ad8360e45fa20f9726ad14c4b50a85fRobert Phillips    SkAutoTMalloc<GrMipLevel> texelsShallowCopy;
6460f9927712ad8360e45fa20f9726ad14c4b50a85fRobert Phillips
6470f9927712ad8360e45fa20f9726ad14c4b50a85fRobert Phillips    if (mipLevelCount) {
6480f9927712ad8360e45fa20f9726ad14c4b50a85fRobert Phillips        texelsShallowCopy.reset(mipLevelCount);
6490f9927712ad8360e45fa20f9726ad14c4b50a85fRobert Phillips        memcpy(texelsShallowCopy.get(), texels, mipLevelCount*sizeof(GrMipLevel));
6500f9927712ad8360e45fa20f9726ad14c4b50a85fRobert Phillips    }
651900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
652590533f066035a48df9f78395a80314b559f4714Robert Phillips    for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; ++currentMipLevel) {
653c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        SkASSERT(texelsShallowCopy[currentMipLevel].fPixels);
654900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
655900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
656900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Determine whether we need to flip when we copy into the buffer
657590533f066035a48df9f78395a80314b559f4714Robert Phillips    bool flipY = (kBottomLeft_GrSurfaceOrigin == tex->origin() && mipLevelCount);
658900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
659590533f066035a48df9f78395a80314b559f4714Robert Phillips    SkTArray<size_t> individualMipOffsets(mipLevelCount);
660c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    individualMipOffsets.push_back(0);
661c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    size_t combinedBufferSize = width * bpp * height;
662c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    int currentWidth = width;
663c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    int currentHeight = height;
664468fd63760283c56630d752583b234f44ab03024Greg Daniel    // The alignment must be at least 4 bytes and a multiple of the bytes per pixel of the image
665468fd63760283c56630d752583b234f44ab03024Greg Daniel    // config. This works with the assumption that the bytes in pixel config is always a power of 2.
666468fd63760283c56630d752583b234f44ab03024Greg Daniel    SkASSERT((bpp & (bpp - 1)) == 0);
667468fd63760283c56630d752583b234f44ab03024Greg Daniel    const size_t alignmentMask = 0x3 | (bpp - 1);
668590533f066035a48df9f78395a80314b559f4714Robert Phillips    for (int currentMipLevel = 1; currentMipLevel < mipLevelCount; currentMipLevel++) {
669c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentWidth = SkTMax(1, currentWidth/2);
670c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentHeight = SkTMax(1, currentHeight/2);
671660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel
672900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        const size_t trimmedSize = currentWidth * bpp * currentHeight;
673468fd63760283c56630d752583b234f44ab03024Greg Daniel        const size_t alignmentDiff = combinedBufferSize & alignmentMask;
674468fd63760283c56630d752583b234f44ab03024Greg Daniel        if (alignmentDiff != 0) {
675468fd63760283c56630d752583b234f44ab03024Greg Daniel           combinedBufferSize += alignmentMask - alignmentDiff + 1;
676468fd63760283c56630d752583b234f44ab03024Greg Daniel        }
677900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        individualMipOffsets.push_back(combinedBufferSize);
678900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        combinedBufferSize += trimmedSize;
679900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
680900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
681900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // allocate buffer to hold our mip data
682900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    GrVkTransferBuffer* transferBuffer =
683900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                   GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuffer::kCopyRead_Type);
684c04f8450d4701ea2b4494c3cd12f5f972d6d5b54Forrest Reiling    if(!transferBuffer)
685c04f8450d4701ea2b4494c3cd12f5f972d6d5b54Forrest Reiling        return false;
686900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
687900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    char* buffer = (char*) transferBuffer->map();
688590533f066035a48df9f78395a80314b559f4714Robert Phillips    SkTArray<VkBufferImageCopy> regions(mipLevelCount);
689900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
690c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    currentWidth = width;
691c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    currentHeight = height;
692a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel    int layerHeight = tex->height();
693590533f066035a48df9f78395a80314b559f4714Robert Phillips    for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
694590533f066035a48df9f78395a80314b559f4714Robert Phillips        SkASSERT(1 == mipLevelCount || currentHeight == layerHeight);
695900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        const size_t trimRowBytes = currentWidth * bpp;
696660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel        const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes ?
697660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel                                texelsShallowCopy[currentMipLevel].fRowBytes :
698660cc9910f636b6092f5f2ee36567999f83fb648Greg Daniel                                trimRowBytes;
699900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
700900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        // copy data into the buffer, skipping the trailing bytes
701900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        char* dst = buffer + individualMipOffsets[currentMipLevel];
702c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels;
703900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        if (flipY) {
704900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            src += (currentHeight - 1) * rowBytes;
705900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            for (int y = 0; y < currentHeight; y++) {
706900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                memcpy(dst, src, trimRowBytes);
707900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                src -= rowBytes;
708900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                dst += trimRowBytes;
709164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            }
710164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        } else {
711900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, currentHeight);
712164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
713164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
714900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        VkBufferImageCopy& region = regions.push_back();
715164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        memset(&region, 0, sizeof(VkBufferImageCopy));
716db37909347d034943bd6b0922710a94c6c6ea572jvanverth        region.bufferOffset = transferBuffer->offset() + individualMipOffsets[currentMipLevel];
717900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        region.bufferRowLength = currentWidth;
718900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        region.bufferImageHeight = currentHeight;
719cf942c4ef750712b624867cbb2217c14857db3c6bsalomon        region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMipLevel), 0, 1 };
720a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel        region.imageOffset = { left, flipY ? layerHeight - top - currentHeight : top, 0 };
721900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 };
7224583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
723c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentWidth = SkTMax(1, currentWidth/2);
724c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentHeight = SkTMax(1, currentHeight/2);
725a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel        layerHeight = currentHeight;
726900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
727164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
7289d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    // no need to flush non-coherent memory, unmap will do that for us
729900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    transferBuffer->unmap();
730164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
731900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Change layout of our target so it can be copied to
732900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    tex->setImageLayout(this,
733900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
73450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                        VK_ACCESS_TRANSFER_WRITE_BIT,
73550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                        VK_PIPELINE_STAGE_TRANSFER_BIT,
736900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                        false);
737900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
738900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Copy the buffer to the image
739900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    fCurrentCmdBuffer->copyBufferToImage(this,
740900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         transferBuffer,
741900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         tex,
742900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
743900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         regions.count(),
744900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         regions.begin());
745900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    transferBuffer->unref();
746590533f066035a48df9f78395a80314b559f4714Robert Phillips    if (1 == mipLevelCount) {
747dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel       tex->texturePriv().dirtyMipMaps(true);
748dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel    }
749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
750164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return true;
751164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
75467d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillipssk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
755590533f066035a48df9f78395a80314b559f4714Robert Phillips                                          const GrMipLevel texels[], int mipLevelCount) {
756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkFormat pixelFormat;
759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) {
760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
762164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
763164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!fVkCaps->isConfigTexturable(desc.fConfig)) {
764164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
765164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
766164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
7670a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    if (renderTarget && !fVkCaps->isConfigRenderable(desc.fConfig, false)) {
7680a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        return nullptr;
7690a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    }
7700a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel
771164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
772164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (renderTarget) {
773164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
774164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
775164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
776164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and
777164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we
778164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // will be using this texture in some copy or not. Also this assumes, as is the current case,
77962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // that all render targets in vulkan are also textures. If we change this practice of setting
780164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // both bits, we must make sure to set the destination bit if we are uploading srcData to the
781164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // texture.
782164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
783164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
784164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is
78562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // requested, this ImageDesc describes the resolved texture. Therefore we always have samples set
786164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // to 1.
787590533f066035a48df9f78395a80314b559f4714Robert Phillips    int mipLevels = !mipLevelCount ? 1 : mipLevelCount;
788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkImage::ImageDesc imageDesc;
789164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fImageType = VK_IMAGE_TYPE_2D;
790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fFormat = pixelFormat;
791164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fWidth = desc.fWidth;
792164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fHeight = desc.fHeight;
7937128fdd82d7c4bd5e17dd5a2ebb6135904335746Brian Salomon    imageDesc.fLevels = mipLevels;
794164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fSamples = 1;
7957128fdd82d7c4bd5e17dd5a2ebb6135904335746Brian Salomon    imageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
796164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fUsageFlags = usageFlags;
7977128fdd82d7c4bd5e17dd5a2ebb6135904335746Brian Salomon    imageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
798164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
79967d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillips    sk_sp<GrVkTexture> tex;
800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (renderTarget) {
8012e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, desc,
802164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                    imageDesc);
803164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    } else {
8042e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc);
805164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
806164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
807164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!tex) {
808164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
809164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
810164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
811590533f066035a48df9f78395a80314b559f4714Robert Phillips    if (mipLevelCount) {
812590533f066035a48df9f78395a80314b559f4714Robert Phillips        SkASSERT(texels[0].fPixels);
81367d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillips        if (!this->uploadTexDataOptimal(tex.get(), 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
814590533f066035a48df9f78395a80314b559f4714Robert Phillips                                        texels, mipLevelCount)) {
815164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            tex->unref();
816164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            return nullptr;
817164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
818164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
819164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
820d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon    if (desc.fFlags & kPerformInitialClear_GrSurfaceFlag) {
821d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        VkClearColorValue zeroClearColor;
822d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        memset(&zeroClearColor, 0, sizeof(zeroClearColor));
823d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        VkImageSubresourceRange range;
824d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
825d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        range.baseArrayLayer = 0;
826d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        range.baseMipLevel = 0;
827d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        range.layerCount = 1;
828d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        range.levelCount = 1;
829d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon        tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
830d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon                            VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
83167d52cf0d8baff02fd4337a62f1f9cd975edc18fRobert Phillips        this->currentCommandBuffer()->clearColorImage(this, tex.get(), &zeroClearColor, 1, &range);
832d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon    }
833164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return tex;
834164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
835164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
836164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
837164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
838db37909347d034943bd6b0922710a94c6c6ea572jvanverthbool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src,
839db37909347d034943bd6b0922710a94c6c6ea572jvanverth                           VkDeviceSize offset, VkDeviceSize size) {
840a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
841a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth    // Update the buffer
842db37909347d034943bd6b0922710a94c6c6ea572jvanverth    fCurrentCmdBuffer->updateBuffer(this, buffer, offset, size, src);
843a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
844a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth    return true;
845a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth}
846a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
847a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth////////////////////////////////////////////////////////////////////////////////
848a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
849164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) {
850164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // By default, all textures in Vk use TopLeft
851164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (kDefault_GrSurfaceOrigin == origin) {
852164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return kTopLeft_GrSurfaceOrigin;
853164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    } else {
854164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return origin;
855164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
856164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
857164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
8587ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Danielsk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
8597ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel                                               GrSurfaceOrigin origin,
8607ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel                                               GrBackendTextureFlags flags,
8617ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel                                               int sampleCnt,
8626bd5284415bd983b0628c4941dff5def40018f5abungeman                                               GrWrapOwnership ownership) {
8637ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    const GrVkImageInfo* info = backendTex.getVkImageInfo();
8647ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    if (!info) {
865164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
866164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
867164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
868164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int maxSize = this->caps()->maxTextureSize();
8697ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    if (backendTex.width() > maxSize || backendTex.height() > maxSize) {
870164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
871164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
872164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
8731e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc.fMemory) {
874fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        return nullptr;
875fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    }
8767ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel
8777ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    SkASSERT(backendTex.config() == GrVkFormatToPixelConfig(info->fFormat));
878164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
879164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrSurfaceDesc surfDesc;
8807ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    // next line relies on GrBackendTextureFlags matching GrTexture's
8817ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    surfDesc.fFlags = (GrSurfaceFlags)flags;
8827ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    surfDesc.fWidth = backendTex.width();
8837ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    surfDesc.fHeight = backendTex.height();
8847ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    surfDesc.fConfig = backendTex.config();
88581e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config());
8867ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    bool renderTarget = SkToBool(flags & kRenderTarget_GrBackendTextureFlag);
887164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // In GL, Chrome assumes all textures are BottomLeft
888164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // In VK, we don't have this restriction
8897ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    surfDesc.fOrigin = resolve_origin(origin);
890164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
8916bd5284415bd983b0628c4941dff5def40018f5abungeman    if (!renderTarget) {
8926bd5284415bd983b0628c4941dff5def40018f5abungeman        return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, info);
893164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
8946bd5284415bd983b0628c4941dff5def40018f5abungeman    return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership, info);
895164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
896164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
897bcf612b5d0032f09d58c2ea5671de977130395dbGreg Danielsk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT,
898bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel                                                         GrSurfaceOrigin origin){
899e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel    // Currently the Vulkan backend does not support wrapping of msaa render targets directly. In
900e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel    // general this is not an issue since swapchain images in vulkan are never multisampled. Thus if
901e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel    // you want a multisampled RT it is best to wrap the swapchain images and then let Skia handle
902e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel    // creating and owning the MSAA images.
903bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    if (backendRT.sampleCnt()) {
904e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel        return nullptr;
905e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel    }
9069d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
907bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    const GrVkImageInfo* info = backendRT.getVkImageInfo();
908bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    if (!info) {
909bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel        return nullptr;
910bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    }
9110b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman    if (VK_NULL_HANDLE == info->fImage) {
912fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        return nullptr;
913fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    }
914164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
915164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrSurfaceDesc desc;
916bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    desc.fConfig = backendRT.config();
9170ec981ba493e4a1f8d7aad513f3ae9e1f2c14711Brian Salomon    desc.fFlags = kRenderTarget_GrSurfaceFlag;
918bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    desc.fWidth = backendRT.width();
919bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    desc.fHeight = backendRT.height();
920e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel    desc.fSampleCnt = 0;
921164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
922bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    SkASSERT(kDefault_GrSurfaceOrigin != origin);
923bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    desc.fOrigin = origin;
924164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
9250b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman    sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info);
926bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    if (tgt && backendRT.stencilBits()) {
9276bd5284415bd983b0628c4941dff5def40018f5abungeman        if (!createStencilAttachmentForRenderTarget(tgt.get(), desc.fWidth, desc.fHeight)) {
928164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            return nullptr;
929164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
930164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
931164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return tgt;
932164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
933164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
9347ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Danielsk_sp<GrRenderTarget> GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
9357ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel                                                                  GrSurfaceOrigin origin,
9367ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel                                                                  int sampleCnt) {
93733910297e032b9af4336bc146c7fbb0f35918de9Brian Osman
9387ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    const GrVkImageInfo* info = tex.getVkImageInfo();
939bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    if (!info) {
940bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel        return nullptr;
941bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel    }
94233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    if (VK_NULL_HANDLE == info->fImage) {
94333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman        return nullptr;
94433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    }
94533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman
94633910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    GrSurfaceDesc desc;
9477ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    desc.fFlags = kRenderTarget_GrSurfaceFlag;
9487ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    desc.fConfig = tex.config();
9497ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    desc.fWidth = tex.width();
9507ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    desc.fHeight = tex.height();
95181e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel    desc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config());
95233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman
9537ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel    desc.fOrigin = resolve_origin(origin);
95433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman
95533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info);
95633910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    return tgt;
95733910297e032b9af4336bc146c7fbb0f35918de9Brian Osman}
95833910297e032b9af4336bc146c7fbb0f35918de9Brian Osman
95950ead53ac97deb23310916e3736c3f5e2d8f7f4begdanielvoid GrVkGpu::generateMipmap(GrVkTexture* tex) {
960900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // don't do anything for linearly tiled textures (can't have mipmaps)
96162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    if (tex->isLinearTiled()) {
962900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        SkDebugf("Trying to create mipmap for linear tiled texture");
96362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        return;
96462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    }
96562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
96662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // determine if we can blit to and from this format
96762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    const GrVkCaps& caps = this->vkCaps();
96862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    if (!caps.configCanBeDstofBlit(tex->config(), false) ||
9692f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel        !caps.configCanBeSrcofBlit(tex->config(), false) ||
9702f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel        !caps.mipMapSupport()) {
97162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        return;
97262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    }
97362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
974fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) {
975fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel        this->submitCommandBuffer(kSkip_SyncQueue);
976fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    }
977fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel
97866933552f1723c4a2b248711ab3d43921401e8e6egdaniel    // We may need to resolve the texture first if it is also a render target
97966933552f1723c4a2b248711ab3d43921401e8e6egdaniel    GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(tex->asRenderTarget());
98066933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (texRT) {
98169d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel        this->internalResolveRenderTarget(texRT, false);
98266933552f1723c4a2b248711ab3d43921401e8e6egdaniel    }
98366933552f1723c4a2b248711ab3d43921401e8e6egdaniel
9847ac5da853457b032781cf865ba018de78508edb7egdaniel    int width = tex->width();
9857ac5da853457b032781cf865ba018de78508edb7egdaniel    int height = tex->height();
9867ac5da853457b032781cf865ba018de78508edb7egdaniel    VkImageBlit blitRegion;
9877ac5da853457b032781cf865ba018de78508edb7egdaniel    memset(&blitRegion, 0, sizeof(VkImageBlit));
98862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
98982c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    // SkMipMap doesn't include the base level in the level count so we have to add 1
99082c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height()) + 1;
9917ac5da853457b032781cf865ba018de78508edb7egdaniel    if (levelCount != tex->mipLevels()) {
9927ac5da853457b032781cf865ba018de78508edb7egdaniel        const GrVkResource* oldResource = tex->resource();
9937ac5da853457b032781cf865ba018de78508edb7egdaniel        oldResource->ref();
9947ac5da853457b032781cf865ba018de78508edb7egdaniel        // grab handle to the original image resource
9957ac5da853457b032781cf865ba018de78508edb7egdaniel        VkImage oldImage = tex->image();
9967ac5da853457b032781cf865ba018de78508edb7egdaniel
9977ac5da853457b032781cf865ba018de78508edb7egdaniel        // change the original image's layout so we can copy from it
9987ac5da853457b032781cf865ba018de78508edb7egdaniel        tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9997ac5da853457b032781cf865ba018de78508edb7egdaniel                            VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
10007ac5da853457b032781cf865ba018de78508edb7egdaniel
10017ac5da853457b032781cf865ba018de78508edb7egdaniel        if (!tex->reallocForMipmap(this, levelCount)) {
10027ac5da853457b032781cf865ba018de78508edb7egdaniel            oldResource->unref(this);
10037ac5da853457b032781cf865ba018de78508edb7egdaniel            return;
10047ac5da853457b032781cf865ba018de78508edb7egdaniel        }
10057ac5da853457b032781cf865ba018de78508edb7egdaniel        // change the new image's layout so we can blit to it
10067ac5da853457b032781cf865ba018de78508edb7egdaniel        tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL,
10077ac5da853457b032781cf865ba018de78508edb7egdaniel                            VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
100862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
10097ac5da853457b032781cf865ba018de78508edb7egdaniel        // Blit original image to top level of new image
10107ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
10117ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.srcOffsets[0] = { 0, 0, 0 };
10127ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.srcOffsets[1] = { width, height, 1 };
10137ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
10147ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.dstOffsets[0] = { 0, 0, 0 };
10157ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.dstOffsets[1] = { width, height, 1 };
101662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
10177ac5da853457b032781cf865ba018de78508edb7egdaniel        fCurrentCmdBuffer->blitImage(this,
10187ac5da853457b032781cf865ba018de78508edb7egdaniel                                     oldResource,
10197ac5da853457b032781cf865ba018de78508edb7egdaniel                                     oldImage,
10207ac5da853457b032781cf865ba018de78508edb7egdaniel                                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10217ac5da853457b032781cf865ba018de78508edb7egdaniel                                     tex->resource(),
10227ac5da853457b032781cf865ba018de78508edb7egdaniel                                     tex->image(),
10237ac5da853457b032781cf865ba018de78508edb7egdaniel                                     VK_IMAGE_LAYOUT_GENERAL,
10247ac5da853457b032781cf865ba018de78508edb7egdaniel                                     1,
10257ac5da853457b032781cf865ba018de78508edb7egdaniel                                     &blitRegion,
10267ac5da853457b032781cf865ba018de78508edb7egdaniel                                     VK_FILTER_LINEAR);
102762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
10287ac5da853457b032781cf865ba018de78508edb7egdaniel        oldResource->unref(this);
10297ac5da853457b032781cf865ba018de78508edb7egdaniel    } else {
10307ac5da853457b032781cf865ba018de78508edb7egdaniel        // change layout of the layers so we can write to them.
10317ac5da853457b032781cf865ba018de78508edb7egdaniel        tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL,
10327ac5da853457b032781cf865ba018de78508edb7egdaniel                            VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
10337ac5da853457b032781cf865ba018de78508edb7egdaniel    }
103450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth
103550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    // setup memory barrier
10369440345a81d6c2372ac0aed937080f3da67439ddGreg Daniel    SkASSERT(kUnknown_GrPixelConfig != GrVkFormatToPixelConfig(tex->imageFormat()));
103750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
103850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    VkImageMemoryBarrier imageMemoryBarrier = {
103950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,          // sType
104050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        NULL,                                            // pNext
10417ac5da853457b032781cf865ba018de78508edb7egdaniel        VK_ACCESS_TRANSFER_WRITE_BIT,                    // srcAccessMask
10427ac5da853457b032781cf865ba018de78508edb7egdaniel        VK_ACCESS_TRANSFER_READ_BIT,                     // dstAccessMask
104350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_IMAGE_LAYOUT_GENERAL,                         // oldLayout
104450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_IMAGE_LAYOUT_GENERAL,                         // newLayout
104550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_QUEUE_FAMILY_IGNORED,                         // srcQueueFamilyIndex
104650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_QUEUE_FAMILY_IGNORED,                         // dstQueueFamilyIndex
1047b2df0c2702329be6380a943d548e7377a51d8565egdaniel        tex->image(),                                    // image
104850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        { aspectFlags, 0, 1, 0, 1 }                      // subresourceRange
104950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    };
105050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth
105162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // Blit the miplevels
105282c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    uint32_t mipLevel = 1;
105382c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    while (mipLevel < levelCount) {
105482c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        int prevWidth = width;
105582c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        int prevHeight = height;
105682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        width = SkTMax(1, width / 2);
105782c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        height = SkTMax(1, height / 2);
105882c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth
105950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        imageMemoryBarrier.subresourceRange.baseMipLevel = mipLevel - 1;
106050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        this->addImageMemoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
106150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                                    false, &imageMemoryBarrier);
106250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth
106350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel - 1, 0, 1 };
106462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        blitRegion.srcOffsets[0] = { 0, 0, 0 };
1065e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman        blitRegion.srcOffsets[1] = { prevWidth, prevHeight, 1 };
106682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 };
106762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        blitRegion.dstOffsets[0] = { 0, 0, 0 };
1068e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman        blitRegion.dstOffsets[1] = { width, height, 1 };
106962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        fCurrentCmdBuffer->blitImage(this,
1070b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                     *tex,
1071b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                     *tex,
107262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth                                     1,
107362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth                                     &blitRegion,
107462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth                                     VK_FILTER_LINEAR);
107582c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        ++mipLevel;
107662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    }
107762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth}
107862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
1079164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
1080164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1081164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
1082164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                     int width,
1083164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                     int height) {
1084164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(width >= rt->width());
1085164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(height >= rt->height());
1086164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1087164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int samples = rt->numStencilSamples();
1088164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
10898f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10egdaniel    const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat();
1090164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1091164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this,
1092164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 width,
1093164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 height,
1094164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 samples,
1095164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 sFmt));
1096164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fStats.incStencilAttachmentCreates();
1097164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return stencil;
1098164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1099164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
1101164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
11029d54afc38b171c01a03b34e773d154fcf83d97dcjvanverthbool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc,
11033602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                       size_t srcRowBytes, size_t dstRowBytes, int h) {
11043602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    void* mapPtr;
11053602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(),
11069d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth                                                            alloc.fMemory,
11079d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth                                                            alloc.fOffset,
11083602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                            dstRowBytes * h,
11093602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                            0,
11103602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                            &mapPtr));
11113602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    if (err) {
11123602d4f16a01da860d16eb36fb52eb62487495ccegdaniel        return false;
11133602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    }
11143602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
111520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    if (srcData) {
111620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // If there is no padding on dst we can do a single memcopy.
111720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // This assumes the srcData comes in with no padding.
111820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkRectMemcpy(mapPtr, static_cast<size_t>(dstRowBytes),
111920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                     srcData, srcRowBytes, srcRowBytes, h);
112020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    } else {
112120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // If there is no srcdata we always copy 0's into the textures so that it is initialized
112220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // with some data.
112320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (srcRowBytes == static_cast<size_t>(dstRowBytes)) {
112420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            memset(mapPtr, 0, srcRowBytes * h);
112520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        } else {
112620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            for (int i = 0; i < h; ++i) {
112720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                memset(mapPtr, 0, srcRowBytes);
112820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                mapPtr = SkTAddOffset<void>(mapPtr, static_cast<size_t>(dstRowBytes));
112920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            }
113020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        }
113120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    }
11329d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkMemory::FlushMappedAlloc(gpu, alloc);
11339d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GR_VK_CALL(gpu->vkInterface(), UnmapMemory(gpu->device(), alloc.fMemory));
11343602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    return true;
11353602d4f16a01da860d16eb36fb52eb62487495ccegdaniel}
11363602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
1137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h,
11380a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel                                                         GrPixelConfig config,
11390a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel                                                         bool isRenderTarget) {
1140164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1141164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkFormat pixelFormat;
1142164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
1143164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return 0;
1144164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool linearTiling = false;
1147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!fVkCaps->isConfigTexturable(config)) {
1148164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return 0;
1149164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1150164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
11510a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) {
11520a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        return 0;
11530a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    }
11540a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel
1155a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel    if (fVkCaps->isConfigTexturableLinearly(config) &&
11560a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        (!isRenderTarget || fVkCaps->isConfigRenderableLinearly(config, false))) {
1157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        linearTiling = true;
1158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
1161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
11630a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    if (isRenderTarget) {
11640a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
11650a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    }
1166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1167fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkImage image = VK_NULL_HANDLE;
11689d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkAlloc alloc = { VK_NULL_HANDLE, 0, 0, 0 };
1169164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1170fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1171fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling)
1172fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth                                ? VK_IMAGE_LAYOUT_PREINITIALIZED
1173fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth                                : VK_IMAGE_LAYOUT_UNDEFINED;
1174fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1175fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    // Create Image
1176fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkSampleCountFlagBits vkSamples;
1177fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    if (!GrSampleCountToVkSampleCount(1, &vkSamples)) {
1178fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        return 0;
1179fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    }
1180fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1181fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    const VkImageCreateInfo imageCreateInfo = {
1182fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,         // sType
1183fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        NULL,                                        // pNext
1184fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        0,                                           // VkImageCreateFlags
1185fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_IMAGE_TYPE_2D,                            // VkImageType
1186fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        pixelFormat,                                 // VkFormat
1187384b5e9cd36e443437de8df3b0f78ef4150efbacethannicholas        { (uint32_t) w, (uint32_t) h, 1 },           // VkExtent3D
1188fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        1,                                           // mipLevels
1189fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        1,                                           // arrayLayers
1190fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        vkSamples,                                   // samples
1191fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        imageTiling,                                 // VkImageTiling
1192fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        usageFlags,                                  // VkImageUsageFlags
1193fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_SHARING_MODE_EXCLUSIVE,                   // VkSharingMode
1194fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        0,                                           // queueFamilyCount
1195fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        0,                                           // pQueueFamilyIndices
1196fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        initialLayout                                // initialLayout
1197fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    };
1198fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1199fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image));
1200fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
12016b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    if (!GrVkMemory::AllocAndBindImageMemory(this, image, linearTiling, &alloc)) {
1202fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_CALL(DestroyImage(this->device(), image, nullptr));
1203164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return 0;
1204164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
120620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    size_t bpp = GrBytesPerPixel(config);
120720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    size_t rowCopyBytes = bpp * w;
120820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    if (linearTiling) {
120920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        const VkImageSubresource subres = {
121020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_IMAGE_ASPECT_COLOR_BIT,
121120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            0,  // mipLevel
121220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            0,  // arraySlice
121320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        };
121420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkSubresourceLayout layout;
121520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
121620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout));
121720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
121820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (!copy_testing_data(this, srcData, alloc, rowCopyBytes,
121920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                               static_cast<size_t>(layout.rowPitch), h)) {
122020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
122120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyImage(fDevice, image, nullptr));
122220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            return 0;
122320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        }
122420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel    } else {
122520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkASSERT(w && h);
122620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
122720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkBuffer buffer;
122820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkBufferCreateInfo bufInfo;
122920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
123020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
123120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.flags = 0;
123220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.size = rowCopyBytes * h;
123320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
123420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
123520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.queueFamilyIndexCount = 0;
123620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        bufInfo.pQueueFamilyIndices = nullptr;
123720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkResult err;
123820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(CreateBuffer(fDevice, &bufInfo, nullptr, &buffer));
123920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
124020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (err) {
124120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
124220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyImage(fDevice, image, nullptr));
124320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            return 0;
124420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        }
12453602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
124620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
124720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type,
124820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                                  true, &bufferAlloc)) {
124920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
125020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyImage(fDevice, image, nullptr));
125120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
125220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            return 0;
125320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        }
12543602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
125520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (!copy_testing_data(this, srcData, bufferAlloc, rowCopyBytes, rowCopyBytes, h)) {
125620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
125720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyImage(fDevice, image, nullptr));
125820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
125920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
126020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            return 0;
126120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        }
12623602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
126320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        const VkCommandBufferAllocateInfo cmdInfo = {
126420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,   // sType
126520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            NULL,                                             // pNext
126620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            fCmdPool,                                         // commandPool
126720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_COMMAND_BUFFER_LEVEL_PRIMARY,                  // level
126820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            1                                                 // bufferCount
126920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        };
127020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
127120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkCommandBuffer cmdBuffer;
127220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer));
127320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (err) {
127420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
127520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyImage(fDevice, image, nullptr));
127620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
127720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
127820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            return 0;
127920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        }
12803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
128120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkCommandBufferBeginInfo cmdBufferBeginInfo;
128220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
128320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
128420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        cmdBufferBeginInfo.pNext = nullptr;
128520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
128620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        cmdBufferBeginInfo.pInheritanceInfo = nullptr;
128720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
128820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
128920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkASSERT(!err);
129020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
129120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // Set image layout and add barrier
129220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkImageMemoryBarrier barrier;
129320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
129420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
129520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.pNext = nullptr;
129620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout);
129720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
129820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
129920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
130020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
130120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.image = image;
130220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0 , 1};
130320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
130420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VK_CALL(CmdPipelineBarrier(cmdBuffer,
130520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                   GrVkMemory::LayoutToPipelineStageFlags(initialLayout),
130620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                   VK_PIPELINE_STAGE_TRANSFER_BIT,
130720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                   0,
130820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                   0, nullptr,
130920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                   0, nullptr,
131020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel                                   1, &barrier));
131120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
131220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
131320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // Submit copy command
131420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkBufferImageCopy region;
131520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        memset(&region, 0, sizeof(VkBufferImageCopy));
131620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        region.bufferOffset = 0;
131720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        region.bufferRowLength = w;
131820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        region.bufferImageHeight = h;
131920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
132020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        region.imageOffset = { 0, 0, 0 };
132120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        region.imageExtent = { (uint32_t)w, (uint32_t)h, 1 };
132220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
132320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, 1, &region));
132420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
132520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // End CommandBuffer
132620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(EndCommandBuffer(cmdBuffer));
132720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkASSERT(!err);
132820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
132920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // Create Fence for queue
133020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkFence fence;
133120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkFenceCreateInfo fenceInfo;
133220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
133320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
133420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
133520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence));
133620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkASSERT(!err);
133720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
133820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VkSubmitInfo submitInfo;
133920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        memset(&submitInfo, 0, sizeof(VkSubmitInfo));
134020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
134120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.pNext = nullptr;
134220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.waitSemaphoreCount = 0;
134320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.pWaitSemaphores = nullptr;
134420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.pWaitDstStageMask = 0;
134520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.commandBufferCount = 1;
134620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.pCommandBuffers = &cmdBuffer;
134720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.signalSemaphoreCount = 0;
134820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        submitInfo.pSignalSemaphores = nullptr;
134920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence));
135020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkASSERT(!err);
135120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
135220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX));
135320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        if (VK_TIMEOUT == err) {
135420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
135520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            VK_CALL(DestroyImage(fDevice, image, nullptr));
13563602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
13573602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
13583602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
13593602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(DestroyFence(fDevice, fence, nullptr));
136020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            SkDebugf("Fence failed to signal: %d\n", err);
136120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel            SkFAIL("failing");
1362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
136320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        SkASSERT(!err);
136420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel
136520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        // Clean up transfer resources
136620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
136720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
136820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
136920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel        VK_CALL(DestroyFence(fDevice, fence, nullptr));
1370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1372b2df0c2702329be6380a943d548e7377a51d8565egdaniel    GrVkImageInfo* info = new GrVkImageInfo;
1373fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fImage = image;
1374fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fAlloc = alloc;
1375fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fImageTiling = imageTiling;
1376fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fImageLayout = initialLayout;
137758a8d9214a70e0f6c81c88a8b0b563c06bf0f70eegdaniel    info->fFormat = pixelFormat;
13782af0f1b014b9aabb6119bf66fac20e4cd3a8279bjvanverth    info->fLevelCount = 1;
1379fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1380fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    return (GrBackendObject)info;
1381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1382164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1383164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const {
1384b2df0c2702329be6380a943d548e7377a51d8565egdaniel    const GrVkImageInfo* backend = reinterpret_cast<const GrVkImageInfo*>(id);
1385164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
13861e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    if (backend && backend->fImage && backend->fAlloc.fMemory) {
1387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        VkMemoryRequirements req;
1388164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        memset(&req, 0, sizeof(req));
1389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice,
1390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                   backend->fImage,
1391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                   &req));
1392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // TODO: find a better check
1393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // This will probably fail with a different driver
1394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return (req.size > 0) && (req.size <= 8192 * 8192);
1395164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1396164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1397164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return false;
1398164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1399164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1400164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) {
14016b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    GrVkImageInfo* backend = reinterpret_cast<GrVkImageInfo*>(id);
1402164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (backend) {
1403164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        if (!abandon) {
1404fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth            // something in the command buffer may still be using this, so force submit
1405fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth            this->submitCommandBuffer(kForce_SyncQueue);
14066b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth            GrVkImage::DestroyImageInfo(this, backend);
1407164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
1408fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        delete backend;
1409164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1410164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1411164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
1413164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1414164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask,
1415164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                               VkPipelineStageFlags dstStageMask,
1416164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                               bool byRegion,
1417164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                               VkMemoryBarrier* barrier) const {
1418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
1419164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->pipelineBarrier(this,
1420164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       srcStageMask,
1421164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       dstStageMask,
1422164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       byRegion,
1423164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       GrVkCommandBuffer::kMemory_BarrierType,
1424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       barrier);
1425164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1426164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1427164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addBufferMemoryBarrier(VkPipelineStageFlags srcStageMask,
1428164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VkPipelineStageFlags dstStageMask,
1429164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     bool byRegion,
1430164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VkBufferMemoryBarrier* barrier) const {
1431164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
1432164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->pipelineBarrier(this,
1433164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       srcStageMask,
1434164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       dstStageMask,
1435164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       byRegion,
1436164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       GrVkCommandBuffer::kBufferMemory_BarrierType,
1437164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       barrier);
1438164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1439164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1440164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask,
1441164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                    VkPipelineStageFlags dstStageMask,
1442164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                    bool byRegion,
1443164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                    VkImageMemoryBarrier* barrier) const {
1444164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
1445164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->pipelineBarrier(this,
1446164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       srcStageMask,
1447164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       dstStageMask,
1448164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       byRegion,
1449164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       GrVkCommandBuffer::kImageMemory_BarrierType,
1450164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       barrier);
1451164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1452164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
145318e9484ad5b5755757dc6badb986017a088a9c6bRobert Phillipsvoid GrVkGpu::finishFlush() {
1454164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Submit the current command buffer to the Queue
1455164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    this->submitCommandBuffer(kSkip_SyncQueue);
1456164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1457164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
14583d5d9ac426ea926f37eaa47e13acf7492068667begdanielvoid GrVkGpu::clearStencil(GrRenderTarget* target) {
14593d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    if (nullptr == target) {
14603d5d9ac426ea926f37eaa47e13acf7492068667begdaniel        return;
14613d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    }
14623d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    GrStencilAttachment* stencil = target->renderTargetPriv().getStencilAttachment();
14633d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
14643d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
14653d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
14663d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    VkClearDepthStencilValue vkStencilColor;
14673d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
14683d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
14693d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    vkStencil->setImageLayout(this,
14703d5d9ac426ea926f37eaa47e13acf7492068667begdaniel                              VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
147150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                              VK_ACCESS_TRANSFER_WRITE_BIT,
147250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                              VK_PIPELINE_STAGE_TRANSFER_BIT,
14733d5d9ac426ea926f37eaa47e13acf7492068667begdaniel                              false);
14743d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
14753d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    VkImageSubresourceRange subRange;
14763d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    memset(&subRange, 0, sizeof(VkImageSubresourceRange));
14773d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
14783d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.baseMipLevel = 0;
14793d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.levelCount = 1;
14803d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.baseArrayLayer = 0;
14813d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.layerCount = 1;
14823d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
14833d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a
14843d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    // draw. Thus we should look into using the load op functions on the render pass to clear out
14853d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    // the stencil there.
14863d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange);
14873d5d9ac426ea926f37eaa47e13acf7492068667begdaniel}
14883d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
1489164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_image(const GrSurface* dst,
1490164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           const GrSurface* src,
1491164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           const GrVkGpu* gpu) {
14924bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    const GrRenderTarget* dstRT = dst->asRenderTarget();
14934bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    const GrRenderTarget* srcRT = src->asRenderTarget();
14944bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (dstRT && srcRT) {
14954bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        if (srcRT->numColorSamples() != dstRT->numColorSamples()) {
14964bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel            return false;
14974bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        }
14984bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    } else if (dstRT) {
14994bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        if (dstRT->numColorSamples() > 1) {
15004bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel            return false;
15014bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        }
15024bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    } else if (srcRT) {
15034bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        if (srcRT->numColorSamples() > 1) {
15044bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel            return false;
15054bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        }
150617b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
150717b892551465e5a44560a06e4b34dc3592b49622egdaniel
15083251ed84052ced22d1e4c285524a835a82f7dd12Michael Jurka    // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
150917b892551465e5a44560a06e4b34dc3592b49622egdaniel    // as image usage flags.
151017b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (src->origin() == dst->origin() &&
151117b892551465e5a44560a06e4b34dc3592b49622egdaniel        GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) {
1512164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return true;
1513164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1514164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1515164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return false;
1516164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1517164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1518164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst,
1519164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     GrSurface* src,
152017b892551465e5a44560a06e4b34dc3592b49622egdaniel                                     GrVkImage* dstImage,
152117b892551465e5a44560a06e4b34dc3592b49622egdaniel                                     GrVkImage* srcImage,
1522164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     const SkIRect& srcRect,
1523164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     const SkIPoint& dstPoint) {
1524164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(can_copy_image(dst, src, this));
1525164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1526164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // These flags are for flushing/invalidating caches and for the dst image it doesn't matter if
1527164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // the cache is flushed since it is only being written to.
152817b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstImage->setImageLayout(this,
152950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
153050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_WRITE_BIT,
153150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
153250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             false);
1533164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
153417b892551465e5a44560a06e4b34dc3592b49622egdaniel    srcImage->setImageLayout(this,
153517b892551465e5a44560a06e4b34dc3592b49622egdaniel                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
153650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_READ_BIT,
153750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
153817b892551465e5a44560a06e4b34dc3592b49622egdaniel                             false);
1539164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1540164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Flip rect if necessary
1541164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkIRect srcVkRect = srcRect;
1542164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int32_t dstY = dstPoint.fY;
1543164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1544164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
1545164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin());
1546164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        srcVkRect.fTop = src->height() - srcRect.fBottom;
1547164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        srcVkRect.fBottom =  src->height() - srcRect.fTop;
1548164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        dstY = dst->height() - dstPoint.fY - srcVkRect.height();
1549164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1550164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1551164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkImageCopy copyRegion;
1552164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    memset(&copyRegion, 0, sizeof(VkImageCopy));
1553164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1554164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
1555164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1556164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.dstOffset = { dstPoint.fX, dstY, 0 };
1557c355bc8dd117291b63ee7b7b39ec37a0e768eec5egdaniel    copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 };
1558164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1559164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->copyImage(this,
156017b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 srcImage,
1561164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
156217b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 dstImage,
1563164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1564164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 1,
1565164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 &copyRegion);
1566900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
1567900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
1568900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                        srcRect.width(), srcRect.height());
1569900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    this->didWriteToSurface(dst, &dstRect);
1570164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1571164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
157217b892551465e5a44560a06e4b34dc3592b49622egdanielinline bool can_copy_as_blit(const GrSurface* dst,
157317b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrSurface* src,
157417b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrVkImage* dstImage,
157517b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrVkImage* srcImage,
157617b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrVkGpu* gpu) {
157766933552f1723c4a2b248711ab3d43921401e8e6egdaniel    // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
157817b892551465e5a44560a06e4b34dc3592b49622egdaniel    // as image usage flags.
157917b892551465e5a44560a06e4b34dc3592b49622egdaniel    const GrVkCaps& caps = gpu->vkCaps();
158017b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (!caps.configCanBeDstofBlit(dst->config(), dstImage->isLinearTiled()) ||
158117b892551465e5a44560a06e4b34dc3592b49622egdaniel        !caps.configCanBeSrcofBlit(src->config(), srcImage->isLinearTiled())) {
158217b892551465e5a44560a06e4b34dc3592b49622egdaniel        return false;
158317b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
158417b892551465e5a44560a06e4b34dc3592b49622egdaniel
158517b892551465e5a44560a06e4b34dc3592b49622egdaniel    // We cannot blit images that are multisampled. Will need to figure out if we can blit the
158617b892551465e5a44560a06e4b34dc3592b49622egdaniel    // resolved msaa though.
158717b892551465e5a44560a06e4b34dc3592b49622egdaniel    if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) ||
158817b892551465e5a44560a06e4b34dc3592b49622egdaniel        (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) {
158917b892551465e5a44560a06e4b34dc3592b49622egdaniel        return false;
159017b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
159117b892551465e5a44560a06e4b34dc3592b49622egdaniel
159217b892551465e5a44560a06e4b34dc3592b49622egdaniel    return true;
159317b892551465e5a44560a06e4b34dc3592b49622egdaniel}
159417b892551465e5a44560a06e4b34dc3592b49622egdaniel
159517b892551465e5a44560a06e4b34dc3592b49622egdanielvoid GrVkGpu::copySurfaceAsBlit(GrSurface* dst,
159617b892551465e5a44560a06e4b34dc3592b49622egdaniel                                GrSurface* src,
159717b892551465e5a44560a06e4b34dc3592b49622egdaniel                                GrVkImage* dstImage,
159817b892551465e5a44560a06e4b34dc3592b49622egdaniel                                GrVkImage* srcImage,
159917b892551465e5a44560a06e4b34dc3592b49622egdaniel                                const SkIRect& srcRect,
160017b892551465e5a44560a06e4b34dc3592b49622egdaniel                                const SkIPoint& dstPoint) {
160117b892551465e5a44560a06e4b34dc3592b49622egdaniel    SkASSERT(can_copy_as_blit(dst, src, dstImage, srcImage, this));
160217b892551465e5a44560a06e4b34dc3592b49622egdaniel
160317b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstImage->setImageLayout(this,
160417b892551465e5a44560a06e4b34dc3592b49622egdaniel                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
160550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_WRITE_BIT,
160650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
160717b892551465e5a44560a06e4b34dc3592b49622egdaniel                             false);
160817b892551465e5a44560a06e4b34dc3592b49622egdaniel
160917b892551465e5a44560a06e4b34dc3592b49622egdaniel    srcImage->setImageLayout(this,
161017b892551465e5a44560a06e4b34dc3592b49622egdaniel                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
161150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_READ_BIT,
161250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
161317b892551465e5a44560a06e4b34dc3592b49622egdaniel                             false);
161417b892551465e5a44560a06e4b34dc3592b49622egdaniel
161517b892551465e5a44560a06e4b34dc3592b49622egdaniel    // Flip rect if necessary
161617b892551465e5a44560a06e4b34dc3592b49622egdaniel    SkIRect srcVkRect;
16178af936d3047208def585b7bc824f013b994f6312egdaniel    srcVkRect.fLeft = srcRect.fLeft;
16188af936d3047208def585b7bc824f013b994f6312egdaniel    srcVkRect.fRight = srcRect.fRight;
161917b892551465e5a44560a06e4b34dc3592b49622egdaniel    SkIRect dstRect;
162017b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstRect.fLeft = dstPoint.fX;
16218af936d3047208def585b7bc824f013b994f6312egdaniel    dstRect.fRight = dstPoint.fX + srcRect.width();
162217b892551465e5a44560a06e4b34dc3592b49622egdaniel
162317b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
162417b892551465e5a44560a06e4b34dc3592b49622egdaniel        srcVkRect.fTop = src->height() - srcRect.fBottom;
162517b892551465e5a44560a06e4b34dc3592b49622egdaniel        srcVkRect.fBottom = src->height() - srcRect.fTop;
162617b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
16278af936d3047208def585b7bc824f013b994f6312egdaniel        srcVkRect.fTop = srcRect.fTop;
16288af936d3047208def585b7bc824f013b994f6312egdaniel        srcVkRect.fBottom = srcRect.fBottom;
162917b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
163017b892551465e5a44560a06e4b34dc3592b49622egdaniel
163117b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
163217b892551465e5a44560a06e4b34dc3592b49622egdaniel        dstRect.fTop = dst->height() - dstPoint.fY - srcVkRect.height();
163317b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
163417b892551465e5a44560a06e4b34dc3592b49622egdaniel        dstRect.fTop = dstPoint.fY;
163517b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
163617b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstRect.fBottom = dstRect.fTop + srcVkRect.height();
163717b892551465e5a44560a06e4b34dc3592b49622egdaniel
163817b892551465e5a44560a06e4b34dc3592b49622egdaniel    // If we have different origins, we need to flip the top and bottom of the dst rect so that we
163917b892551465e5a44560a06e4b34dc3592b49622egdaniel    // get the correct origintation of the copied data.
164017b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (src->origin() != dst->origin()) {
164117b892551465e5a44560a06e4b34dc3592b49622egdaniel        SkTSwap(dstRect.fTop, dstRect.fBottom);
164217b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
164317b892551465e5a44560a06e4b34dc3592b49622egdaniel
164417b892551465e5a44560a06e4b34dc3592b49622egdaniel    VkImageBlit blitRegion;
164517b892551465e5a44560a06e4b34dc3592b49622egdaniel    memset(&blitRegion, 0, sizeof(VkImageBlit));
164617b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
164717b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
1648e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel    blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 1 };
164917b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
165017b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 };
1651e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel    blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 1 };
165217b892551465e5a44560a06e4b34dc3592b49622egdaniel
165317b892551465e5a44560a06e4b34dc3592b49622egdaniel    fCurrentCmdBuffer->blitImage(this,
1654b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                 *srcImage,
1655b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                 *dstImage,
165617b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 1,
165717b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 &blitRegion,
165817b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 VK_FILTER_NEAREST); // We never scale so any filter works here
1659900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
1660900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    this->didWriteToSurface(dst, &dstRect);
166117b892551465e5a44560a06e4b34dc3592b49622egdaniel}
166217b892551465e5a44560a06e4b34dc3592b49622egdaniel
16634bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielinline bool can_copy_as_resolve(const GrSurface* dst,
16644bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                const GrSurface* src,
16654bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                const GrVkGpu* gpu) {
16664bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // Our src must be a multisampled render target
16674bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (!src->asRenderTarget() || src->asRenderTarget()->numColorSamples() <= 1) {
16684bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        return false;
16694bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
16704bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
16717d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel    // The dst must not be a multisampled render target, expect in the case where the dst is the
16727d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel    // resolve texture connected to the msaa src. We check for this in case we are copying a part of
16737d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel    // a surface to a different region in the same surface.
16747d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel    if (dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1 && dst != src) {
16754bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        return false;
16764bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
16774bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
16784bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // Surfaces must have the same origin.
16794bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (src->origin() != dst->origin()) {
16804bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        return false;
16814bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
16824bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
16834bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    return true;
16844bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel}
16854bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
16864bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielvoid GrVkGpu::copySurfaceAsResolve(GrSurface* dst,
16874bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                   GrSurface* src,
16884bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                   const SkIRect& srcRect,
16894bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                   const SkIPoint& dstPoint) {
16904bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget());
1691bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel    this->resolveImage(dst, srcRT, srcRect, dstPoint);
16924bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel}
16934bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
1694164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onCopySurface(GrSurface* dst,
1695164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            GrSurface* src,
1696164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            const SkIRect& srcRect,
1697164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            const SkIPoint& dstPoint) {
16984bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (can_copy_as_resolve(dst, src, this)) {
16994bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        this->copySurfaceAsResolve(dst, src, srcRect, dstPoint);
1700ec44099979acd3e83ad93a15dbd9301856a90572egdaniel        return true;
17014bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
17024bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
1703fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) {
1704fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel        this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue);
1705fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    }
1706fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel
1707bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    if (fCopyManager.copySurfaceAsDraw(this, dst, src, srcRect, dstPoint)) {
1708bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel        return true;
1709bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    }
1710bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel
171117b892551465e5a44560a06e4b34dc3592b49622egdaniel    GrVkImage* dstImage;
171217b892551465e5a44560a06e4b34dc3592b49622egdaniel    GrVkImage* srcImage;
17134bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrRenderTarget* dstRT = dst->asRenderTarget();
17144bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (dstRT) {
17154bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT);
17164bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        dstImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT;
171717b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
17184bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        SkASSERT(dst->asTexture());
17194bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        dstImage = static_cast<GrVkTexture*>(dst->asTexture());
172017b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
17214bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrRenderTarget* srcRT = src->asRenderTarget();
17224bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (srcRT) {
17234bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT);
17244bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT;
172517b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
17264bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        SkASSERT(src->asTexture());
17274bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcImage = static_cast<GrVkTexture*>(src->asTexture());
172817b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
172917b892551465e5a44560a06e4b34dc3592b49622egdaniel
173013dddce65fd87a8175a209a49f35615735a2886aBrian Osman    // For borrowed textures, we *only* want to copy using draws (to avoid layout changes)
173113dddce65fd87a8175a209a49f35615735a2886aBrian Osman    if (srcImage->isBorrowed()) {
173213dddce65fd87a8175a209a49f35615735a2886aBrian Osman        return false;
173313dddce65fd87a8175a209a49f35615735a2886aBrian Osman    }
173413dddce65fd87a8175a209a49f35615735a2886aBrian Osman
1735164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (can_copy_image(dst, src, this)) {
173617b892551465e5a44560a06e4b34dc3592b49622egdaniel        this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstPoint);
173717b892551465e5a44560a06e4b34dc3592b49622egdaniel        return true;
173817b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
173917b892551465e5a44560a06e4b34dc3592b49622egdaniel
174017b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) {
174117b892551465e5a44560a06e4b34dc3592b49622egdaniel        this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint);
1742164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return true;
1743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return false;
1746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1748c25c5d73e9f4d840dc758c399496d5690709ad58csmartdaltonvoid GrVkGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&,
1749c25c5d73e9f4d840dc758c399496d5690709ad58csmartdalton                                      int* effectiveSampleCnt, SamplePattern*) {
175028f45b949acc746849100fbe112ee5280f0594c9cdalton    // TODO: stub.
175128f45b949acc746849100fbe112ee5280f0594c9cdalton    SkASSERT(!this->caps()->sampleLocationsSupport());
1752154ce91dc96187229d0bc84cf10a77f480194e6fBrian Salomon    *effectiveSampleCnt = rt->numStencilSamples();
175328f45b949acc746849100fbe112ee5280f0594c9cdalton}
175428f45b949acc746849100fbe112ee5280f0594c9cdalton
1755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
1756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                  GrPixelConfig readConfig, DrawPreference* drawPreference,
1757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                  ReadPixelTempDrawInfo* tempDrawInfo) {
175888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // These settings we will always want if a temp draw is performed.
175988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
176088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
176188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
176288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
176388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
1764b117ff194ff888ef9107a4797aad053b0d76be30bsalomon    tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox;
176588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel
176688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // For now assume no swizzling, we may change that below.
176788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
176888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel
176988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read
177088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // from will be srcConfig and we will read readConfig pixels from it.
177133910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    // Note that if we require a draw and return a non-renderable format for the temp surface the
177288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // base class will fail for us.
177388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config();
177488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fReadConfig = readConfig;
177588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel
17764583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    if (srcSurface->config() == readConfig) {
17774583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        return true;
1778164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1779164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
178033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    // Any config change requires a draw
178133910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
178233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
178333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    tempDrawInfo->fReadConfig = readConfig;
1784164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
178533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman    return true;
1786164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1787164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onReadPixels(GrSurface* surface,
1789164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           int left, int top, int width, int height,
1790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           GrPixelConfig config,
1791164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           void* buffer,
1792164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           size_t rowBytes) {
1793164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkFormat pixelFormat;
1794164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
1795164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
1796164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1797164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
179866933552f1723c4a2b248711ab3d43921401e8e6egdaniel    GrVkImage* image = nullptr;
179966933552f1723c4a2b248711ab3d43921401e8e6egdaniel    GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(surface->asRenderTarget());
180066933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (rt) {
180166933552f1723c4a2b248711ab3d43921401e8e6egdaniel        // resolve the render target if necessary
180266933552f1723c4a2b248711ab3d43921401e8e6egdaniel        switch (rt->getResolveType()) {
180366933552f1723c4a2b248711ab3d43921401e8e6egdaniel            case GrVkRenderTarget::kCantResolve_ResolveType:
180466933552f1723c4a2b248711ab3d43921401e8e6egdaniel                return false;
180566933552f1723c4a2b248711ab3d43921401e8e6egdaniel            case GrVkRenderTarget::kAutoResolves_ResolveType:
180666933552f1723c4a2b248711ab3d43921401e8e6egdaniel                break;
180766933552f1723c4a2b248711ab3d43921401e8e6egdaniel            case GrVkRenderTarget::kCanResolve_ResolveType:
180869d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel                this->internalResolveRenderTarget(rt, false);
180966933552f1723c4a2b248711ab3d43921401e8e6egdaniel                break;
181066933552f1723c4a2b248711ab3d43921401e8e6egdaniel            default:
181166933552f1723c4a2b248711ab3d43921401e8e6egdaniel                SkFAIL("Unknown resolve type");
181266933552f1723c4a2b248711ab3d43921401e8e6egdaniel        }
181366933552f1723c4a2b248711ab3d43921401e8e6egdaniel        image = rt;
181466933552f1723c4a2b248711ab3d43921401e8e6egdaniel    } else {
181566933552f1723c4a2b248711ab3d43921401e8e6egdaniel        image = static_cast<GrVkTexture*>(surface->asTexture());
181666933552f1723c4a2b248711ab3d43921401e8e6egdaniel    }
181766933552f1723c4a2b248711ab3d43921401e8e6egdaniel
181866933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (!image) {
1819164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
1820164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1821164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1822164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Change layout of our target so it can be used as copy
182366933552f1723c4a2b248711ab3d43921401e8e6egdaniel    image->setImageLayout(this,
182466933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
182566933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          VK_ACCESS_TRANSFER_READ_BIT,
182666933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          VK_PIPELINE_STAGE_TRANSFER_BIT,
182766933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          false);
1828164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
18296fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    size_t bpp = GrBytesPerPixel(config);
18306fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    size_t tightRowBytes = bpp * width;
1831164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
1832164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1833164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkBufferImageCopy region;
1834164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    memset(&region, 0, sizeof(VkBufferImageCopy));
18356fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
18366fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    bool copyFromOrigin = this->vkCaps().mustDoCopiesFromOrigin();
18376fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    if (copyFromOrigin) {
18386fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageOffset = { 0, 0, 0 };
18396fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageExtent = { (uint32_t)(left + width),
18406fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                               (uint32_t)(flipY ? surface->height() - top : top + height),
18416fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                               1
18426fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                             };
18436fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    } else {
18446fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        VkOffset3D offset = {
18456fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            left,
18466fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            flipY ? surface->height() - top - height : top,
18476fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            0
18486fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        };
18496fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageOffset = offset;
18506fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
18516fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    }
18526fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
18536fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    size_t transBufferRowBytes = bpp * region.imageExtent.width;
18546fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    GrVkTransferBuffer* transferBuffer =
18556fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            static_cast<GrVkTransferBuffer*>(this->createBuffer(transBufferRowBytes * height,
18566fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                                                                kXferGpuToCpu_GrBufferType,
18576fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                                                                kStream_GrAccessPattern));
18586fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
18596fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    // Copy the image to a buffer so we can map it to cpu memory
1860db37909347d034943bd6b0922710a94c6c6ea572jvanverth    region.bufferOffset = transferBuffer->offset();
186188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    region.bufferRowLength = 0; // Forces RowLength to be width. We handle the rowBytes below.
1862164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images.
1863164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1864164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1865164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->copyImageToBuffer(this,
186666933552f1723c4a2b248711ab3d43921401e8e6egdaniel                                         image,
1867164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1868164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         transferBuffer,
1869164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         1,
1870164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         &region);
1871164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1872164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // make sure the copy to buffer has finished
1873164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    transferBuffer->addMemoryBarrier(this,
1874164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_ACCESS_TRANSFER_WRITE_BIT,
1875164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_ACCESS_HOST_READ_BIT,
1876164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_PIPELINE_STAGE_TRANSFER_BIT,
1877164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_PIPELINE_STAGE_HOST_BIT,
1878164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     false);
1879164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1880164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // We need to submit the current command buffer to the Queue and make sure it finishes before
1881164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // we can copy the data out of the buffer.
1882164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    this->submitCommandBuffer(kForce_SyncQueue);
18839d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkMemory::InvalidateMappedAlloc(this, transferBuffer->alloc());
1884164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void* mappedMemory = transferBuffer->map();
1885164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
18866fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    if (copyFromOrigin) {
18876fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        uint32_t skipRows = region.imageExtent.height - height;
18886fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        mappedMemory = (char*)mappedMemory + transBufferRowBytes * skipRows + bpp * left;
18896fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    }
18906fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
1891164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (flipY) {
189288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        const char* srcRow = reinterpret_cast<const char*>(mappedMemory);
189388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes;
189488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        for (int y = 0; y < height; y++) {
189588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel            memcpy(dstRow, srcRow, tightRowBytes);
18966fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            srcRow += transBufferRowBytes;
189788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel            dstRow -= rowBytes;
189888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        }
189988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    } else {
1900cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett        SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, height);
1901164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1902164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
190388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    transferBuffer->unmap();
190488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    transferBuffer->unref();
1905164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return true;
1906164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1907066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
190827bb28473912181cf9a838e9282e86cb62e2d44begdaniel// The RenderArea bounds we pass into BeginRenderPass must have a start x value that is a multiple
190927bb28473912181cf9a838e9282e86cb62e2d44begdaniel// of the granularity. The width must also be a multiple of the granularity or eaqual to the width
191027bb28473912181cf9a838e9282e86cb62e2d44begdaniel// the the entire attachment. Similar requirements for the y and height components.
191127bb28473912181cf9a838e9282e86cb62e2d44begdanielvoid adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds,
191227bb28473912181cf9a838e9282e86cb62e2d44begdaniel                                  const VkExtent2D& granularity, int maxWidth, int maxHeight) {
191327bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // Adjust Width
1914d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel    if ((0 != granularity.width && 1 != granularity.width)) {
1915d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        // Start with the right side of rect so we know if we end up going pass the maxWidth.
1916d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        int rightAdj = srcBounds.fRight % granularity.width;
1917d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (rightAdj != 0) {
1918d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            rightAdj = granularity.width - rightAdj;
1919d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
1920d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fRight = srcBounds.fRight + rightAdj;
1921d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (dstBounds->fRight > maxWidth) {
1922d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fRight = maxWidth;
1923d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fLeft = 0;
1924d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        } else {
1925d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fLeft = srcBounds.fLeft - srcBounds.fLeft % granularity.width;
1926d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
192727bb28473912181cf9a838e9282e86cb62e2d44begdaniel    } else {
1928d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fLeft = srcBounds.fLeft;
1929d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fRight = srcBounds.fRight;
193027bb28473912181cf9a838e9282e86cb62e2d44begdaniel    }
193127bb28473912181cf9a838e9282e86cb62e2d44begdaniel
193227bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // Adjust height
1933d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel    if ((0 != granularity.height && 1 != granularity.height)) {
1934d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        // Start with the bottom side of rect so we know if we end up going pass the maxHeight.
1935d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        int bottomAdj = srcBounds.fBottom % granularity.height;
1936d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (bottomAdj != 0) {
1937d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            bottomAdj = granularity.height - bottomAdj;
1938d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
1939d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fBottom = srcBounds.fBottom + bottomAdj;
1940d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (dstBounds->fBottom > maxHeight) {
1941d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fBottom = maxHeight;
1942d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fTop = 0;
1943d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        } else {
1944d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fTop = srcBounds.fTop - srcBounds.fTop % granularity.height;
1945d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
194627bb28473912181cf9a838e9282e86cb62e2d44begdaniel    } else {
1947d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fTop = srcBounds.fTop;
1948d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fBottom = srcBounds.fBottom;
194927bb28473912181cf9a838e9282e86cb62e2d44begdaniel    }
195027bb28473912181cf9a838e9282e86cb62e2d44begdaniel}
195127bb28473912181cf9a838e9282e86cb62e2d44begdaniel
195222bc8653d704584e13f35844dafb5ddeb9989127Greg Danielvoid GrVkGpu::submitSecondaryCommandBuffer(const SkTArray<GrVkSecondaryCommandBuffer*>& buffers,
19539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const GrVkRenderPass* renderPass,
19549cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const VkClearValue* colorClear,
19559cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           GrVkRenderTarget* target,
19569cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const SkIRect& bounds) {
1957e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    const SkIRect* pBounds = &bounds;
1958e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    SkIRect flippedBounds;
1959e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    if (kBottomLeft_GrSurfaceOrigin == target->origin()) {
1960e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        flippedBounds = bounds;
1961e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        flippedBounds.fTop = target->height() - bounds.fBottom;
1962e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        flippedBounds.fBottom = target->height() - bounds.fTop;
1963e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        pBounds = &flippedBounds;
1964e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    }
1965e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel
196627bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // The bounds we use for the render pass should be of the granularity supported
196727bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // by the device.
196827bb28473912181cf9a838e9282e86cb62e2d44begdaniel    const VkExtent2D& granularity = renderPass->granularity();
196927bb28473912181cf9a838e9282e86cb62e2d44begdaniel    SkIRect adjustedBounds;
197027bb28473912181cf9a838e9282e86cb62e2d44begdaniel    if ((0 != granularity.width && 1 != granularity.width) ||
197127bb28473912181cf9a838e9282e86cb62e2d44begdaniel        (0 != granularity.height && 1 != granularity.height)) {
197227bb28473912181cf9a838e9282e86cb62e2d44begdaniel        adjust_bounds_to_granularity(&adjustedBounds, *pBounds, granularity,
197327bb28473912181cf9a838e9282e86cb62e2d44begdaniel                                     target->width(), target->height());
197427bb28473912181cf9a838e9282e86cb62e2d44begdaniel        pBounds = &adjustedBounds;
197527bb28473912181cf9a838e9282e86cb62e2d44begdaniel    }
197627bb28473912181cf9a838e9282e86cb62e2d44begdaniel
197777a86f81f39227ea53441af2afc647f589a96a0dGreg Daniel    fCurrentCmdBuffer->beginRenderPass(this, renderPass, colorClear, *target, *pBounds, true);
197822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    for (int i = 0; i < buffers.count(); ++i) {
197922bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel        fCurrentCmdBuffer->executeCommands(this, buffers[i]);
198022bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel    }
1981164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->endRenderPass(this);
198266933552f1723c4a2b248711ab3d43921401e8e6egdaniel
1983ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    this->didWriteToSurface(target, &bounds);
1984164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
19859cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
19866be35238855dbbc7575e78d6723936293a4b38e6Greg DanielGrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() {
198784741b308496409f4ff662658167221fc6801bbejvanverth    VkFenceCreateInfo createInfo;
198884741b308496409f4ff662658167221fc6801bbejvanverth    memset(&createInfo, 0, sizeof(VkFenceCreateInfo));
198984741b308496409f4ff662658167221fc6801bbejvanverth    createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
199084741b308496409f4ff662658167221fc6801bbejvanverth    createInfo.pNext = nullptr;
199184741b308496409f4ff662658167221fc6801bbejvanverth    createInfo.flags = 0;
199284741b308496409f4ff662658167221fc6801bbejvanverth    VkFence fence = VK_NULL_HANDLE;
19936be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
19946be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VK_CALL_ERRCHECK(CreateFence(this->device(), &createInfo, nullptr, &fence));
19956be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VK_CALL(QueueSubmit(this->queue(), 0, nullptr, fence));
19966be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
19976be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(VkFence));
199884741b308496409f4ff662658167221fc6801bbejvanverth    return (GrFence)fence;
199984741b308496409f4ff662658167221fc6801bbejvanverth}
200084741b308496409f4ff662658167221fc6801bbejvanverth
20016be35238855dbbc7575e78d6723936293a4b38e6Greg Danielbool GrVkGpu::waitFence(GrFence fence, uint64_t timeout) {
20026be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    SkASSERT(VK_NULL_HANDLE != (VkFence)fence);
20036be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
20046be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VkResult result = VK_CALL(WaitForFences(this->device(), 1, (VkFence*)&fence, VK_TRUE, timeout));
200584741b308496409f4ff662658167221fc6801bbejvanverth    return (VK_SUCCESS == result);
200684741b308496409f4ff662658167221fc6801bbejvanverth}
200784741b308496409f4ff662658167221fc6801bbejvanverth
200884741b308496409f4ff662658167221fc6801bbejvanverthvoid GrVkGpu::deleteFence(GrFence fence) const {
20096be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VK_CALL(DestroyFence(this->device(), (VkFence)fence, nullptr));
20106be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
20116be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
2012a5cb781c17c09e01655defd0a84b431996b6a015Greg Danielsk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrVkGpu::makeSemaphore(bool isOwned) {
2013a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    return GrVkSemaphore::Make(this, isOwned);
2014a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel}
2015a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel
2016a5cb781c17c09e01655defd0a84b431996b6a015Greg Danielsk_sp<GrSemaphore> GrVkGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
2017a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel                                                 GrWrapOwnership ownership) {
2018a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    return GrVkSemaphore::MakeWrapped(this, semaphore.vkSemaphore(), ownership);
20196be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
20206be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
2021a5cb781c17c09e01655defd0a84b431996b6a015Greg Danielvoid GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
20226be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
20236be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
2024a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    const GrVkSemaphore::Resource* resource = vkSem->getResource();
2025a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    resource->ref();
2026a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    fSemaphoresToSignal.push_back(resource);
2027a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel
2028a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    if (flush) {
2029a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel        this->submitCommandBuffer(kSkip_SyncQueue);
2030a5cb781c17c09e01655defd0a84b431996b6a015Greg Daniel    }
20316be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
20326be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
20336be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrVkGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
20346be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
20356be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
20366be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    const GrVkSemaphore::Resource* resource = vkSem->getResource();
20376be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    resource->ref();
20386be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fSemaphoresToWaitOn.push_back(resource);
203984741b308496409f4ff662658167221fc6801bbejvanverth}
204013dddce65fd87a8175a209a49f35615735a2886aBrian Osman
204113dddce65fd87a8175a209a49f35615735a2886aBrian Osmansk_sp<GrSemaphore> GrVkGpu::prepareTextureForCrossContextUsage(GrTexture* texture) {
204213dddce65fd87a8175a209a49f35615735a2886aBrian Osman    SkASSERT(texture);
204313dddce65fd87a8175a209a49f35615735a2886aBrian Osman    GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture);
204413dddce65fd87a8175a209a49f35615735a2886aBrian Osman    vkTexture->setImageLayout(this,
204513dddce65fd87a8175a209a49f35615735a2886aBrian Osman                              VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
204613dddce65fd87a8175a209a49f35615735a2886aBrian Osman                              VK_ACCESS_SHADER_READ_BIT,
204713dddce65fd87a8175a209a49f35615735a2886aBrian Osman                              VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
204813dddce65fd87a8175a209a49f35615735a2886aBrian Osman                              false);
204913dddce65fd87a8175a209a49f35615735a2886aBrian Osman    this->submitCommandBuffer(kSkip_SyncQueue);
205013dddce65fd87a8175a209a49f35615735a2886aBrian Osman
205113dddce65fd87a8175a209a49f35615735a2886aBrian Osman    // The image layout change serves as a barrier, so no semaphore is needed
205213dddce65fd87a8175a209a49f35615735a2886aBrian Osman    return nullptr;
205313dddce65fd87a8175a209a49f35615735a2886aBrian Osman}
2054