GrVkGpu.cpp revision 0b791f57c4a158fa3cab7250f0955b7f8abd5755
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
10164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrContextOptions.h"
11164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGeometryProcessor.h"
12164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGpuResourceCacheAccess.h"
130e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel#include "GrMesh.h"
14164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrPipeline.h"
15164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrRenderTargetPriv.h"
16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrSurfacePriv.h"
17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrTexturePriv.h"
18164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
19164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkCommandBuffer.h"
20066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpuCommandBuffer.h"
21164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkImage.h"
22164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkIndexBuffer.h"
23164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkMemory.h"
24164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkPipeline.h"
2522281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel#include "GrVkPipelineState.h"
26164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkRenderPass.h"
27164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkResourceProvider.h"
286be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel#include "GrVkSemaphore.h"
29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h"
30164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTextureRenderTarget.h"
31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTransferBuffer.h"
32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkVertexBuffer.h"
33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
34485c499a2797c1eb0e750fa4aaec57192799b424Matt Sarett#include "SkConvertPixels.h"
35900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth#include "SkMipMap.h"
36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
37164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vk/GrVkInterface.h"
38fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth#include "vk/GrVkTypes.h"
39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
40b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#include "SkSLCompiler.h"
41b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
42164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X)
43164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X)
44164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X)
45164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
46735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS
47d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverthVKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
48d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    VkDebugReportFlagsEXT       flags,
49d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    VkDebugReportObjectTypeEXT  objectType,
50d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    uint64_t                    object,
51d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    size_t                      location,
52d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    int32_t                     messageCode,
53d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    const char*                 pLayerPrefix,
54d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    const char*                 pMessage,
55d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    void*                       pUserData) {
56d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
57d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
58ce3fe23c04e93d2aa8d4c09c0c99088207edd509Jim Van Verth        return VK_TRUE; // skip further layers
59d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
60d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
61d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
62d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
63d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    } else {
64d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
65d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    }
66d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    return VK_FALSE;
67d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth}
68d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif
69d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth
70633b35657c964c32e7010b14bb2d396b4a764c52jvanverthGrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
71633b35657c964c32e7010b14bb2d396b4a764c52jvanverth                       GrContext* context) {
72dc0fcd41e75682a8bfd5e285d684461475226330bsalomon    const GrVkBackendContext* vkBackendContext =
73dc0fcd41e75682a8bfd5e285d684461475226330bsalomon        reinterpret_cast<const GrVkBackendContext*>(backendContext);
74633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    if (!vkBackendContext) {
75dc0fcd41e75682a8bfd5e285d684461475226330bsalomon        vkBackendContext = GrVkBackendContext::Create();
76633b35657c964c32e7010b14bb2d396b4a764c52jvanverth        if (!vkBackendContext) {
77633b35657c964c32e7010b14bb2d396b4a764c52jvanverth            return nullptr;
78164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
79633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    } else {
80633b35657c964c32e7010b14bb2d396b4a764c52jvanverth        vkBackendContext->ref();
81164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
82164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
83fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel    if (!vkBackendContext->fInterface->validate(vkBackendContext->fExtensions)) {
84fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel        return nullptr;
85fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel    }
86fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel
87633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    return new GrVkGpu(context, options, vkBackendContext);
88164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
89164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
90164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
91164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
929d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanaryGrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
93633b35657c964c32e7010b14bb2d396b4a764c52jvanverth                 const GrVkBackendContext* backendCtx)
94164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    : INHERITED(context)
95633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    , fDevice(backendCtx->fDevice)
96633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    , fQueue(backendCtx->fQueue)
97633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    , fResourceProvider(this) {
98633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fBackendContext.reset(backendCtx);
99164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
100735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS
101419ca64f0f800dc098369b5aa5a604acd017b240brianosman    fCallback = VK_NULL_HANDLE;
102fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth    if (backendCtx->fExtensions & kEXT_debug_report_GrVkExtensionFlag) {
103fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth        // Setup callback creation information
104d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        VkDebugReportCallbackCreateInfoEXT callbackCreateInfo;
105d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
106d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.pNext = nullptr;
107d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
108ef0c10cffefef90646ff2e238d7c2d82247a0370egdaniel                                   VK_DEBUG_REPORT_WARNING_BIT_EXT |
109d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth                                   //VK_DEBUG_REPORT_INFORMATION_BIT_EXT |
110d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth                                   //VK_DEBUG_REPORT_DEBUG_BIT_EXT |
111b4aa36211ca66ef127ac2954108742af1ead5082egdaniel                                   VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
112d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.pfnCallback = &DebugReportCallback;
113d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth        callbackCreateInfo.pUserData = nullptr;
114d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth
115fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth        // Register the callback
116a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth        GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateDebugReportCallbackEXT(
117a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth                            backendCtx->fInstance, &callbackCreateInfo, nullptr, &fCallback));
118d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth    }
119d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif
120633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
121b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas    fCompiler = new SkSL::Compiler();
122633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
123fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth    fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice,
124c5ec1408298510410270ea67e895570ccfa76e54egdaniel                               backendCtx->fFeatures, backendCtx->fExtensions));
125633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fCaps.reset(SkRef(fVkCaps.get()));
126633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
127633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps));
128633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
129633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    const VkCommandPoolCreateInfo cmdPoolInfo = {
1307ec92413307c9da43c013d1e4e15716a44059810jvanverth        VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
1317ec92413307c9da43c013d1e4e15716a44059810jvanverth        nullptr,                                         // pNext
1327ec92413307c9da43c013d1e4e15716a44059810jvanverth        VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
1337ec92413307c9da43c013d1e4e15716a44059810jvanverth        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // CmdPoolCreateFlags
1347ec92413307c9da43c013d1e4e15716a44059810jvanverth        backendCtx->fGraphicsQueueIndex,                 // queueFamilyIndex
135633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    };
1369d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateCommandPool(fDevice, &cmdPoolInfo, nullptr,
137633b35657c964c32e7010b14bb2d396b4a764c52jvanverth                                                               &fCmdPool));
138633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
139633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    // must call this after creating the CommandPool
140633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fResourceProvider.init();
1417ec92413307c9da43c013d1e4e15716a44059810jvanverth    fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer();
142633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    SkASSERT(fCurrentCmdBuffer);
143633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    fCurrentCmdBuffer->begin(this);
1446b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth
1456b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    // set up our heaps
1466b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kLinearImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024));
14705dceabf3422b785b52439378aa5527c42c6ca18egdaniel    // We want the OptimalImage_Heap to use a SubAlloc_strategy but it occasionally causes the
14805dceabf3422b785b52439378aa5527c42c6ca18egdaniel    // device to run out of memory. Most likely this is caused by fragmentation in the device heap
14905dceabf3422b785b52439378aa5527c42c6ca18egdaniel    // and we can't allocate more. Until we get a fix moving this to SingleAlloc.
15005dceabf3422b785b52439378aa5527c42c6ca18egdaniel    fHeaps[kOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 64*1024*1024));
1516b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kSmallOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 2*1024*1024));
1526b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kVertexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1536b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kIndexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1544c6e47a8a827077e36fa5feb4ab5ac7435d8276bjvanverth    fHeaps[kUniformBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 256*1024));
1556b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kCopyReadBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0));
1566b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    fHeaps[kCopyWriteBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024));
157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkGpu::~GrVkGpu() {
160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->end(this);
161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->unref(this);
162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // wait for all commands to finish
164ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth    fResourceProvider.checkCommandBuffers();
16509557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    VkResult res = VK_CALL(QueueWaitIdle(fQueue));
166f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel
167f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel    // On windows, sometimes calls to QueueWaitIdle return before actually signalling the fences
168f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel    // on the command buffers even though they have completed. This causes an assert to fire when
169f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel    // destroying the command buffers. Currently this ony seems to happen on windows, so we add a
17009557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    // sleep to make sure the fence signals.
171f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#ifdef SK_DEBUG
17280a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    if (this->vkCaps().mustSleepOnTearDown()) {
173f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#if defined(SK_BUILD_FOR_WIN)
17480a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel        Sleep(10); // In milliseconds
175f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#else
17680a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel        sleep(1);  // In seconds
177f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif
17880a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    }
179f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif
180f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel
181be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#ifdef SK_DEBUG
1828a8668b4721097de657ad8b30d45f60f62433c6fGreg Daniel    SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res);
183be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#endif
1849d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
1856be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
1866be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel        fSemaphoresToWaitOn[i]->unref(this);
1876be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    }
1886be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fSemaphoresToWaitOn.reset();
1896be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
190bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    fCopyManager.destroyResources(this);
191bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel
19209557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    // must call this just before we destroy the command pool and VkDevice
19309557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth    fResourceProvider.destroyResources(VK_ERROR_DEVICE_LOST == res);
194164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
195633b35657c964c32e7010b14bb2d396b4a764c52jvanverth    VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr));
196633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
197b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas    delete fCompiler;
198633b35657c964c32e7010b14bb2d396b4a764c52jvanverth
199735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS
200a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth    if (fCallback) {
201a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth        VK_CALL(DestroyDebugReportCallbackEXT(fBackendContext->fInstance, fCallback, nullptr));
202419ca64f0f800dc098369b5aa5a604acd017b240brianosman        fCallback = VK_NULL_HANDLE;
203a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth    }
204d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif
205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
206164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
207164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel///////////////////////////////////////////////////////////////////////////////
208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
2099cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpuCommandBuffer* GrVkGpu::createCommandBuffer(
2109cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
2119cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel            const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) {
212c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon    return new GrVkGpuCommandBuffer(this, colorInfo, stencilInfo);
213066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel}
214066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
2156be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrVkGpu::submitCommandBuffer(SyncQueue sync,
2166be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel                                  const GrVkSemaphore::Resource* signalSemaphore) {
217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->end(this);
219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
2206be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fCurrentCmdBuffer->submitToQueue(this, fQueue, sync, signalSemaphore, fSemaphoresToWaitOn);
2216be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
2226be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
2236be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel        fSemaphoresToWaitOn[i]->unref(this);
2246be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    }
2256be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fSemaphoresToWaitOn.reset();
2266be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
227164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fResourceProvider.checkCommandBuffers();
228164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
229164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Release old command buffer and create a new one
230164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->unref(this);
2317ec92413307c9da43c013d1e4e15716a44059810jvanverth    fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer();
232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->begin(this);
235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel///////////////////////////////////////////////////////////////////////////////
2381bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdaltonGrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern accessPattern,
2391bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton                                  const void* data) {
2401bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    GrBuffer* buff;
241397536cabe12a9936659870dd220c869789424bacdalton    switch (type) {
242397536cabe12a9936659870dd220c869789424bacdalton        case kVertex_GrBufferType:
243397536cabe12a9936659870dd220c869789424bacdalton            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
244397536cabe12a9936659870dd220c869789424bacdalton                     kStatic_GrAccessPattern == accessPattern);
2451bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
246e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
247397536cabe12a9936659870dd220c869789424bacdalton        case kIndex_GrBufferType:
248397536cabe12a9936659870dd220c869789424bacdalton            SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
249397536cabe12a9936659870dd220c869789424bacdalton                     kStatic_GrAccessPattern == accessPattern);
2501bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
251e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
252397536cabe12a9936659870dd220c869789424bacdalton        case kXferCpuToGpu_GrBufferType:
253c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth            SkASSERT(kStream_GrAccessPattern == accessPattern);
2541bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type);
255e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
256397536cabe12a9936659870dd220c869789424bacdalton        case kXferGpuToCpu_GrBufferType:
257c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth            SkASSERT(kStream_GrAccessPattern == accessPattern);
2581bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton            buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type);
259e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel            break;
260397536cabe12a9936659870dd220c869789424bacdalton        default:
261397536cabe12a9936659870dd220c869789424bacdalton            SkFAIL("Unknown buffer type.");
262397536cabe12a9936659870dd220c869789424bacdalton            return nullptr;
263397536cabe12a9936659870dd220c869789424bacdalton    }
2641bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    if (data && buff) {
2651bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton        buff->updateData(data, size);
2661bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    }
2671bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton    return buff;
268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                   GrPixelConfig srcConfig, DrawPreference* drawPreference,
273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                   WritePixelTempDrawInfo* tempDrawInfo) {
274d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman    if (GrPixelConfigIsCompressed(dstSurface->config())) {
275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
2784583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    GrRenderTarget* renderTarget = dstSurface->asRenderTarget();
2794583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
2804583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    // Start off assuming no swizzling
2814583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
2824583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fWriteConfig = srcConfig;
2834583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
2844583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    // These settings we will always want if a temp draw is performed. Initially set the config
2854583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    // to srcConfig, though that may be modified if we decide to do a R/B swap
2864583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
2874583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
2884583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
2894583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
2904583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
2914583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
2924583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
293d66110f5972169dbcda8932c3a9a001adff23df4egdaniel    if (dstSurface->config() == srcConfig) {
294d66110f5972169dbcda8932c3a9a001adff23df4egdaniel        return true;
295d66110f5972169dbcda8932c3a9a001adff23df4egdaniel    }
296d66110f5972169dbcda8932c3a9a001adff23df4egdaniel
29766933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (renderTarget && this->vkCaps().isConfigRenderable(renderTarget->config(),
29866933552f1723c4a2b248711ab3d43921401e8e6egdaniel                                                          renderTarget->numColorSamples() > 1)) {
2994583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
3004583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
3014583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
3024583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
3034583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) {
3044583ec51d9ddc830eeb854db068235be96ce59c4egdaniel            if (!this->vkCaps().isConfigTexturable(dstSurface->config())) {
3054583ec51d9ddc830eeb854db068235be96ce59c4egdaniel                return false;
3064583ec51d9ddc830eeb854db068235be96ce59c4egdaniel            }
3074583ec51d9ddc830eeb854db068235be96ce59c4egdaniel            tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
3084583ec51d9ddc830eeb854db068235be96ce59c4egdaniel            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
3094583ec51d9ddc830eeb854db068235be96ce59c4egdaniel            tempDrawInfo->fWriteConfig = dstSurface->config();
3104583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        }
3114583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        return true;
312164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
313164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
3144583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    return false;
315164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
316164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
317164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onWritePixels(GrSurface* surface,
318164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            int left, int top, int width, int height,
319a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon                            GrPixelConfig config,
320a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon                            const SkTArray<GrMipLevel>& texels) {
321164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture());
322164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!vkTex) {
323164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
324164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
325164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
326900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Make sure we have at least the base level
32703509eafa3e25819ff69f4d4f339d46264820c38jvanverth    if (texels.empty() || !texels.begin()->fPixels) {
32803509eafa3e25819ff69f4d4f339d46264820c38jvanverth        return false;
32903509eafa3e25819ff69f4d4f339d46264820c38jvanverth    }
330a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon
331164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
332164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
333164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
334164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
335164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
336164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool success = false;
337164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) {
338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo()
339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        SkASSERT(config == vkTex->desc().fConfig);
340164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // TODO: add compressed texture support
341164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // delete the following two lines and uncomment the two after that when ready
342164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        vkTex->unref();
343164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
344164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false, left, top, width,
345164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        //                                       height);
346164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    } else {
347164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        bool linearTiling = vkTex->isLinearTiled();
348900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        if (linearTiling) {
349900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            if (texels.count() > 1) {
350900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                SkDebugf("Can't upload mipmap data to linear tiled texture");
351900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                return false;
352900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            }
353900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            if (VK_IMAGE_LAYOUT_PREINITIALIZED != vkTex->currentLayout()) {
354900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                // Need to change the layout to general in order to perform a host write
355900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                vkTex->setImageLayout(this,
356900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                      VK_IMAGE_LAYOUT_GENERAL,
35750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                                      VK_ACCESS_HOST_WRITE_BIT,
35850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                                      VK_PIPELINE_STAGE_HOST_BIT,
359900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                      false);
360bdf8811b3126ab08ccff08b5e647b80cae5bd087egdaniel                this->submitCommandBuffer(kForce_SyncQueue);
361900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            }
362900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            success = this->uploadTexDataLinear(vkTex, left, top, width, height, config,
363900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                texels.begin()->fPixels, texels.begin()->fRowBytes);
364900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        } else {
365c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth            int newMipLevels = texels.count();
36682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth            int currentMipLevels = vkTex->texturePriv().maxMipMapLevel() + 1;
36782c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth            if (newMipLevels != currentMipLevels) {
368c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                if (!vkTex->reallocForMipmap(this, newMipLevels)) {
369900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                    return false;
370900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                }
371900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            }
372900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config, texels);
373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
374164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
3754583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
376900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    return success;
377164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
378164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
3794bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielvoid GrVkGpu::resolveImage(GrVkRenderTarget* dst, GrVkRenderTarget* src, const SkIRect& srcRect,
3804bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                           const SkIPoint& dstPoint) {
3814bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkASSERT(dst);
3824bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage());
3834bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
384fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) {
385fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel        this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue);
386fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    }
387fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel
3884bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // Flip rect if necessary
3894bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkIRect srcVkRect = srcRect;
3904bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    int32_t dstY = dstPoint.fY;
3914bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
3924bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
3934bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin());
3944bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcVkRect.fTop = src->height() - srcRect.fBottom;
3954bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcVkRect.fBottom = src->height() - srcRect.fTop;
3964bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        dstY = dst->height() - dstPoint.fY - srcVkRect.height();
3974bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
3984bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
3994bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    VkImageResolve resolveInfo;
4004bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
4014bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
4024bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
4034bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.dstOffset = { dstPoint.fX, dstY, 0 };
4044bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 };
4054bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
4064bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    dst->setImageLayout(this,
4074bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4084bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                        VK_ACCESS_TRANSFER_WRITE_BIT,
4094bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                        VK_PIPELINE_STAGE_TRANSFER_BIT,
4104bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                        false);
4114bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
4124bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    src->msaaImage()->setImageLayout(this,
4134bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4144bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     VK_ACCESS_TRANSFER_READ_BIT,
4154bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     VK_PIPELINE_STAGE_TRANSFER_BIT,
4164bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                     false);
4174bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
4184bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    fCurrentCmdBuffer->resolveImage(this, *src->msaaImage(), *dst, 1, &resolveInfo);
4194bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel}
4204bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
42169d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Danielvoid GrVkGpu::internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit) {
42266933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (target->needsResolve()) {
42366933552f1723c4a2b248711ab3d43921401e8e6egdaniel        SkASSERT(target->numColorSamples() > 1);
42452ad25151a1c7d1ac3872971f56adf15200c437eegdaniel        GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target);
42552ad25151a1c7d1ac3872971f56adf15200c437eegdaniel        SkASSERT(rt->msaaImage());
42669d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel
4274bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        const SkIRect& srcRect = rt->getResolveRect();
42852ad25151a1c7d1ac3872971f56adf15200c437eegdaniel
4294bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        this->resolveImage(rt, rt, srcRect, SkIPoint::Make(srcRect.fLeft, srcRect.fTop));
43052ad25151a1c7d1ac3872971f56adf15200c437eegdaniel
43152ad25151a1c7d1ac3872971f56adf15200c437eegdaniel        rt->flagAsResolved();
43269d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel
43369d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel        if (requiresSubmit) {
43469d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel            this->submitCommandBuffer(kSkip_SyncQueue);
43569d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel        }
43652ad25151a1c7d1ac3872971f56adf15200c437eegdaniel    }
43752ad25151a1c7d1ac3872971f56adf15200c437eegdaniel}
43852ad25151a1c7d1ac3872971f56adf15200c437eegdaniel
439900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex,
440900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  int left, int top, int width, int height,
441900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  GrPixelConfig dataConfig,
442900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  const void* data,
443900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                  size_t rowBytes) {
444164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(data);
445900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(tex->isLinearTiled());
446164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
447164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // If we're uploading compressed data then we should be using uploadCompressedTexData
448164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
449164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
450164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    size_t bpp = GrBytesPerPixel(dataConfig);
451164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
452164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    const GrSurfaceDesc& desc = tex->desc();
453164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
454164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top,
455164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                               &width, &height, &data, &rowBytes)) {
456164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
457164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
458164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    size_t trimRowBytes = width * bpp;
459164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
460900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == tex->currentLayout() ||
461900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth             VK_IMAGE_LAYOUT_GENERAL == tex->currentLayout());
462900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    const VkImageSubresource subres = {
463900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        VK_IMAGE_ASPECT_COLOR_BIT,
464900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        0,  // mipLevel
465900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        0,  // arraySlice
466900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    };
467900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    VkSubresourceLayout layout;
468900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    VkResult err;
469900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
470900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    const GrVkInterface* interface = this->vkInterface();
471900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
472900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice,
473b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                                    tex->image(),
474900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                    &subres,
475900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                    &layout));
476900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
477900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    int texTop = kBottomLeft_GrSurfaceOrigin == desc.fOrigin ? tex->height() - top - height : top;
4781e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    const GrVkAlloc& alloc = tex->alloc();
4791e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    VkDeviceSize offset = alloc.fOffset + texTop*layout.rowPitch + left*bpp;
480900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    VkDeviceSize size = height*layout.rowPitch;
481900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    void* mapPtr;
4821e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    err = GR_VK_CALL(interface, MapMemory(fDevice, alloc.fMemory, offset, size, 0, &mapPtr));
483900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    if (err) {
484900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        return false;
485900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
486164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
487900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
488900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        // copy into buffer by rows
489900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        const char* srcRow = reinterpret_cast<const char*>(data);
490900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*layout.rowPitch;
491900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        for (int y = 0; y < height; y++) {
492900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            memcpy(dstRow, srcRow, trimRowBytes);
493900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            srcRow += rowBytes;
494900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            dstRow -= layout.rowPitch;
495900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        }
496900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    } else {
497cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett        SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, trimRowBytes,
498cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett                     height);
499900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
500164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
5019d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkMemory::FlushMappedAlloc(this, alloc);
5021e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    GR_VK_CALL(interface, UnmapMemory(fDevice, alloc.fMemory));
503900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
504900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    return true;
505900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth}
506900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
507900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
508a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth                                   int left, int top, int width, int height,
509a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth                                   GrPixelConfig dataConfig,
510a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth                                   const SkTArray<GrMipLevel>& texels) {
511900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(!tex->isLinearTiled());
512900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // The assumption is either that we have no mipmaps, or that our rect is the entire texture
513900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(1 == texels.count() ||
514900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth             (0 == left && 0 == top && width == tex->width() && height == tex->height()));
515900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
516900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // If we're uploading compressed data then we should be using uploadCompressedTexData
517900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
518900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
519900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    if (width == 0 || height == 0) {
520900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        return false;
521900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
522900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
523900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    const GrSurfaceDesc& desc = tex->desc();
524900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
525900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    size_t bpp = GrBytesPerPixel(dataConfig);
526900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
527900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // texels is const.
528c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // But we may need to adjust the fPixels ptr based on the copyRect, or fRowBytes.
529c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // Because of this we need to make a non-const shallow copy of texels.
530c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    SkTArray<GrMipLevel> texelsShallowCopy(texels);
531900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
532c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
533c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth         currentMipLevel--) {
534c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        SkASSERT(texelsShallowCopy[currentMipLevel].fPixels);
535900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
536900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
537900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Determine whether we need to flip when we copy into the buffer
538c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty());
539900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
540c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // adjust any params (left, top, currentWidth, currentHeight
541900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // find the combined size of all the mip levels and the relative offset of
542900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // each into the collective buffer
543c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // Do the first level separately because we may need to adjust width and height
544c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    // (for the non-mipped case).
545c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top,
546c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                               &width,
547c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                               &height,
548c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                               &texelsShallowCopy[0].fPixels,
549c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                               &texelsShallowCopy[0].fRowBytes)) {
550c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        return false;
551c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    }
552c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    SkTArray<size_t> individualMipOffsets(texelsShallowCopy.count());
553c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    individualMipOffsets.push_back(0);
554c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    size_t combinedBufferSize = width * bpp * height;
555c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    int currentWidth = width;
556c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    int currentHeight = height;
557c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    for (int currentMipLevel = 1; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
558c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentWidth = SkTMax(1, currentWidth/2);
559c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentHeight = SkTMax(1, currentHeight/2);
560c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top,
561c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                                   &currentWidth,
562c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                                   &currentHeight,
563c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                                   &texelsShallowCopy[currentMipLevel].fPixels,
564c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth                                                   &texelsShallowCopy[currentMipLevel].fRowBytes)) {
565c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth            return false;
566c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        }
567900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        const size_t trimmedSize = currentWidth * bpp * currentHeight;
568900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        individualMipOffsets.push_back(combinedBufferSize);
569900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        combinedBufferSize += trimmedSize;
570900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
571900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
572900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // allocate buffer to hold our mip data
573900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    GrVkTransferBuffer* transferBuffer =
574900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                   GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuffer::kCopyRead_Type);
575900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
576900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    char* buffer = (char*) transferBuffer->map();
577c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    SkTArray<VkBufferImageCopy> regions(texelsShallowCopy.count());
578900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
579c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    currentWidth = width;
580c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    currentHeight = height;
581c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) {
582900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        const size_t trimRowBytes = currentWidth * bpp;
583c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes;
584900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
585900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        // copy data into the buffer, skipping the trailing bytes
586900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        char* dst = buffer + individualMipOffsets[currentMipLevel];
587c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels;
588900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        if (flipY) {
589900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            src += (currentHeight - 1) * rowBytes;
590900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            for (int y = 0; y < currentHeight; y++) {
591900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                memcpy(dst, src, trimRowBytes);
592900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                src -= rowBytes;
593900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                dst += trimRowBytes;
594164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            }
595164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        } else {
596900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, currentHeight);
597164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
598164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
599900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        VkBufferImageCopy& region = regions.push_back();
600164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        memset(&region, 0, sizeof(VkBufferImageCopy));
601db37909347d034943bd6b0922710a94c6c6ea572jvanverth        region.bufferOffset = transferBuffer->offset() + individualMipOffsets[currentMipLevel];
602900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        region.bufferRowLength = currentWidth;
603900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        region.bufferImageHeight = currentHeight;
604cf942c4ef750712b624867cbb2217c14857db3c6bsalomon        region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMipLevel), 0, 1 };
605c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        region.imageOffset = { left, flipY ? tex->height() - top - currentHeight : top, 0 };
606900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 };
6074583ec51d9ddc830eeb854db068235be96ce59c4egdaniel
608c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentWidth = SkTMax(1, currentWidth/2);
609c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth        currentHeight = SkTMax(1, currentHeight/2);
610900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    }
611164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
6129d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    // no need to flush non-coherent memory, unmap will do that for us
613900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    transferBuffer->unmap();
614164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
615900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Change layout of our target so it can be copied to
616900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    tex->setImageLayout(this,
617900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
61850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                        VK_ACCESS_TRANSFER_WRITE_BIT,
61950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                        VK_PIPELINE_STAGE_TRANSFER_BIT,
620900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                        false);
621900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
622900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // Copy the buffer to the image
623900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    fCurrentCmdBuffer->copyBufferToImage(this,
624900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         transferBuffer,
625900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         tex,
626900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
627900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         regions.count(),
628900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                         regions.begin());
629900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    transferBuffer->unref();
630164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
631164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return true;
632164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
633164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
634164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
6352e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunenGrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
636a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon                                    const SkTArray<GrMipLevel>& texels) {
637164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
638164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
639164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkFormat pixelFormat;
640164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) {
641164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
642164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
643164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
644164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!fVkCaps->isConfigTexturable(desc.fConfig)) {
645164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
646164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
647164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
6480a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    if (renderTarget && !fVkCaps->isConfigRenderable(desc.fConfig, false)) {
6490a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        return nullptr;
6500a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    }
6510a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel
652164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool linearTiling = false;
653164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (SkToBool(desc.fFlags & kZeroCopy_GrSurfaceFlag)) {
654900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        // we can't have a linear texture with a mipmap
655900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        if (texels.count() > 1) {
656900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            SkDebugf("Trying to create linear tiled texture with mipmap");
657900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            return nullptr;
658900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        }
659a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel        if (fVkCaps->isConfigTexturableLinearly(desc.fConfig) &&
660164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            (!renderTarget || fVkCaps->isConfigRenderableLinearly(desc.fConfig, false))) {
661164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            linearTiling = true;
662164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        } else {
663164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            return nullptr;
664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
666164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
667164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
668164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (renderTarget) {
669164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
670164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
671164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
672164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and
673164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we
674164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // will be using this texture in some copy or not. Also this assumes, as is the current case,
67562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // that all render targets in vulkan are also textures. If we change this practice of setting
676164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // both bits, we must make sure to set the destination bit if we are uploading srcData to the
677164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // texture.
678164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
679164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
680a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon    VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
681a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon                                                           VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
682164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
683164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is
68462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // requested, this ImageDesc describes the resolved texture. Therefore we always have samples set
685164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // to 1.
686c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    int mipLevels = texels.empty() ? 1 : texels.count();
687164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkImage::ImageDesc imageDesc;
688164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fImageType = VK_IMAGE_TYPE_2D;
689164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fFormat = pixelFormat;
690164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fWidth = desc.fWidth;
691164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fHeight = desc.fHeight;
692c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth    imageDesc.fLevels = linearTiling ? 1 : mipLevels;
693164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fSamples = 1;
694164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
695164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fUsageFlags = usageFlags;
696164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    imageDesc.fMemProps = memProps;
697164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
698164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkTexture* tex;
699164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (renderTarget) {
7002e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, desc,
701164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                    imageDesc);
702164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    } else {
7032e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen        tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc);
704164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
705164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
706164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!tex) {
707164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
708164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
709164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
710e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon    if (!texels.empty()) {
711e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon        SkASSERT(texels.begin()->fPixels);
712900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        bool success;
713900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        if (linearTiling) {
714900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            success = this->uploadTexDataLinear(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
715900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                texels.begin()->fPixels, texels.begin()->fRowBytes);
716900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        } else {
717900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth            success = this->uploadTexDataOptimal(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
718900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                                 texels);
719900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        }
720900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        if (!success) {
721164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            tex->unref();
722164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            return nullptr;
723164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
724164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
725164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
726164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return tex;
727164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
728164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
729164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
730164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
731db37909347d034943bd6b0922710a94c6c6ea572jvanverthbool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src,
732db37909347d034943bd6b0922710a94c6c6ea572jvanverth                           VkDeviceSize offset, VkDeviceSize size) {
733a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
734a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth    // Update the buffer
735db37909347d034943bd6b0922710a94c6c6ea572jvanverth    fCurrentCmdBuffer->updateBuffer(this, buffer, offset, size, src);
736a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
737a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth    return true;
738a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth}
739a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
740a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth////////////////////////////////////////////////////////////////////////////////
741a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth
742164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) {
743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // By default, all textures in Vk use TopLeft
744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (kDefault_GrSurfaceOrigin == origin) {
745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return kTopLeft_GrSurfaceOrigin;
746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    } else {
747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return origin;
748164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
750164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
7516bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
7526bd5284415bd983b0628c4941dff5def40018f5abungeman                                               GrWrapOwnership ownership) {
753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (0 == desc.fTextureHandle) {
754164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int maxSize = this->caps()->maxTextureSize();
758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return nullptr;
760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
762b2df0c2702329be6380a943d548e7377a51d8565egdaniel    const GrVkImageInfo* info = reinterpret_cast<const GrVkImageInfo*>(desc.fTextureHandle);
7631e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc.fMemory) {
764fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        return nullptr;
765fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    }
766b2df0c2702329be6380a943d548e7377a51d8565egdaniel#ifdef SK_DEBUG
767b2df0c2702329be6380a943d548e7377a51d8565egdaniel    VkFormat format;
768b2df0c2702329be6380a943d548e7377a51d8565egdaniel    if (!GrPixelConfigToVkFormat(desc.fConfig, &format)) {
769b2df0c2702329be6380a943d548e7377a51d8565egdaniel        return nullptr;
770b2df0c2702329be6380a943d548e7377a51d8565egdaniel    }
771b2df0c2702329be6380a943d548e7377a51d8565egdaniel    SkASSERT(format == info->fFormat);
772b2df0c2702329be6380a943d548e7377a51d8565egdaniel#endif
773164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
774164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrSurfaceDesc surfDesc;
775164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // next line relies on GrBackendTextureDesc's flags matching GrTexture's
776164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags;
777164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    surfDesc.fWidth = desc.fWidth;
778164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    surfDesc.fHeight = desc.fHeight;
779164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    surfDesc.fConfig = desc.fConfig;
780164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount());
781164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
782164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // In GL, Chrome assumes all textures are BottomLeft
783164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // In VK, we don't have this restriction
784164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    surfDesc.fOrigin = resolve_origin(desc.fOrigin);
785164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
7866bd5284415bd983b0628c4941dff5def40018f5abungeman    if (!renderTarget) {
7876bd5284415bd983b0628c4941dff5def40018f5abungeman        return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, info);
788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
7896bd5284415bd983b0628c4941dff5def40018f5abungeman    return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership, info);
790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
791164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
7920b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osmansk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc){
7939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
794b2df0c2702329be6380a943d548e7377a51d8565egdaniel    const GrVkImageInfo* info =
795b2df0c2702329be6380a943d548e7377a51d8565egdaniel        reinterpret_cast<const GrVkImageInfo*>(wrapDesc.fRenderTargetHandle);
7960b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman    if (VK_NULL_HANDLE == info->fImage) {
797fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        return nullptr;
798fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    }
799164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrSurfaceDesc desc;
801164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    desc.fConfig = wrapDesc.fConfig;
8023667b4970d6972675be58a331be7c5ba02f3d39eRobert Phillips    desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag;
803164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    desc.fWidth = wrapDesc.fWidth;
804164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    desc.fHeight = wrapDesc.fHeight;
805164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount());
806164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
807164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    desc.fOrigin = resolve_origin(wrapDesc.fOrigin);
808164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
8090b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman    sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info);
810164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (tgt && wrapDesc.fStencilBits) {
8116bd5284415bd983b0628c4941dff5def40018f5abungeman        if (!createStencilAttachmentForRenderTarget(tgt.get(), desc.fWidth, desc.fHeight)) {
812164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            return nullptr;
813164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
814164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
815164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return tgt;
816164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
817164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
81850ead53ac97deb23310916e3736c3f5e2d8f7f4begdanielvoid GrVkGpu::generateMipmap(GrVkTexture* tex) {
819900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    // don't do anything for linearly tiled textures (can't have mipmaps)
82062340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    if (tex->isLinearTiled()) {
821900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth        SkDebugf("Trying to create mipmap for linear tiled texture");
82262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        return;
82362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    }
82462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
82562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // determine if we can blit to and from this format
82662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    const GrVkCaps& caps = this->vkCaps();
82762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    if (!caps.configCanBeDstofBlit(tex->config(), false) ||
8282f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel        !caps.configCanBeSrcofBlit(tex->config(), false) ||
8292f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel        !caps.mipMapSupport()) {
83062340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        return;
83162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    }
83262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
833fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) {
834fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel        this->submitCommandBuffer(kSkip_SyncQueue);
835fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    }
836fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel
83766933552f1723c4a2b248711ab3d43921401e8e6egdaniel    // We may need to resolve the texture first if it is also a render target
83866933552f1723c4a2b248711ab3d43921401e8e6egdaniel    GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(tex->asRenderTarget());
83966933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (texRT) {
84069d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel        this->internalResolveRenderTarget(texRT, false);
84166933552f1723c4a2b248711ab3d43921401e8e6egdaniel    }
84266933552f1723c4a2b248711ab3d43921401e8e6egdaniel
8437ac5da853457b032781cf865ba018de78508edb7egdaniel    int width = tex->width();
8447ac5da853457b032781cf865ba018de78508edb7egdaniel    int height = tex->height();
8457ac5da853457b032781cf865ba018de78508edb7egdaniel    VkImageBlit blitRegion;
8467ac5da853457b032781cf865ba018de78508edb7egdaniel    memset(&blitRegion, 0, sizeof(VkImageBlit));
84762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
84882c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    // SkMipMap doesn't include the base level in the level count so we have to add 1
84982c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height()) + 1;
8507ac5da853457b032781cf865ba018de78508edb7egdaniel    if (levelCount != tex->mipLevels()) {
8517ac5da853457b032781cf865ba018de78508edb7egdaniel        const GrVkResource* oldResource = tex->resource();
8527ac5da853457b032781cf865ba018de78508edb7egdaniel        oldResource->ref();
8537ac5da853457b032781cf865ba018de78508edb7egdaniel        // grab handle to the original image resource
8547ac5da853457b032781cf865ba018de78508edb7egdaniel        VkImage oldImage = tex->image();
8557ac5da853457b032781cf865ba018de78508edb7egdaniel
8567ac5da853457b032781cf865ba018de78508edb7egdaniel        // change the original image's layout so we can copy from it
8577ac5da853457b032781cf865ba018de78508edb7egdaniel        tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8587ac5da853457b032781cf865ba018de78508edb7egdaniel                            VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
8597ac5da853457b032781cf865ba018de78508edb7egdaniel
8607ac5da853457b032781cf865ba018de78508edb7egdaniel        if (!tex->reallocForMipmap(this, levelCount)) {
8617ac5da853457b032781cf865ba018de78508edb7egdaniel            oldResource->unref(this);
8627ac5da853457b032781cf865ba018de78508edb7egdaniel            return;
8637ac5da853457b032781cf865ba018de78508edb7egdaniel        }
8647ac5da853457b032781cf865ba018de78508edb7egdaniel        // change the new image's layout so we can blit to it
8657ac5da853457b032781cf865ba018de78508edb7egdaniel        tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL,
8667ac5da853457b032781cf865ba018de78508edb7egdaniel                            VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
86762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
8687ac5da853457b032781cf865ba018de78508edb7egdaniel        // Blit original image to top level of new image
8697ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
8707ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.srcOffsets[0] = { 0, 0, 0 };
8717ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.srcOffsets[1] = { width, height, 1 };
8727ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
8737ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.dstOffsets[0] = { 0, 0, 0 };
8747ac5da853457b032781cf865ba018de78508edb7egdaniel        blitRegion.dstOffsets[1] = { width, height, 1 };
87562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
8767ac5da853457b032781cf865ba018de78508edb7egdaniel        fCurrentCmdBuffer->blitImage(this,
8777ac5da853457b032781cf865ba018de78508edb7egdaniel                                     oldResource,
8787ac5da853457b032781cf865ba018de78508edb7egdaniel                                     oldImage,
8797ac5da853457b032781cf865ba018de78508edb7egdaniel                                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8807ac5da853457b032781cf865ba018de78508edb7egdaniel                                     tex->resource(),
8817ac5da853457b032781cf865ba018de78508edb7egdaniel                                     tex->image(),
8827ac5da853457b032781cf865ba018de78508edb7egdaniel                                     VK_IMAGE_LAYOUT_GENERAL,
8837ac5da853457b032781cf865ba018de78508edb7egdaniel                                     1,
8847ac5da853457b032781cf865ba018de78508edb7egdaniel                                     &blitRegion,
8857ac5da853457b032781cf865ba018de78508edb7egdaniel                                     VK_FILTER_LINEAR);
88662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
8877ac5da853457b032781cf865ba018de78508edb7egdaniel        oldResource->unref(this);
8887ac5da853457b032781cf865ba018de78508edb7egdaniel    } else {
8897ac5da853457b032781cf865ba018de78508edb7egdaniel        // change layout of the layers so we can write to them.
8907ac5da853457b032781cf865ba018de78508edb7egdaniel        tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL,
8917ac5da853457b032781cf865ba018de78508edb7egdaniel                            VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false);
8927ac5da853457b032781cf865ba018de78508edb7egdaniel    }
89350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth
89450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    // setup memory barrier
895b2df0c2702329be6380a943d548e7377a51d8565egdaniel    SkASSERT(GrVkFormatToPixelConfig(tex->imageFormat(), nullptr));
89650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
89750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    VkImageMemoryBarrier imageMemoryBarrier = {
89850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,          // sType
89950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        NULL,                                            // pNext
9007ac5da853457b032781cf865ba018de78508edb7egdaniel        VK_ACCESS_TRANSFER_WRITE_BIT,                    // srcAccessMask
9017ac5da853457b032781cf865ba018de78508edb7egdaniel        VK_ACCESS_TRANSFER_READ_BIT,                     // dstAccessMask
90250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_IMAGE_LAYOUT_GENERAL,                         // oldLayout
90350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_IMAGE_LAYOUT_GENERAL,                         // newLayout
90450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_QUEUE_FAMILY_IGNORED,                         // srcQueueFamilyIndex
90550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        VK_QUEUE_FAMILY_IGNORED,                         // dstQueueFamilyIndex
906b2df0c2702329be6380a943d548e7377a51d8565egdaniel        tex->image(),                                    // image
90750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        { aspectFlags, 0, 1, 0, 1 }                      // subresourceRange
90850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth    };
90950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth
91062340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    // Blit the miplevels
91182c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    uint32_t mipLevel = 1;
91282c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth    while (mipLevel < levelCount) {
91382c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        int prevWidth = width;
91482c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        int prevHeight = height;
91582c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        width = SkTMax(1, width / 2);
91682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        height = SkTMax(1, height / 2);
91782c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth
91850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        imageMemoryBarrier.subresourceRange.baseMipLevel = mipLevel - 1;
91950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        this->addImageMemoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
92050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                                    false, &imageMemoryBarrier);
92150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth
92250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth        blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel - 1, 0, 1 };
92362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        blitRegion.srcOffsets[0] = { 0, 0, 0 };
924e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman        blitRegion.srcOffsets[1] = { prevWidth, prevHeight, 1 };
92582c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 };
92662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        blitRegion.dstOffsets[0] = { 0, 0, 0 };
927e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman        blitRegion.dstOffsets[1] = { width, height, 1 };
92862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth        fCurrentCmdBuffer->blitImage(this,
929b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                     *tex,
930b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                     *tex,
93162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth                                     1,
93262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth                                     &blitRegion,
93362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth                                     VK_FILTER_LINEAR);
93482c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth        ++mipLevel;
93562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth    }
93662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth}
93762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth
938164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
939164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
940164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
941164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                     int width,
942164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                     int height) {
943164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(width >= rt->width());
944164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(height >= rt->height());
945164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
946164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int samples = rt->numStencilSamples();
947164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
9488f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10egdaniel    const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat();
949164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
950164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this,
951164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 width,
952164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 height,
953164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 samples,
954164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                 sFmt));
955164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fStats.incStencilAttachmentCreates();
956164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return stencil;
957164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
958164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
959164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
960164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
9619d54afc38b171c01a03b34e773d154fcf83d97dcjvanverthbool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc,
9623602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                       size_t srcRowBytes, size_t dstRowBytes, int h) {
9633602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    void* mapPtr;
9643602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(),
9659d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth                                                            alloc.fMemory,
9669d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth                                                            alloc.fOffset,
9673602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                            dstRowBytes * h,
9683602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                            0,
9693602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                            &mapPtr));
9703602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    if (err) {
9713602d4f16a01da860d16eb36fb52eb62487495ccegdaniel        return false;
9723602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    }
9733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
9743602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    // If there is no padding on dst we can do a single memcopy.
9753602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    // This assumes the srcData comes in with no padding.
976cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett    SkRectMemcpy(mapPtr, static_cast<size_t>(dstRowBytes), srcData, srcRowBytes, srcRowBytes, h);
9779d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkMemory::FlushMappedAlloc(gpu, alloc);
9789d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GR_VK_CALL(gpu->vkInterface(), UnmapMemory(gpu->device(), alloc.fMemory));
9793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel    return true;
9803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel}
9813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
982164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h,
9830a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel                                                         GrPixelConfig config,
9840a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel                                                         bool isRenderTarget) {
985164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
986164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkFormat pixelFormat;
987164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
988164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return 0;
989164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
990164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
991164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool linearTiling = false;
992164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!fVkCaps->isConfigTexturable(config)) {
993164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return 0;
994164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
995164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
9960a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) {
9970a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        return 0;
9980a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    }
9990a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel
1000a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel    if (fVkCaps->isConfigTexturableLinearly(config) &&
10010a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        (!isRenderTarget || fVkCaps->isConfigRenderableLinearly(config, false))) {
1002164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        linearTiling = true;
1003164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1004164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1005164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
1006164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1007164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
10080a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    if (isRenderTarget) {
10090a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel        usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
10100a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel    }
1011164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1012fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkImage image = VK_NULL_HANDLE;
10139d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkAlloc alloc = { VK_NULL_HANDLE, 0, 0, 0 };
1014164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1015fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1016fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling)
1017fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth                                ? VK_IMAGE_LAYOUT_PREINITIALIZED
1018fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth                                : VK_IMAGE_LAYOUT_UNDEFINED;
1019fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1020fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    // Create Image
1021fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    VkSampleCountFlagBits vkSamples;
1022fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    if (!GrSampleCountToVkSampleCount(1, &vkSamples)) {
1023fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        return 0;
1024fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    }
1025fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1026fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    const VkImageCreateInfo imageCreateInfo = {
1027fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,         // sType
1028fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        NULL,                                        // pNext
1029fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        0,                                           // VkImageCreateFlags
1030fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_IMAGE_TYPE_2D,                            // VkImageType
1031fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        pixelFormat,                                 // VkFormat
1032384b5e9cd36e443437de8df3b0f78ef4150efbacethannicholas        { (uint32_t) w, (uint32_t) h, 1 },           // VkExtent3D
1033fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        1,                                           // mipLevels
1034fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        1,                                           // arrayLayers
1035fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        vkSamples,                                   // samples
1036fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        imageTiling,                                 // VkImageTiling
1037fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        usageFlags,                                  // VkImageUsageFlags
1038fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_SHARING_MODE_EXCLUSIVE,                   // VkSharingMode
1039fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        0,                                           // queueFamilyCount
1040fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        0,                                           // pQueueFamilyIndices
1041fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        initialLayout                                // initialLayout
1042fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    };
1043fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1044fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image));
1045fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
10466b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    if (!GrVkMemory::AllocAndBindImageMemory(this, image, linearTiling, &alloc)) {
1047fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        VK_CALL(DestroyImage(this->device(), image, nullptr));
1048164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return 0;
1049164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1050164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1051164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (srcData) {
10523602d4f16a01da860d16eb36fb52eb62487495ccegdaniel        size_t bpp = GrBytesPerPixel(config);
10533602d4f16a01da860d16eb36fb52eb62487495ccegdaniel        size_t rowCopyBytes = bpp * w;
1054164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        if (linearTiling) {
1055164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            const VkImageSubresource subres = {
1056164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                VK_IMAGE_ASPECT_COLOR_BIT,
1057164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                0,  // mipLevel
1058164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                0,  // arraySlice
1059164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            };
1060164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            VkSubresourceLayout layout;
1061164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1062fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth            VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout));
1063164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
10649d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth            if (!copy_testing_data(this, srcData, alloc, rowCopyBytes,
1065583bc2e98d8105fc799897daea28eea03c23fbbcbrianosman                                   static_cast<size_t>(layout.rowPitch), h)) {
10663602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
10673602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyImage(fDevice, image, nullptr));
10683602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                return 0;
10693602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            }
10703602d4f16a01da860d16eb36fb52eb62487495ccegdaniel        } else {
10713602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            SkASSERT(w && h);
10723602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
10733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkBuffer buffer;
10743602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkBufferCreateInfo bufInfo;
10753602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            memset(&bufInfo, 0, sizeof(VkBufferCreateInfo));
10763602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10773602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.flags = 0;
10783602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.size = rowCopyBytes * h;
10793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
10803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
10813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.queueFamilyIndexCount = 0;
10823602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            bufInfo.pQueueFamilyIndices = nullptr;
10833602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkResult err;
10843602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(CreateBuffer(fDevice, &bufInfo, nullptr, &buffer));
10853602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
1086164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            if (err) {
10876b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth                GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
10883602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyImage(fDevice, image, nullptr));
1089164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                return 0;
1090164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            }
1091164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
10929d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth            GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
10933602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type,
10943602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                                      true, &bufferAlloc)) {
10953602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
10963602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyImage(fDevice, image, nullptr));
10973602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
10983602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                return 0;
1099164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel            }
11003602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11019d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth            if (!copy_testing_data(this, srcData, bufferAlloc, rowCopyBytes, rowCopyBytes, h)) {
11023602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
11033602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyImage(fDevice, image, nullptr));
11043602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
11053602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
11063602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                return 0;
11073602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            }
11083602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11093602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            const VkCommandBufferAllocateInfo cmdInfo = {
11103602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,   // sType
11113602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                NULL,                                             // pNext
11123602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                fCmdPool,                                         // commandPool
11133602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_COMMAND_BUFFER_LEVEL_PRIMARY,                  // level
11143602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                1                                                 // bufferCount
11153602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            };
11163602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11173602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkCommandBuffer cmdBuffer;
11183602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer));
11193602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            if (err) {
11203602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
11213602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyImage(fDevice, image, nullptr));
11223602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
11233602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
11243602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                return 0;
11253602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            }
11263602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11273602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkCommandBufferBeginInfo cmdBufferBeginInfo;
11283602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
11293602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
11303602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            cmdBufferBeginInfo.pNext = nullptr;
11313602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
11323602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            cmdBufferBeginInfo.pInheritanceInfo = nullptr;
11333602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11343602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
11353602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            SkASSERT(!err);
11363602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11373602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            // Set image layout and add barrier
11383602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkImageMemoryBarrier barrier;
11393602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
11403602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
11413602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.pNext = nullptr;
11423602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout);
11433602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
11443602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11453602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
11463602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
11473602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.image = image;
11483602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0 , 1};
11493602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11503602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(CmdPipelineBarrier(cmdBuffer,
11513602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                       GrVkMemory::LayoutToPipelineStageFlags(initialLayout),
11523602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                       VK_PIPELINE_STAGE_TRANSFER_BIT,
11533602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                       0,
11543602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                       0, nullptr,
11553602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                       0, nullptr,
11563602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                                       1, &barrier));
11573602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11583602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11593602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            // Submit copy command
11603602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkBufferImageCopy region;
11613602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            memset(&region, 0, sizeof(VkBufferImageCopy));
11623602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            region.bufferOffset = 0;
1163a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel            region.bufferRowLength = w;
11643602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            region.bufferImageHeight = h;
11653602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
11663602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            region.imageOffset = { 0, 0, 0 };
11673602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            region.imageExtent = { (uint32_t)w, (uint32_t)h, 1 };
11683602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11693602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, 1, &region));
11703602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11713602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            // End CommandBuffer
11723602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(EndCommandBuffer(cmdBuffer));
11733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            SkASSERT(!err);
11743602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11753602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            // Create Fence for queue
11763602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkFence fence;
11773602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkFenceCreateInfo fenceInfo;
11783602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
11793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
11803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence));
11823602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            SkASSERT(!err);
11833602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11843602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VkSubmitInfo submitInfo;
11853602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            memset(&submitInfo, 0, sizeof(VkSubmitInfo));
11863602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
11873602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.pNext = nullptr;
11883602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.waitSemaphoreCount = 0;
11893602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.pWaitSemaphores = nullptr;
11903602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.pWaitDstStageMask = 0;
11913602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.commandBufferCount = 1;
11923602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.pCommandBuffers = &cmdBuffer;
11933602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.signalSemaphoreCount = 0;
11943602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            submitInfo.pSignalSemaphores = nullptr;
11953602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence));
11963602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            SkASSERT(!err);
11973602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
11983602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX));
11993602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            if (VK_TIMEOUT == err) {
12003602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeImageMemory(this, linearTiling, alloc);
12013602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyImage(fDevice, image, nullptr));
12023602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
12033602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
12043602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
12053602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                VK_CALL(DestroyFence(fDevice, fence, nullptr));
12063602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                SkDebugf("Fence failed to signal: %d\n", err);
12073602d4f16a01da860d16eb36fb52eb62487495ccegdaniel                SkFAIL("failing");
12083602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            }
12093602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            SkASSERT(!err);
12103602d4f16a01da860d16eb36fb52eb62487495ccegdaniel
12113602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            // Clean up transfer resources
12123602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
12133602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
12143602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
12153602d4f16a01da860d16eb36fb52eb62487495ccegdaniel            VK_CALL(DestroyFence(fDevice, fence, nullptr));
1216164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
1217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1219b2df0c2702329be6380a943d548e7377a51d8565egdaniel    GrVkImageInfo* info = new GrVkImageInfo;
1220fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fImage = image;
1221fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fAlloc = alloc;
1222fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fImageTiling = imageTiling;
1223fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    info->fImageLayout = initialLayout;
122458a8d9214a70e0f6c81c88a8b0b563c06bf0f70eegdaniel    info->fFormat = pixelFormat;
12252af0f1b014b9aabb6119bf66fac20e4cd3a8279bjvanverth    info->fLevelCount = 1;
1226fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth
1227fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth    return (GrBackendObject)info;
1228164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1229164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1230164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const {
1231b2df0c2702329be6380a943d548e7377a51d8565egdaniel    const GrVkImageInfo* backend = reinterpret_cast<const GrVkImageInfo*>(id);
1232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
12331e305ba0d6a4237020d36234e9e286d3b0489401jvanverth    if (backend && backend->fImage && backend->fAlloc.fMemory) {
1234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        VkMemoryRequirements req;
1235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        memset(&req, 0, sizeof(req));
1236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice,
1237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                   backend->fImage,
1238164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                                                   &req));
1239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // TODO: find a better check
1240164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        // This will probably fail with a different driver
1241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return (req.size > 0) && (req.size <= 8192 * 8192);
1242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return false;
1245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) {
12486b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth    GrVkImageInfo* backend = reinterpret_cast<GrVkImageInfo*>(id);
1249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (backend) {
1250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        if (!abandon) {
1251fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth            // something in the command buffer may still be using this, so force submit
1252fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth            this->submitCommandBuffer(kForce_SyncQueue);
12536b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth            GrVkImage::DestroyImageInfo(this, backend);
1254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        }
1255fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth        delete backend;
1256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1258164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1259164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel////////////////////////////////////////////////////////////////////////////////
1260164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask,
1262164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                               VkPipelineStageFlags dstStageMask,
1263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                               bool byRegion,
1264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                               VkMemoryBarrier* barrier) const {
1265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
1266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->pipelineBarrier(this,
1267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       srcStageMask,
1268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       dstStageMask,
1269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       byRegion,
1270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       GrVkCommandBuffer::kMemory_BarrierType,
1271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       barrier);
1272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addBufferMemoryBarrier(VkPipelineStageFlags srcStageMask,
1275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VkPipelineStageFlags dstStageMask,
1276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     bool byRegion,
1277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VkBufferMemoryBarrier* barrier) const {
1278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
1279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->pipelineBarrier(this,
1280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       srcStageMask,
1281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       dstStageMask,
1282164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       byRegion,
1283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       GrVkCommandBuffer::kBufferMemory_BarrierType,
1284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       barrier);
1285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask,
1288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                    VkPipelineStageFlags dstStageMask,
1289164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                    bool byRegion,
1290164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                    VkImageMemoryBarrier* barrier) const {
1291164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(fCurrentCmdBuffer);
1292164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->pipelineBarrier(this,
1293164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       srcStageMask,
1294164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       dstStageMask,
1295164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       byRegion,
1296164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       GrVkCommandBuffer::kImageMemory_BarrierType,
1297164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                       barrier);
1298164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1299164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1300f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillipsvoid GrVkGpu::finishOpList() {
1301164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Submit the current command buffer to the Queue
1302164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    this->submitCommandBuffer(kSkip_SyncQueue);
1303164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1304164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
13053d5d9ac426ea926f37eaa47e13acf7492068667begdanielvoid GrVkGpu::clearStencil(GrRenderTarget* target) {
13063d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    if (nullptr == target) {
13073d5d9ac426ea926f37eaa47e13acf7492068667begdaniel        return;
13083d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    }
13093d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    GrStencilAttachment* stencil = target->renderTargetPriv().getStencilAttachment();
13103d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
13113d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
13123d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
13133d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    VkClearDepthStencilValue vkStencilColor;
13143d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue));
13153d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
13163d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    vkStencil->setImageLayout(this,
13173d5d9ac426ea926f37eaa47e13acf7492068667begdaniel                              VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
131850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                              VK_ACCESS_TRANSFER_WRITE_BIT,
131950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                              VK_PIPELINE_STAGE_TRANSFER_BIT,
13203d5d9ac426ea926f37eaa47e13acf7492068667begdaniel                              false);
13213d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
13223d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    VkImageSubresourceRange subRange;
13233d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    memset(&subRange, 0, sizeof(VkImageSubresourceRange));
13243d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
13253d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.baseMipLevel = 0;
13263d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.levelCount = 1;
13273d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.baseArrayLayer = 0;
13283d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    subRange.layerCount = 1;
13293d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
13303d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a
13313d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    // draw. Thus we should look into using the load op functions on the render pass to clear out
13323d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    // the stencil there.
13333d5d9ac426ea926f37eaa47e13acf7492068667begdaniel    fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange);
13343d5d9ac426ea926f37eaa47e13acf7492068667begdaniel}
13353d5d9ac426ea926f37eaa47e13acf7492068667begdaniel
1336164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_image(const GrSurface* dst,
1337164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           const GrSurface* src,
1338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           const GrVkGpu* gpu) {
13394bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    const GrRenderTarget* dstRT = dst->asRenderTarget();
13404bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    const GrRenderTarget* srcRT = src->asRenderTarget();
13414bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (dstRT && srcRT) {
13424bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        if (srcRT->numColorSamples() != dstRT->numColorSamples()) {
13434bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel            return false;
13444bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        }
13454bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    } else if (dstRT) {
13464bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        if (dstRT->numColorSamples() > 1) {
13474bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel            return false;
13484bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        }
13494bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    } else if (srcRT) {
13504bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        if (srcRT->numColorSamples() > 1) {
13514bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel            return false;
13524bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        }
135317b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
135417b892551465e5a44560a06e4b34dc3592b49622egdaniel
135517b892551465e5a44560a06e4b34dc3592b49622egdaniel    // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
135617b892551465e5a44560a06e4b34dc3592b49622egdaniel    // as image usage flags.
135717b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (src->origin() == dst->origin() &&
135817b892551465e5a44560a06e4b34dc3592b49622egdaniel        GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) {
1359164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return true;
1360164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1361164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return false;
1363164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1364164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1365164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst,
1366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     GrSurface* src,
136717b892551465e5a44560a06e4b34dc3592b49622egdaniel                                     GrVkImage* dstImage,
136817b892551465e5a44560a06e4b34dc3592b49622egdaniel                                     GrVkImage* srcImage,
1369164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     const SkIRect& srcRect,
1370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     const SkIPoint& dstPoint) {
1371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkASSERT(can_copy_image(dst, src, this));
1372164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // These flags are for flushing/invalidating caches and for the dst image it doesn't matter if
1374164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // the cache is flushed since it is only being written to.
137517b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstImage->setImageLayout(this,
137650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
137750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_WRITE_BIT,
137850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
137950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             false);
1380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
138117b892551465e5a44560a06e4b34dc3592b49622egdaniel    srcImage->setImageLayout(this,
138217b892551465e5a44560a06e4b34dc3592b49622egdaniel                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
138350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_READ_BIT,
138450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
138517b892551465e5a44560a06e4b34dc3592b49622egdaniel                             false);
1386164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Flip rect if necessary
1388164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    SkIRect srcVkRect = srcRect;
1389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    int32_t dstY = dstPoint.fY;
1390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
1392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin());
1393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        srcVkRect.fTop = src->height() - srcRect.fBottom;
1394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        srcVkRect.fBottom =  src->height() - srcRect.fTop;
1395164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        dstY = dst->height() - dstPoint.fY - srcVkRect.height();
1396164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1397164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1398164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkImageCopy copyRegion;
1399164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    memset(&copyRegion, 0, sizeof(VkImageCopy));
1400164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1401164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
1402164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1403164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    copyRegion.dstOffset = { dstPoint.fX, dstY, 0 };
1404c355bc8dd117291b63ee7b7b39ec37a0e768eec5egdaniel    copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 };
1405164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1406164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->copyImage(this,
140717b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 srcImage,
1408164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
140917b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 dstImage,
1410164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1411164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 1,
1412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                 &copyRegion);
1413900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
1414900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
1415900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth                                        srcRect.width(), srcRect.height());
1416900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    this->didWriteToSurface(dst, &dstRect);
1417164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
141917b892551465e5a44560a06e4b34dc3592b49622egdanielinline bool can_copy_as_blit(const GrSurface* dst,
142017b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrSurface* src,
142117b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrVkImage* dstImage,
142217b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrVkImage* srcImage,
142317b892551465e5a44560a06e4b34dc3592b49622egdaniel                             const GrVkGpu* gpu) {
142466933552f1723c4a2b248711ab3d43921401e8e6egdaniel    // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
142517b892551465e5a44560a06e4b34dc3592b49622egdaniel    // as image usage flags.
142617b892551465e5a44560a06e4b34dc3592b49622egdaniel    const GrVkCaps& caps = gpu->vkCaps();
142717b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (!caps.configCanBeDstofBlit(dst->config(), dstImage->isLinearTiled()) ||
142817b892551465e5a44560a06e4b34dc3592b49622egdaniel        !caps.configCanBeSrcofBlit(src->config(), srcImage->isLinearTiled())) {
142917b892551465e5a44560a06e4b34dc3592b49622egdaniel        return false;
143017b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
143117b892551465e5a44560a06e4b34dc3592b49622egdaniel
143217b892551465e5a44560a06e4b34dc3592b49622egdaniel    // We cannot blit images that are multisampled. Will need to figure out if we can blit the
143317b892551465e5a44560a06e4b34dc3592b49622egdaniel    // resolved msaa though.
143417b892551465e5a44560a06e4b34dc3592b49622egdaniel    if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) ||
143517b892551465e5a44560a06e4b34dc3592b49622egdaniel        (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) {
143617b892551465e5a44560a06e4b34dc3592b49622egdaniel        return false;
143717b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
143817b892551465e5a44560a06e4b34dc3592b49622egdaniel
143917b892551465e5a44560a06e4b34dc3592b49622egdaniel    return true;
144017b892551465e5a44560a06e4b34dc3592b49622egdaniel}
144117b892551465e5a44560a06e4b34dc3592b49622egdaniel
144217b892551465e5a44560a06e4b34dc3592b49622egdanielvoid GrVkGpu::copySurfaceAsBlit(GrSurface* dst,
144317b892551465e5a44560a06e4b34dc3592b49622egdaniel                                GrSurface* src,
144417b892551465e5a44560a06e4b34dc3592b49622egdaniel                                GrVkImage* dstImage,
144517b892551465e5a44560a06e4b34dc3592b49622egdaniel                                GrVkImage* srcImage,
144617b892551465e5a44560a06e4b34dc3592b49622egdaniel                                const SkIRect& srcRect,
144717b892551465e5a44560a06e4b34dc3592b49622egdaniel                                const SkIPoint& dstPoint) {
144817b892551465e5a44560a06e4b34dc3592b49622egdaniel    SkASSERT(can_copy_as_blit(dst, src, dstImage, srcImage, this));
144917b892551465e5a44560a06e4b34dc3592b49622egdaniel
145017b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstImage->setImageLayout(this,
145117b892551465e5a44560a06e4b34dc3592b49622egdaniel                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
145250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_WRITE_BIT,
145350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
145417b892551465e5a44560a06e4b34dc3592b49622egdaniel                             false);
145517b892551465e5a44560a06e4b34dc3592b49622egdaniel
145617b892551465e5a44560a06e4b34dc3592b49622egdaniel    srcImage->setImageLayout(this,
145717b892551465e5a44560a06e4b34dc3592b49622egdaniel                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
145850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_ACCESS_TRANSFER_READ_BIT,
145950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth                             VK_PIPELINE_STAGE_TRANSFER_BIT,
146017b892551465e5a44560a06e4b34dc3592b49622egdaniel                             false);
146117b892551465e5a44560a06e4b34dc3592b49622egdaniel
146217b892551465e5a44560a06e4b34dc3592b49622egdaniel    // Flip rect if necessary
146317b892551465e5a44560a06e4b34dc3592b49622egdaniel    SkIRect srcVkRect;
14648af936d3047208def585b7bc824f013b994f6312egdaniel    srcVkRect.fLeft = srcRect.fLeft;
14658af936d3047208def585b7bc824f013b994f6312egdaniel    srcVkRect.fRight = srcRect.fRight;
146617b892551465e5a44560a06e4b34dc3592b49622egdaniel    SkIRect dstRect;
146717b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstRect.fLeft = dstPoint.fX;
14688af936d3047208def585b7bc824f013b994f6312egdaniel    dstRect.fRight = dstPoint.fX + srcRect.width();
146917b892551465e5a44560a06e4b34dc3592b49622egdaniel
147017b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
147117b892551465e5a44560a06e4b34dc3592b49622egdaniel        srcVkRect.fTop = src->height() - srcRect.fBottom;
147217b892551465e5a44560a06e4b34dc3592b49622egdaniel        srcVkRect.fBottom = src->height() - srcRect.fTop;
147317b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
14748af936d3047208def585b7bc824f013b994f6312egdaniel        srcVkRect.fTop = srcRect.fTop;
14758af936d3047208def585b7bc824f013b994f6312egdaniel        srcVkRect.fBottom = srcRect.fBottom;
147617b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
147717b892551465e5a44560a06e4b34dc3592b49622egdaniel
147817b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
147917b892551465e5a44560a06e4b34dc3592b49622egdaniel        dstRect.fTop = dst->height() - dstPoint.fY - srcVkRect.height();
148017b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
148117b892551465e5a44560a06e4b34dc3592b49622egdaniel        dstRect.fTop = dstPoint.fY;
148217b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
148317b892551465e5a44560a06e4b34dc3592b49622egdaniel    dstRect.fBottom = dstRect.fTop + srcVkRect.height();
148417b892551465e5a44560a06e4b34dc3592b49622egdaniel
148517b892551465e5a44560a06e4b34dc3592b49622egdaniel    // If we have different origins, we need to flip the top and bottom of the dst rect so that we
148617b892551465e5a44560a06e4b34dc3592b49622egdaniel    // get the correct origintation of the copied data.
148717b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (src->origin() != dst->origin()) {
148817b892551465e5a44560a06e4b34dc3592b49622egdaniel        SkTSwap(dstRect.fTop, dstRect.fBottom);
148917b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
149017b892551465e5a44560a06e4b34dc3592b49622egdaniel
149117b892551465e5a44560a06e4b34dc3592b49622egdaniel    VkImageBlit blitRegion;
149217b892551465e5a44560a06e4b34dc3592b49622egdaniel    memset(&blitRegion, 0, sizeof(VkImageBlit));
149317b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
149417b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
1495e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel    blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 1 };
149617b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
149717b892551465e5a44560a06e4b34dc3592b49622egdaniel    blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 };
1498e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel    blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 1 };
149917b892551465e5a44560a06e4b34dc3592b49622egdaniel
150017b892551465e5a44560a06e4b34dc3592b49622egdaniel    fCurrentCmdBuffer->blitImage(this,
1501b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                 *srcImage,
1502b2df0c2702329be6380a943d548e7377a51d8565egdaniel                                 *dstImage,
150317b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 1,
150417b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 &blitRegion,
150517b892551465e5a44560a06e4b34dc3592b49622egdaniel                                 VK_FILTER_NEAREST); // We never scale so any filter works here
1506900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth
1507900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth    this->didWriteToSurface(dst, &dstRect);
150817b892551465e5a44560a06e4b34dc3592b49622egdaniel}
150917b892551465e5a44560a06e4b34dc3592b49622egdaniel
15104bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielinline bool can_copy_as_resolve(const GrSurface* dst,
15114bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                const GrSurface* src,
15124bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                const GrVkGpu* gpu) {
15134bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // Our src must be a multisampled render target
15144bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (!src->asRenderTarget() || src->asRenderTarget()->numColorSamples() <= 1) {
15154bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        return false;
15164bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
15174bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
15184bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // The dst must be a render target but not multisampled
15194bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (!dst->asRenderTarget() || dst->asRenderTarget()->numColorSamples() > 1) {
15204bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        return false;
15214bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
15224bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
15234bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    // Surfaces must have the same origin.
15244bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (src->origin() != dst->origin()) {
15254bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        return false;
15264bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
15274bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
15284bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    return true;
15294bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel}
15304bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
15314bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielvoid GrVkGpu::copySurfaceAsResolve(GrSurface* dst,
15324bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                   GrSurface* src,
15334bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                   const SkIRect& srcRect,
15344bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel                                   const SkIPoint& dstPoint) {
15354bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrVkRenderTarget* dstRT = static_cast<GrVkRenderTarget*>(dst->asRenderTarget());
15364bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget());
15374bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    SkASSERT(dstRT && dstRT->numColorSamples() <= 1);
15384bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    this->resolveImage(dstRT, srcRT, srcRect, dstPoint);
15394bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel}
15404bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
1541164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onCopySurface(GrSurface* dst,
1542164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            GrSurface* src,
1543164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            const SkIRect& srcRect,
1544164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                            const SkIPoint& dstPoint) {
15454bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (can_copy_as_resolve(dst, src, this)) {
15464bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        this->copySurfaceAsResolve(dst, src, srcRect, dstPoint);
1547ec44099979acd3e83ad93a15dbd9301856a90572egdaniel        return true;
15484bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    }
15494bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel
1550fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) {
1551fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel        this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue);
1552fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel    }
1553fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel
1554bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    if (fCopyManager.copySurfaceAsDraw(this, dst, src, srcRect, dstPoint)) {
1555bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel        return true;
1556bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel    }
1557bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel
155817b892551465e5a44560a06e4b34dc3592b49622egdaniel    GrVkImage* dstImage;
155917b892551465e5a44560a06e4b34dc3592b49622egdaniel    GrVkImage* srcImage;
15604bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrRenderTarget* dstRT = dst->asRenderTarget();
15614bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (dstRT) {
15624bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT);
15634bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        dstImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT;
156417b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
15654bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        SkASSERT(dst->asTexture());
15664bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        dstImage = static_cast<GrVkTexture*>(dst->asTexture());
156717b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
15684bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    GrRenderTarget* srcRT = src->asRenderTarget();
15694bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel    if (srcRT) {
15704bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT);
15714bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT;
157217b892551465e5a44560a06e4b34dc3592b49622egdaniel    } else {
15734bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        SkASSERT(src->asTexture());
15744bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel        srcImage = static_cast<GrVkTexture*>(src->asTexture());
157517b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
157617b892551465e5a44560a06e4b34dc3592b49622egdaniel
1577164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (can_copy_image(dst, src, this)) {
157817b892551465e5a44560a06e4b34dc3592b49622egdaniel        this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstPoint);
157917b892551465e5a44560a06e4b34dc3592b49622egdaniel        return true;
158017b892551465e5a44560a06e4b34dc3592b49622egdaniel    }
158117b892551465e5a44560a06e4b34dc3592b49622egdaniel
158217b892551465e5a44560a06e4b34dc3592b49622egdaniel    if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) {
158317b892551465e5a44560a06e4b34dc3592b49622egdaniel        this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint);
1584164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return true;
1585164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1586164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1587164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return false;
1588164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1589164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1590c25c5d73e9f4d840dc758c399496d5690709ad58csmartdaltonvoid GrVkGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&,
1591c25c5d73e9f4d840dc758c399496d5690709ad58csmartdalton                                      int* effectiveSampleCnt, SamplePattern*) {
159228f45b949acc746849100fbe112ee5280f0594c9cdalton    // TODO: stub.
159328f45b949acc746849100fbe112ee5280f0594c9cdalton    SkASSERT(!this->caps()->sampleLocationsSupport());
159428f45b949acc746849100fbe112ee5280f0594c9cdalton    *effectiveSampleCnt = rt->desc().fSampleCnt;
159528f45b949acc746849100fbe112ee5280f0594c9cdalton}
159628f45b949acc746849100fbe112ee5280f0594c9cdalton
1597164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
1598164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                  GrPixelConfig readConfig, DrawPreference* drawPreference,
1599164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                  ReadPixelTempDrawInfo* tempDrawInfo) {
160088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // These settings we will always want if a temp draw is performed.
160188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
160288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fWidth = width;
160388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fHeight = height;
160488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
160588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
1606b117ff194ff888ef9107a4797aad053b0d76be30bsalomon    tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox;
160788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel
160888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // For now assume no swizzling, we may change that below.
160988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
161088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel
161188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read
161288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // from will be srcConfig and we will read readConfig pixels from it.
161388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // Not that if we require a draw and return a non-renderable format for the temp surface the
161488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    // base class will fail for us.
161588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config();
161688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    tempDrawInfo->fReadConfig = readConfig;
161788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel
16184583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    if (srcSurface->config() == readConfig) {
16194583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        return true;
1620164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1621164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
162266933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (this->vkCaps().isConfigRenderable(readConfig, srcSurface->desc().fSampleCnt > 1)) {
16234583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
16244583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
16254583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        tempDrawInfo->fReadConfig = readConfig;
16264583ec51d9ddc830eeb854db068235be96ce59c4egdaniel        return true;
1627164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1628164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
16294583ec51d9ddc830eeb854db068235be96ce59c4egdaniel    return false;
1630164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1631164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1632164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onReadPixels(GrSurface* surface,
1633164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           int left, int top, int width, int height,
1634164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           GrPixelConfig config,
1635164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           void* buffer,
1636164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                           size_t rowBytes) {
1637164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkFormat pixelFormat;
1638164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
1639164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
1640164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1641164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
164266933552f1723c4a2b248711ab3d43921401e8e6egdaniel    GrVkImage* image = nullptr;
164366933552f1723c4a2b248711ab3d43921401e8e6egdaniel    GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(surface->asRenderTarget());
164466933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (rt) {
164566933552f1723c4a2b248711ab3d43921401e8e6egdaniel        // resolve the render target if necessary
164666933552f1723c4a2b248711ab3d43921401e8e6egdaniel        switch (rt->getResolveType()) {
164766933552f1723c4a2b248711ab3d43921401e8e6egdaniel            case GrVkRenderTarget::kCantResolve_ResolveType:
164866933552f1723c4a2b248711ab3d43921401e8e6egdaniel                return false;
164966933552f1723c4a2b248711ab3d43921401e8e6egdaniel            case GrVkRenderTarget::kAutoResolves_ResolveType:
165066933552f1723c4a2b248711ab3d43921401e8e6egdaniel                break;
165166933552f1723c4a2b248711ab3d43921401e8e6egdaniel            case GrVkRenderTarget::kCanResolve_ResolveType:
165269d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel                this->internalResolveRenderTarget(rt, false);
165366933552f1723c4a2b248711ab3d43921401e8e6egdaniel                break;
165466933552f1723c4a2b248711ab3d43921401e8e6egdaniel            default:
165566933552f1723c4a2b248711ab3d43921401e8e6egdaniel                SkFAIL("Unknown resolve type");
165666933552f1723c4a2b248711ab3d43921401e8e6egdaniel        }
165766933552f1723c4a2b248711ab3d43921401e8e6egdaniel        image = rt;
165866933552f1723c4a2b248711ab3d43921401e8e6egdaniel    } else {
165966933552f1723c4a2b248711ab3d43921401e8e6egdaniel        image = static_cast<GrVkTexture*>(surface->asTexture());
166066933552f1723c4a2b248711ab3d43921401e8e6egdaniel    }
166166933552f1723c4a2b248711ab3d43921401e8e6egdaniel
166266933552f1723c4a2b248711ab3d43921401e8e6egdaniel    if (!image) {
1663164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel        return false;
1664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1666164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // Change layout of our target so it can be used as copy
166766933552f1723c4a2b248711ab3d43921401e8e6egdaniel    image->setImageLayout(this,
166866933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
166966933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          VK_ACCESS_TRANSFER_READ_BIT,
167066933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          VK_PIPELINE_STAGE_TRANSFER_BIT,
167166933552f1723c4a2b248711ab3d43921401e8e6egdaniel                          false);
1672164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
16736fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    size_t bpp = GrBytesPerPixel(config);
16746fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    size_t tightRowBytes = bpp * width;
1675164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
1676164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1677164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    VkBufferImageCopy region;
1678164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    memset(&region, 0, sizeof(VkBufferImageCopy));
16796fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
16806fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    bool copyFromOrigin = this->vkCaps().mustDoCopiesFromOrigin();
16816fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    if (copyFromOrigin) {
16826fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageOffset = { 0, 0, 0 };
16836fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageExtent = { (uint32_t)(left + width),
16846fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                               (uint32_t)(flipY ? surface->height() - top : top + height),
16856fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                               1
16866fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                             };
16876fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    } else {
16886fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        VkOffset3D offset = {
16896fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            left,
16906fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            flipY ? surface->height() - top - height : top,
16916fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            0
16926fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        };
16936fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageOffset = offset;
16946fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
16956fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    }
16966fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
16976fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    size_t transBufferRowBytes = bpp * region.imageExtent.width;
16986fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    GrVkTransferBuffer* transferBuffer =
16996fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            static_cast<GrVkTransferBuffer*>(this->createBuffer(transBufferRowBytes * height,
17006fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                                                                kXferGpuToCpu_GrBufferType,
17016fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel                                                                kStream_GrAccessPattern));
17026fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
17036fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    // Copy the image to a buffer so we can map it to cpu memory
1704db37909347d034943bd6b0922710a94c6c6ea572jvanverth    region.bufferOffset = transferBuffer->offset();
170588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    region.bufferRowLength = 0; // Forces RowLength to be width. We handle the rowBytes below.
1706164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images.
1707164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
1708164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1709164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->copyImageToBuffer(this,
171066933552f1723c4a2b248711ab3d43921401e8e6egdaniel                                         image,
1711164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1712164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         transferBuffer,
1713164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         1,
1714164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                         &region);
1715164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1716164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // make sure the copy to buffer has finished
1717164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    transferBuffer->addMemoryBarrier(this,
1718164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_ACCESS_TRANSFER_WRITE_BIT,
1719164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_ACCESS_HOST_READ_BIT,
1720164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_PIPELINE_STAGE_TRANSFER_BIT,
1721164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     VK_PIPELINE_STAGE_HOST_BIT,
1722164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel                                     false);
1723164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
1724164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // We need to submit the current command buffer to the Queue and make sure it finishes before
1725164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    // we can copy the data out of the buffer.
1726164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    this->submitCommandBuffer(kForce_SyncQueue);
17279d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth    GrVkMemory::InvalidateMappedAlloc(this, transferBuffer->alloc());
1728164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    void* mappedMemory = transferBuffer->map();
1729164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
17306fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    if (copyFromOrigin) {
17316fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        uint32_t skipRows = region.imageExtent.height - height;
17326fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel        mappedMemory = (char*)mappedMemory + transBufferRowBytes * skipRows + bpp * left;
17336fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel    }
17346fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel
1735164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    if (flipY) {
173688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        const char* srcRow = reinterpret_cast<const char*>(mappedMemory);
173788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes;
173888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        for (int y = 0; y < height; y++) {
173988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel            memcpy(dstRow, srcRow, tightRowBytes);
17406fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel            srcRow += transBufferRowBytes;
174188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel            dstRow -= rowBytes;
174288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel        }
174388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    } else {
1744cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett        SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, height);
1745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    }
1746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel
174788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    transferBuffer->unmap();
174888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel    transferBuffer->unref();
1749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    return true;
1750164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
1751066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel
175227bb28473912181cf9a838e9282e86cb62e2d44begdaniel// The RenderArea bounds we pass into BeginRenderPass must have a start x value that is a multiple
175327bb28473912181cf9a838e9282e86cb62e2d44begdaniel// of the granularity. The width must also be a multiple of the granularity or eaqual to the width
175427bb28473912181cf9a838e9282e86cb62e2d44begdaniel// the the entire attachment. Similar requirements for the y and height components.
175527bb28473912181cf9a838e9282e86cb62e2d44begdanielvoid adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds,
175627bb28473912181cf9a838e9282e86cb62e2d44begdaniel                                  const VkExtent2D& granularity, int maxWidth, int maxHeight) {
175727bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // Adjust Width
1758d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel    if ((0 != granularity.width && 1 != granularity.width)) {
1759d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        // Start with the right side of rect so we know if we end up going pass the maxWidth.
1760d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        int rightAdj = srcBounds.fRight % granularity.width;
1761d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (rightAdj != 0) {
1762d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            rightAdj = granularity.width - rightAdj;
1763d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
1764d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fRight = srcBounds.fRight + rightAdj;
1765d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (dstBounds->fRight > maxWidth) {
1766d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fRight = maxWidth;
1767d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fLeft = 0;
1768d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        } else {
1769d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fLeft = srcBounds.fLeft - srcBounds.fLeft % granularity.width;
1770d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
177127bb28473912181cf9a838e9282e86cb62e2d44begdaniel    } else {
1772d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fLeft = srcBounds.fLeft;
1773d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fRight = srcBounds.fRight;
177427bb28473912181cf9a838e9282e86cb62e2d44begdaniel    }
177527bb28473912181cf9a838e9282e86cb62e2d44begdaniel
177627bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // Adjust height
1777d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel    if ((0 != granularity.height && 1 != granularity.height)) {
1778d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        // Start with the bottom side of rect so we know if we end up going pass the maxHeight.
1779d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        int bottomAdj = srcBounds.fBottom % granularity.height;
1780d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (bottomAdj != 0) {
1781d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            bottomAdj = granularity.height - bottomAdj;
1782d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
1783d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fBottom = srcBounds.fBottom + bottomAdj;
1784d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        if (dstBounds->fBottom > maxHeight) {
1785d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fBottom = maxHeight;
1786d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fTop = 0;
1787d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        } else {
1788d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel            dstBounds->fTop = srcBounds.fTop - srcBounds.fTop % granularity.height;
1789d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        }
179027bb28473912181cf9a838e9282e86cb62e2d44begdaniel    } else {
1791d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fTop = srcBounds.fTop;
1792d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel        dstBounds->fBottom = srcBounds.fBottom;
179327bb28473912181cf9a838e9282e86cb62e2d44begdaniel    }
179427bb28473912181cf9a838e9282e86cb62e2d44begdaniel}
179527bb28473912181cf9a838e9282e86cb62e2d44begdaniel
17967ec92413307c9da43c013d1e4e15716a44059810jvanverthvoid GrVkGpu::submitSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer,
17979cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const GrVkRenderPass* renderPass,
17989cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const VkClearValue* colorClear,
17999cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           GrVkRenderTarget* target,
18009cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel                                           const SkIRect& bounds) {
1801e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    const SkIRect* pBounds = &bounds;
1802e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    SkIRect flippedBounds;
1803e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    if (kBottomLeft_GrSurfaceOrigin == target->origin()) {
1804e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        flippedBounds = bounds;
1805e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        flippedBounds.fTop = target->height() - bounds.fBottom;
1806e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        flippedBounds.fBottom = target->height() - bounds.fTop;
1807e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel        pBounds = &flippedBounds;
1808e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel    }
1809e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel
181027bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // The bounds we use for the render pass should be of the granularity supported
181127bb28473912181cf9a838e9282e86cb62e2d44begdaniel    // by the device.
181227bb28473912181cf9a838e9282e86cb62e2d44begdaniel    const VkExtent2D& granularity = renderPass->granularity();
181327bb28473912181cf9a838e9282e86cb62e2d44begdaniel    SkIRect adjustedBounds;
181427bb28473912181cf9a838e9282e86cb62e2d44begdaniel    if ((0 != granularity.width && 1 != granularity.width) ||
181527bb28473912181cf9a838e9282e86cb62e2d44begdaniel        (0 != granularity.height && 1 != granularity.height)) {
181627bb28473912181cf9a838e9282e86cb62e2d44begdaniel        adjust_bounds_to_granularity(&adjustedBounds, *pBounds, granularity,
181727bb28473912181cf9a838e9282e86cb62e2d44begdaniel                                     target->width(), target->height());
181827bb28473912181cf9a838e9282e86cb62e2d44begdaniel        pBounds = &adjustedBounds;
181927bb28473912181cf9a838e9282e86cb62e2d44begdaniel    }
182027bb28473912181cf9a838e9282e86cb62e2d44begdaniel
182177a86f81f39227ea53441af2afc647f589a96a0dGreg Daniel    fCurrentCmdBuffer->beginRenderPass(this, renderPass, colorClear, *target, *pBounds, true);
1822066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel    fCurrentCmdBuffer->executeCommands(this, buffer);
1823164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel    fCurrentCmdBuffer->endRenderPass(this);
182466933552f1723c4a2b248711ab3d43921401e8e6egdaniel
1825ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel    this->didWriteToSurface(target, &bounds);
1826164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel}
18279cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel
18286be35238855dbbc7575e78d6723936293a4b38e6Greg DanielGrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() {
182984741b308496409f4ff662658167221fc6801bbejvanverth    VkFenceCreateInfo createInfo;
183084741b308496409f4ff662658167221fc6801bbejvanverth    memset(&createInfo, 0, sizeof(VkFenceCreateInfo));
183184741b308496409f4ff662658167221fc6801bbejvanverth    createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
183284741b308496409f4ff662658167221fc6801bbejvanverth    createInfo.pNext = nullptr;
183384741b308496409f4ff662658167221fc6801bbejvanverth    createInfo.flags = 0;
183484741b308496409f4ff662658167221fc6801bbejvanverth    VkFence fence = VK_NULL_HANDLE;
18356be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18366be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VK_CALL_ERRCHECK(CreateFence(this->device(), &createInfo, nullptr, &fence));
18376be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VK_CALL(QueueSubmit(this->queue(), 0, nullptr, fence));
18386be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18396be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(VkFence));
184084741b308496409f4ff662658167221fc6801bbejvanverth    return (GrFence)fence;
184184741b308496409f4ff662658167221fc6801bbejvanverth}
184284741b308496409f4ff662658167221fc6801bbejvanverth
18436be35238855dbbc7575e78d6723936293a4b38e6Greg Danielbool GrVkGpu::waitFence(GrFence fence, uint64_t timeout) {
18446be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    SkASSERT(VK_NULL_HANDLE != (VkFence)fence);
18456be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18466be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VkResult result = VK_CALL(WaitForFences(this->device(), 1, (VkFence*)&fence, VK_TRUE, timeout));
184784741b308496409f4ff662658167221fc6801bbejvanverth    return (VK_SUCCESS == result);
184884741b308496409f4ff662658167221fc6801bbejvanverth}
184984741b308496409f4ff662658167221fc6801bbejvanverth
185084741b308496409f4ff662658167221fc6801bbejvanverthvoid GrVkGpu::deleteFence(GrFence fence) const {
18516be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    VK_CALL(DestroyFence(this->device(), (VkFence)fence, nullptr));
18526be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
18536be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18546be35238855dbbc7575e78d6723936293a4b38e6Greg Danielsk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrVkGpu::makeSemaphore() {
18556be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    return GrVkSemaphore::Make(this);
18566be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
18576be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18586be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore) {
18596be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
18606be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18616be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    this->submitCommandBuffer(kSkip_SyncQueue, vkSem->getResource());
18626be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel}
18636be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18646be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrVkGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
18656be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
18666be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel
18676be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    const GrVkSemaphore::Resource* resource = vkSem->getResource();
18686be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    resource->ref();
18696be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel    fSemaphoresToWaitOn.push_back(resource);
187084741b308496409f4ff662658167221fc6801bbejvanverth}
187184741b308496409f4ff662658167221fc6801bbejvanverth
18722c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osmanvoid GrVkGpu::flush() {
18732c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman    // We submit the command buffer to the queue whenever Ganesh is flushed, so nothing is needed
18742c2bc11aea4dfcd7ee2f5859838a2aa0a56939e0Brian Osman}
1875