GrVkGpu.cpp revision c293a29bc2fced15ac44a66efa813d42cb3f2e0b
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" 28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h" 29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTextureRenderTarget.h" 30164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTransferBuffer.h" 31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkVertexBuffer.h" 32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "SkConfig8888.h" 34900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth#include "SkMipMap.h" 35164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vk/GrVkInterface.h" 37fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth#include "vk/GrVkTypes.h" 38164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 39b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#if USE_SKSL 40b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#include "SkSLCompiler.h" 41b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#endif 42b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 43164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X) 44164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) 45164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) 46164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 47735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS 48d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverthVKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( 49d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportFlagsEXT flags, 50d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportObjectTypeEXT objectType, 51d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth uint64_t object, 52d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth size_t location, 53d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth int32_t messageCode, 54d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth const char* pLayerPrefix, 55d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth const char* pMessage, 56d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth void* pUserData) { 57d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { 58d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 59ce3fe23c04e93d2aa8d4c09c0c99088207edd509Jim Van Verth return VK_TRUE; // skip further layers 60d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { 61d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 62d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { 63d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 64d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else { 65d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 66d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } 67d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth return VK_FALSE; 68d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth} 69d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 70d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth 71633b35657c964c32e7010b14bb2d396b4a764c52jvanverthGrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options, 72633b35657c964c32e7010b14bb2d396b4a764c52jvanverth GrContext* context) { 73dc0fcd41e75682a8bfd5e285d684461475226330bsalomon const GrVkBackendContext* vkBackendContext = 74dc0fcd41e75682a8bfd5e285d684461475226330bsalomon reinterpret_cast<const GrVkBackendContext*>(backendContext); 75633b35657c964c32e7010b14bb2d396b4a764c52jvanverth if (!vkBackendContext) { 76dc0fcd41e75682a8bfd5e285d684461475226330bsalomon vkBackendContext = GrVkBackendContext::Create(); 77633b35657c964c32e7010b14bb2d396b4a764c52jvanverth if (!vkBackendContext) { 78633b35657c964c32e7010b14bb2d396b4a764c52jvanverth return nullptr; 79164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 80633b35657c964c32e7010b14bb2d396b4a764c52jvanverth } else { 81633b35657c964c32e7010b14bb2d396b4a764c52jvanverth vkBackendContext->ref(); 82164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 83164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 84fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel if (!vkBackendContext->fInterface->validate(vkBackendContext->fExtensions)) { 85fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel return nullptr; 86fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel } 87fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel 88633b35657c964c32e7010b14bb2d396b4a764c52jvanverth return new GrVkGpu(context, options, vkBackendContext); 89164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 90164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 91164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 92164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanaryGrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, 94633b35657c964c32e7010b14bb2d396b4a764c52jvanverth const GrVkBackendContext* backendCtx) 95164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : INHERITED(context) 96633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fDevice(backendCtx->fDevice) 97633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fQueue(backendCtx->fQueue) 98633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fResourceProvider(this) { 99633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fBackendContext.reset(backendCtx); 100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 101735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS 102419ca64f0f800dc098369b5aa5a604acd017b240brianosman fCallback = VK_NULL_HANDLE; 103fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth if (backendCtx->fExtensions & kEXT_debug_report_GrVkExtensionFlag) { 104fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth // Setup callback creation information 105d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; 106d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 107d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pNext = nullptr; 108d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | 109ef0c10cffefef90646ff2e238d7c2d82247a0370egdaniel VK_DEBUG_REPORT_WARNING_BIT_EXT | 110d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth //VK_DEBUG_REPORT_INFORMATION_BIT_EXT | 111d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth //VK_DEBUG_REPORT_DEBUG_BIT_EXT | 112b4aa36211ca66ef127ac2954108742af1ead5082egdaniel VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; 113d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pfnCallback = &DebugReportCallback; 114d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pUserData = nullptr; 115d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth 116fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth // Register the callback 117a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateDebugReportCallbackEXT( 118a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth backendCtx->fInstance, &callbackCreateInfo, nullptr, &fCallback)); 119d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } 120d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 121633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 122b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#if USE_SKSL 123b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas fCompiler = new SkSL::Compiler(); 124b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#else 125633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCompiler = shaderc_compiler_initialize(); 126b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#endif 127633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 128fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice, 129c5ec1408298510410270ea67e895570ccfa76e54egdaniel backendCtx->fFeatures, backendCtx->fExtensions)); 130633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCaps.reset(SkRef(fVkCaps.get())); 131633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 132633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps)); 133633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 134633b35657c964c32e7010b14bb2d396b4a764c52jvanverth const VkCommandPoolCreateInfo cmdPoolInfo = { 1357ec92413307c9da43c013d1e4e15716a44059810jvanverth VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType 1367ec92413307c9da43c013d1e4e15716a44059810jvanverth nullptr, // pNext 1377ec92413307c9da43c013d1e4e15716a44059810jvanverth VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | 1387ec92413307c9da43c013d1e4e15716a44059810jvanverth VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // CmdPoolCreateFlags 1397ec92413307c9da43c013d1e4e15716a44059810jvanverth backendCtx->fGraphicsQueueIndex, // queueFamilyIndex 140633b35657c964c32e7010b14bb2d396b4a764c52jvanverth }; 1419d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateCommandPool(fDevice, &cmdPoolInfo, nullptr, 142633b35657c964c32e7010b14bb2d396b4a764c52jvanverth &fCmdPool)); 143633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 144633b35657c964c32e7010b14bb2d396b4a764c52jvanverth // must call this after creating the CommandPool 145633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fResourceProvider.init(); 1467ec92413307c9da43c013d1e4e15716a44059810jvanverth fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer(); 147633b35657c964c32e7010b14bb2d396b4a764c52jvanverth SkASSERT(fCurrentCmdBuffer); 148633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCurrentCmdBuffer->begin(this); 1496b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth 1506b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth // set up our heaps 1516b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kLinearImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024)); 15205dceabf3422b785b52439378aa5527c42c6ca18egdaniel // We want the OptimalImage_Heap to use a SubAlloc_strategy but it occasionally causes the 15305dceabf3422b785b52439378aa5527c42c6ca18egdaniel // device to run out of memory. Most likely this is caused by fragmentation in the device heap 15405dceabf3422b785b52439378aa5527c42c6ca18egdaniel // and we can't allocate more. Until we get a fix moving this to SingleAlloc. 15505dceabf3422b785b52439378aa5527c42c6ca18egdaniel fHeaps[kOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 64*1024*1024)); 1566b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kSmallOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 2*1024*1024)); 1576b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kVertexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1586b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kIndexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1594c6e47a8a827077e36fa5feb4ab5ac7435d8276bjvanverth fHeaps[kUniformBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 256*1024)); 1606b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kCopyReadBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1616b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kCopyWriteBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024)); 162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 164164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkGpu::~GrVkGpu() { 165164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // wait for all commands to finish 169ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth fResourceProvider.checkCommandBuffers(); 17009557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth VkResult res = VK_CALL(QueueWaitIdle(fQueue)); 171f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel 172f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // On windows, sometimes calls to QueueWaitIdle return before actually signalling the fences 173f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // on the command buffers even though they have completed. This causes an assert to fire when 174f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // destroying the command buffers. Currently this ony seems to happen on windows, so we add a 17509557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth // sleep to make sure the fence signals. 176f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#ifdef SK_DEBUG 177f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#if defined(SK_BUILD_FOR_WIN) 178f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel Sleep(10); // In milliseconds 179f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#else 180f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // Uncomment if above bug happens on non windows build. 181f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // sleep(1); // In seconds 182f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif 183f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif 184f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel 185be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#ifdef SK_DEBUG 1868a8668b4721097de657ad8b30d45f60f62433c6fGreg Daniel SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res); 187be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#endif 1889d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 189bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel fCopyManager.destroyResources(this); 190bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel 19109557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth // must call this just before we destroy the command pool and VkDevice 19209557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth fResourceProvider.destroyResources(VK_ERROR_DEVICE_LOST == res); 193164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 194633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); 195633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 196b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#if USE_SKSL 197b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas delete fCompiler; 198b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#else 199633b35657c964c32e7010b14bb2d396b4a764c52jvanverth shaderc_compiler_release(fCompiler); 200b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#endif 201633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 202735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS 203a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth if (fCallback) { 204a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth VK_CALL(DestroyDebugReportCallbackEXT(fBackendContext->fInstance, fCallback, nullptr)); 205419ca64f0f800dc098369b5aa5a604acd017b240brianosman fCallback = VK_NULL_HANDLE; 206a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth } 207d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 209164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 210164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 211164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 2129cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpuCommandBuffer* GrVkGpu::createCommandBuffer( 2139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo, 2149cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) { 215c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon return new GrVkGpuCommandBuffer(this, colorInfo, stencilInfo); 216066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 217066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::submitCommandBuffer(SyncQueue sync) { 219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 220164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 221164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 222164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->submitToQueue(this, fQueue, sync); 223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fResourceProvider.checkCommandBuffers(); 224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Release old command buffer and create a new one 226164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 2277ec92413307c9da43c013d1e4e15716a44059810jvanverth fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer(); 228164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 229164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 230164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->begin(this); 231164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 2341bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdaltonGrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern accessPattern, 2351bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton const void* data) { 2361bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton GrBuffer* buff; 237397536cabe12a9936659870dd220c869789424bacdalton switch (type) { 238397536cabe12a9936659870dd220c869789424bacdalton case kVertex_GrBufferType: 239397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kDynamic_GrAccessPattern == accessPattern || 240397536cabe12a9936659870dd220c869789424bacdalton kStatic_GrAccessPattern == accessPattern); 2411bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); 242e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 243397536cabe12a9936659870dd220c869789424bacdalton case kIndex_GrBufferType: 244397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kDynamic_GrAccessPattern == accessPattern || 245397536cabe12a9936659870dd220c869789424bacdalton kStatic_GrAccessPattern == accessPattern); 2461bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); 247e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 248397536cabe12a9936659870dd220c869789424bacdalton case kXferCpuToGpu_GrBufferType: 249c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth SkASSERT(kStream_GrAccessPattern == accessPattern); 2501bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type); 251e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 252397536cabe12a9936659870dd220c869789424bacdalton case kXferGpuToCpu_GrBufferType: 253c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth SkASSERT(kStream_GrAccessPattern == accessPattern); 2541bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type); 255e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 256397536cabe12a9936659870dd220c869789424bacdalton default: 257397536cabe12a9936659870dd220c869789424bacdalton SkFAIL("Unknown buffer type."); 258397536cabe12a9936659870dd220c869789424bacdalton return nullptr; 259397536cabe12a9936659870dd220c869789424bacdalton } 2601bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton if (data && buff) { 2611bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff->updateData(data, size); 2621bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton } 2631bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton return buff; 264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig srcConfig, DrawPreference* drawPreference, 269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel WritePixelTempDrawInfo* tempDrawInfo) { 270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurface->config())) { 271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 2744583ec51d9ddc830eeb854db068235be96ce59c4egdaniel GrRenderTarget* renderTarget = dstSurface->asRenderTarget(); 2754583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 2764583ec51d9ddc830eeb854db068235be96ce59c4egdaniel // Start off assuming no swizzling 2774583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); 2784583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fWriteConfig = srcConfig; 2794583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 2804583ec51d9ddc830eeb854db068235be96ce59c4egdaniel // These settings we will always want if a temp draw is performed. Initially set the config 2814583ec51d9ddc830eeb854db068235be96ce59c4egdaniel // to srcConfig, though that may be modified if we decide to do a R/B swap 2824583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags; 2834583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 2844583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fWidth = width; 2854583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fHeight = height; 2864583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 2874583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; 2884583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 289d66110f5972169dbcda8932c3a9a001adff23df4egdaniel if (dstSurface->config() == srcConfig) { 290d66110f5972169dbcda8932c3a9a001adff23df4egdaniel return true; 291d66110f5972169dbcda8932c3a9a001adff23df4egdaniel } 292d66110f5972169dbcda8932c3a9a001adff23df4egdaniel 29366933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (renderTarget && this->vkCaps().isConfigRenderable(renderTarget->config(), 29466933552f1723c4a2b248711ab3d43921401e8e6egdaniel renderTarget->numColorSamples() > 1)) { 2954583ec51d9ddc830eeb854db068235be96ce59c4egdaniel ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2964583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 2974583ec51d9ddc830eeb854db068235be96ce59c4egdaniel bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config(); 2984583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 2994583ec51d9ddc830eeb854db068235be96ce59c4egdaniel if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) { 3004583ec51d9ddc830eeb854db068235be96ce59c4egdaniel if (!this->vkCaps().isConfigTexturable(dstSurface->config())) { 3014583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return false; 3024583ec51d9ddc830eeb854db068235be96ce59c4egdaniel } 3034583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 3044583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 3054583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fWriteConfig = dstSurface->config(); 3064583ec51d9ddc830eeb854db068235be96ce59c4egdaniel } 3074583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return true; 308164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 309164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 3104583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return false; 311164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 312164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 313164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onWritePixels(GrSurface* surface, 314164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 315a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon GrPixelConfig config, 316a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon const SkTArray<GrMipLevel>& texels) { 317164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture()); 318164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!vkTex) { 319164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 320164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 321164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 322900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Make sure we have at least the base level 32303509eafa3e25819ff69f4d4f339d46264820c38jvanverth if (texels.empty() || !texels.begin()->fPixels) { 32403509eafa3e25819ff69f4d4f339d46264820c38jvanverth return false; 32503509eafa3e25819ff69f4d4f339d46264820c38jvanverth } 326a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon 327164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels. 328164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 329164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 330164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 331164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 332164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool success = false; 333164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) { 334164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo() 335164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(config == vkTex->desc().fConfig); 336164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: add compressed texture support 337164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // delete the following two lines and uncomment the two after that when ready 338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->unref(); 339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 340164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false, left, top, width, 341164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // height); 342164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 343164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = vkTex->isLinearTiled(); 344900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (linearTiling) { 345900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (texels.count() > 1) { 346900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkDebugf("Can't upload mipmap data to linear tiled texture"); 347900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 348900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 349900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (VK_IMAGE_LAYOUT_PREINITIALIZED != vkTex->currentLayout()) { 350900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Need to change the layout to general in order to perform a host write 351900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth vkTex->setImageLayout(this, 352900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_GENERAL, 35350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_HOST_WRITE_BIT, 35450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_HOST_BIT, 355900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth false); 356bdf8811b3126ab08ccff08b5e647b80cae5bd087egdaniel this->submitCommandBuffer(kForce_SyncQueue); 357900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 358900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataLinear(vkTex, left, top, width, height, config, 359900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth texels.begin()->fPixels, texels.begin()->fRowBytes); 360900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else { 361c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int newMipLevels = texels.count(); 36282c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth int currentMipLevels = vkTex->texturePriv().maxMipMapLevel() + 1; 36382c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth if (newMipLevels != currentMipLevels) { 364c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth if (!vkTex->reallocForMipmap(this, newMipLevels)) { 365900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 366900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 367900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 368900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config, texels); 369164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 3714583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 372900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return success; 373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 374164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 3754bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielvoid GrVkGpu::resolveImage(GrVkRenderTarget* dst, GrVkRenderTarget* src, const SkIRect& srcRect, 3764bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIPoint& dstPoint) { 3774bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(dst); 3784bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage()); 3794bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 380fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { 381fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); 382fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel } 383fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel 3844bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // Flip rect if necessary 3854bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkIRect srcVkRect = srcRect; 3864bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel int32_t dstY = dstPoint.fY; 3874bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 3884bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 3894bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); 3904bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcVkRect.fTop = src->height() - srcRect.fBottom; 3914bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcVkRect.fBottom = src->height() - srcRect.fTop; 3924bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dstY = dst->height() - dstPoint.fY - srcVkRect.height(); 3934bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 3944bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 3954bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VkImageResolve resolveInfo; 3964bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 3974bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 3984bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 3994bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.dstOffset = { dstPoint.fX, dstY, 0 }; 4004bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 }; 4014bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4024bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dst->setImageLayout(this, 4034bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 4044bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, 4054bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_PIPELINE_STAGE_TRANSFER_BIT, 4064bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel false); 4074bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4084bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel src->msaaImage()->setImageLayout(this, 4094bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4104bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_ACCESS_TRANSFER_READ_BIT, 4114bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_PIPELINE_STAGE_TRANSFER_BIT, 4124bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel false); 4134bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4144bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel fCurrentCmdBuffer->resolveImage(this, *src->msaaImage(), *dst, 1, &resolveInfo); 4154bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel} 4164bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 41752ad25151a1c7d1ac3872971f56adf15200c437eegdanielvoid GrVkGpu::onResolveRenderTarget(GrRenderTarget* target) { 41866933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (target->needsResolve()) { 41966933552f1723c4a2b248711ab3d43921401e8e6egdaniel SkASSERT(target->numColorSamples() > 1); 42052ad25151a1c7d1ac3872971f56adf15200c437eegdaniel GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); 42152ad25151a1c7d1ac3872971f56adf15200c437eegdaniel SkASSERT(rt->msaaImage()); 4224bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4234bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIRect& srcRect = rt->getResolveRect(); 42452ad25151a1c7d1ac3872971f56adf15200c437eegdaniel 4254bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel this->resolveImage(rt, rt, srcRect, SkIPoint::Make(srcRect.fLeft, srcRect.fTop)); 42652ad25151a1c7d1ac3872971f56adf15200c437eegdaniel 42752ad25151a1c7d1ac3872971f56adf15200c437eegdaniel rt->flagAsResolved(); 42852ad25151a1c7d1ac3872971f56adf15200c437eegdaniel } 42952ad25151a1c7d1ac3872971f56adf15200c437eegdaniel} 43052ad25151a1c7d1ac3872971f56adf15200c437eegdaniel 431900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex, 432900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth int left, int top, int width, int height, 433900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GrPixelConfig dataConfig, 434900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const void* data, 435900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth size_t rowBytes) { 436164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(data); 437900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(tex->isLinearTiled()); 438164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 439164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If we're uploading compressed data then we should be using uploadCompressedTexData 440164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 441164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 442164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t bpp = GrBytesPerPixel(dataConfig); 443164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 444164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurfaceDesc& desc = tex->desc(); 445164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 446164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 447164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &width, &height, &data, &rowBytes)) { 448164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 449164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 450164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t trimRowBytes = width * bpp; 451164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 452900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == tex->currentLayout() || 453900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_GENERAL == tex->currentLayout()); 454900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const VkImageSubresource subres = { 455900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_ASPECT_COLOR_BIT, 456900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 0, // mipLevel 457900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 0, // arraySlice 458900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth }; 459900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkSubresourceLayout layout; 460900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkResult err; 461900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 462900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const GrVkInterface* interface = this->vkInterface(); 463900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 464900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice, 465b2df0c2702329be6380a943d548e7377a51d8565egdaniel tex->image(), 466900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth &subres, 467900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth &layout)); 468900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 469900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth int texTop = kBottomLeft_GrSurfaceOrigin == desc.fOrigin ? tex->height() - top - height : top; 4701e305ba0d6a4237020d36234e9e286d3b0489401jvanverth const GrVkAlloc& alloc = tex->alloc(); 4711e305ba0d6a4237020d36234e9e286d3b0489401jvanverth VkDeviceSize offset = alloc.fOffset + texTop*layout.rowPitch + left*bpp; 472900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkDeviceSize size = height*layout.rowPitch; 473900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth void* mapPtr; 4741e305ba0d6a4237020d36234e9e286d3b0489401jvanverth err = GR_VK_CALL(interface, MapMemory(fDevice, alloc.fMemory, offset, size, 0, &mapPtr)); 475900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (err) { 476900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 477900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 478164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 479900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 480900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // copy into buffer by rows 481900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const char* srcRow = reinterpret_cast<const char*>(data); 482900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*layout.rowPitch; 483900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth for (int y = 0; y < height; y++) { 484900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth memcpy(dstRow, srcRow, trimRowBytes); 485900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth srcRow += rowBytes; 486900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth dstRow -= layout.rowPitch; 487900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 488900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else { 489900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // If there is no padding on the src (rowBytes) or dst (layout.rowPitch) we can memcpy 490900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (trimRowBytes == rowBytes && trimRowBytes == layout.rowPitch) { 491900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth memcpy(mapPtr, data, trimRowBytes * height); 492164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 49388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, trimRowBytes, 49488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel height); 495164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 496900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 497164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 4989d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkMemory::FlushMappedAlloc(this, alloc); 4991e305ba0d6a4237020d36234e9e286d3b0489401jvanverth GR_VK_CALL(interface, UnmapMemory(fDevice, alloc.fMemory)); 500900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 501900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return true; 502900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth} 503900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 504900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, 505a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth int left, int top, int width, int height, 506a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth GrPixelConfig dataConfig, 507a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth const SkTArray<GrMipLevel>& texels) { 508900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(!tex->isLinearTiled()); 509900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // The assumption is either that we have no mipmaps, or that our rect is the entire texture 510900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(1 == texels.count() || 511900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth (0 == left && 0 == top && width == tex->width() && height == tex->height())); 512900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 513900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // If we're uploading compressed data then we should be using uploadCompressedTexData 514900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 515900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 516900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (width == 0 || height == 0) { 517900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 518900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 519900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 520900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const GrSurfaceDesc& desc = tex->desc(); 521900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 522900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth size_t bpp = GrBytesPerPixel(dataConfig); 523900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 524900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // texels is const. 525c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // But we may need to adjust the fPixels ptr based on the copyRect, or fRowBytes. 526c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // Because of this we need to make a non-const shallow copy of texels. 527c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkTArray<GrMipLevel> texelsShallowCopy(texels); 528900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 529c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0; 530c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentMipLevel--) { 531c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkASSERT(texelsShallowCopy[currentMipLevel].fPixels); 532900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 533900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 534900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Determine whether we need to flip when we copy into the buffer 535c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty()); 536900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 537c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // adjust any params (left, top, currentWidth, currentHeight 538900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // find the combined size of all the mip levels and the relative offset of 539900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // each into the collective buffer 540c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // Do the first level separately because we may need to adjust width and height 541c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // (for the non-mipped case). 542c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 543c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &width, 544c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &height, 545c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[0].fPixels, 546c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[0].fRowBytes)) { 547c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth return false; 548c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth } 549c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkTArray<size_t> individualMipOffsets(texelsShallowCopy.count()); 550c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth individualMipOffsets.push_back(0); 551c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth size_t combinedBufferSize = width * bpp * height; 552c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int currentWidth = width; 553c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int currentHeight = height; 554c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth for (int currentMipLevel = 1; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 555c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentWidth = SkTMax(1, currentWidth/2); 556c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentHeight = SkTMax(1, currentHeight/2); 557c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 558c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth ¤tWidth, 559c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth ¤tHeight, 560c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[currentMipLevel].fPixels, 561c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[currentMipLevel].fRowBytes)) { 562c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth return false; 563c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth } 564900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const size_t trimmedSize = currentWidth * bpp * currentHeight; 565900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth individualMipOffsets.push_back(combinedBufferSize); 566900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth combinedBufferSize += trimmedSize; 567900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 568900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 569900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // allocate buffer to hold our mip data 570900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GrVkTransferBuffer* transferBuffer = 571900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuffer::kCopyRead_Type); 572900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 573900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth char* buffer = (char*) transferBuffer->map(); 574c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkTArray<VkBufferImageCopy> regions(texelsShallowCopy.count()); 575900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 576c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentWidth = width; 577c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentHeight = height; 578c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 579900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const size_t trimRowBytes = currentWidth * bpp; 580c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes; 581900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 582900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // copy data into the buffer, skipping the trailing bytes 583900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth char* dst = buffer + individualMipOffsets[currentMipLevel]; 584c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels; 585900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (flipY) { 586900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth src += (currentHeight - 1) * rowBytes; 587900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth for (int y = 0; y < currentHeight; y++) { 588900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth memcpy(dst, src, trimRowBytes); 589900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth src -= rowBytes; 590900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth dst += trimRowBytes; 591164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 592900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else if (trimRowBytes == rowBytes) { 593900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth memcpy(dst, src, trimRowBytes * currentHeight); 594164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 595900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, currentHeight); 596164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 597164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 598900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkBufferImageCopy& region = regions.push_back(); 599164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 600db37909347d034943bd6b0922710a94c6c6ea572jvanverth region.bufferOffset = transferBuffer->offset() + individualMipOffsets[currentMipLevel]; 601900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth region.bufferRowLength = currentWidth; 602900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth region.bufferImageHeight = currentHeight; 603cf942c4ef750712b624867cbb2217c14857db3c6bsalomon region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMipLevel), 0, 1 }; 604c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth region.imageOffset = { left, flipY ? tex->height() - top - currentHeight : top, 0 }; 605900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 }; 6064583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 607c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentWidth = SkTMax(1, currentWidth/2); 608c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentHeight = SkTMax(1, currentHeight/2); 609900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 610164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 6119d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth // no need to flush non-coherent memory, unmap will do that for us 612900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth transferBuffer->unmap(); 613164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 614900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Change layout of our target so it can be copied to 615900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth tex->setImageLayout(this, 616900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 61750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 61850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 619900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth false); 620900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 621900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Copy the buffer to the image 622900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth fCurrentCmdBuffer->copyBufferToImage(this, 623900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth transferBuffer, 624900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth tex, 625900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 626900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth regions.count(), 627900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth regions.begin()); 628900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth transferBuffer->unref(); 629164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 630164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 631164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 632164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 633164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 6342e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunenGrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 635a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon const SkTArray<GrMipLevel>& texels) { 636164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 637164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 638164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 639164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) { 640164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 641164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 642164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 643164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(desc.fConfig)) { 644164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 645164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 646164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 6470a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel if (renderTarget && !fVkCaps->isConfigRenderable(desc.fConfig, false)) { 6480a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel return nullptr; 6490a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel } 6500a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel 651164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 652164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (SkToBool(desc.fFlags & kZeroCopy_GrSurfaceFlag)) { 653900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // we can't have a linear texture with a mipmap 654900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (texels.count() > 1) { 655900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkDebugf("Trying to create linear tiled texture with mipmap"); 656900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return nullptr; 657900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 658a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel if (fVkCaps->isConfigTexturableLinearly(desc.fConfig) && 659164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel (!renderTarget || fVkCaps->isConfigRenderableLinearly(desc.fConfig, false))) { 660164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 661164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 662164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 663164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 666164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 667164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 668164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 669164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 670164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 671164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and 672164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we 673164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // will be using this texture in some copy or not. Also this assumes, as is the current case, 67462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // that all render targets in vulkan are also textures. If we change this practice of setting 675164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // both bits, we must make sure to set the destination bit if we are uploading srcData to the 676164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // texture. 677164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 678164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 679a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : 680a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 681164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 682164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is 68362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // requested, this ImageDesc describes the resolved texture. Therefore we always have samples set 684164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // to 1. 685c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int mipLevels = texels.empty() ? 1 : texels.count(); 686164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::ImageDesc imageDesc; 687164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageType = VK_IMAGE_TYPE_2D; 688164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fFormat = pixelFormat; 689164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fWidth = desc.fWidth; 690164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fHeight = desc.fHeight; 691c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth imageDesc.fLevels = linearTiling ? 1 : mipLevels; 692164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fSamples = 1; 693164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 694164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fUsageFlags = usageFlags; 695164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fMemProps = memProps; 696164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 697164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* tex; 698164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 6992e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, desc, 700164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc); 701164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 7022e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc); 703164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 704164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 705164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!tex) { 706164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 707164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 708164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 709e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (!texels.empty()) { 710e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon SkASSERT(texels.begin()->fPixels); 711900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth bool success; 712900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (linearTiling) { 713900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataLinear(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 714900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth texels.begin()->fPixels, texels.begin()->fRowBytes); 715900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else { 716900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataOptimal(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 717900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth texels); 718900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 719900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (!success) { 720164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->unref(); 721164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 722164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 723164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 724164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 725164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tex; 726164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 727164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 728164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 729164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 730db37909347d034943bd6b0922710a94c6c6ea572jvanverthbool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src, 731db37909347d034943bd6b0922710a94c6c6ea572jvanverth VkDeviceSize offset, VkDeviceSize size) { 732a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 733a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth // Update the buffer 734db37909347d034943bd6b0922710a94c6c6ea572jvanverth fCurrentCmdBuffer->updateBuffer(this, buffer, offset, size, src); 735a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 736a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth return true; 737a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth} 738a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 739a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth//////////////////////////////////////////////////////////////////////////////// 740a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 741164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) { 742164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // By default, all textures in Vk use TopLeft 743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kDefault_GrSurfaceOrigin == origin) { 744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return kTopLeft_GrSurfaceOrigin; 745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return origin; 747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 748164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 7506bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc, 7516bd5284415bd983b0628c4941dff5def40018f5abungeman GrWrapOwnership ownership) { 752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (0 == desc.fTextureHandle) { 753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 754164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int maxSize = this->caps()->maxTextureSize(); 757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 761b2df0c2702329be6380a943d548e7377a51d8565egdaniel const GrVkImageInfo* info = reinterpret_cast<const GrVkImageInfo*>(desc.fTextureHandle); 7621e305ba0d6a4237020d36234e9e286d3b0489401jvanverth if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc.fMemory) { 763fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return nullptr; 764fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 765b2df0c2702329be6380a943d548e7377a51d8565egdaniel#ifdef SK_DEBUG 766b2df0c2702329be6380a943d548e7377a51d8565egdaniel VkFormat format; 767b2df0c2702329be6380a943d548e7377a51d8565egdaniel if (!GrPixelConfigToVkFormat(desc.fConfig, &format)) { 768b2df0c2702329be6380a943d548e7377a51d8565egdaniel return nullptr; 769b2df0c2702329be6380a943d548e7377a51d8565egdaniel } 770b2df0c2702329be6380a943d548e7377a51d8565egdaniel SkASSERT(format == info->fFormat); 771b2df0c2702329be6380a943d548e7377a51d8565egdaniel#endif 772164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 773164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc surfDesc; 774164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // next line relies on GrBackendTextureDesc's flags matching GrTexture's 775164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags; 776164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fWidth = desc.fWidth; 777164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fHeight = desc.fHeight; 778164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fConfig = desc.fConfig; 779164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()); 780164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag); 781164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In GL, Chrome assumes all textures are BottomLeft 782164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In VK, we don't have this restriction 783164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fOrigin = resolve_origin(desc.fOrigin); 784164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 7856bd5284415bd983b0628c4941dff5def40018f5abungeman if (!renderTarget) { 7866bd5284415bd983b0628c4941dff5def40018f5abungeman return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, info); 787164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 7886bd5284415bd983b0628c4941dff5def40018f5abungeman return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership, info); 789164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 7916bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc, 7926bd5284415bd983b0628c4941dff5def40018f5abungeman GrWrapOwnership ownership) { 7939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 794b2df0c2702329be6380a943d548e7377a51d8565egdaniel const GrVkImageInfo* info = 795b2df0c2702329be6380a943d548e7377a51d8565egdaniel reinterpret_cast<const GrVkImageInfo*>(wrapDesc.fRenderTargetHandle); 796fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (VK_NULL_HANDLE == info->fImage || 7971e305ba0d6a4237020d36234e9e286d3b0489401jvanverth (VK_NULL_HANDLE == info->fAlloc.fMemory && kAdopt_GrWrapOwnership == ownership)) { 798fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return nullptr; 799fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 801164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc desc; 802164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fConfig = wrapDesc.fConfig; 8033667b4970d6972675be58a331be7c5ba02f3d39eRobert Phillips desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; 804164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fWidth = wrapDesc.fWidth; 805164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fHeight = wrapDesc.fHeight; 806164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()); 807164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 808164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fOrigin = resolve_origin(wrapDesc.fOrigin); 809164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8106bd5284415bd983b0628c4941dff5def40018f5abungeman sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, 8116bd5284415bd983b0628c4941dff5def40018f5abungeman ownership, info); 812164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (tgt && wrapDesc.fStencilBits) { 8136bd5284415bd983b0628c4941dff5def40018f5abungeman if (!createStencilAttachmentForRenderTarget(tgt.get(), desc.fWidth, desc.fHeight)) { 814164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 815164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 816164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 817164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tgt; 818164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 819164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 82050ead53ac97deb23310916e3736c3f5e2d8f7f4begdanielvoid GrVkGpu::generateMipmap(GrVkTexture* tex) { 821900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // don't do anything for linearly tiled textures (can't have mipmaps) 82262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth if (tex->isLinearTiled()) { 823900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkDebugf("Trying to create mipmap for linear tiled texture"); 82462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth return; 82562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth } 82662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 82762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // determine if we can blit to and from this format 82862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth const GrVkCaps& caps = this->vkCaps(); 82962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth if (!caps.configCanBeDstofBlit(tex->config(), false) || 8302f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel !caps.configCanBeSrcofBlit(tex->config(), false) || 8312f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel !caps.mipMapSupport()) { 83262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth return; 83362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth } 83462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 835fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { 836fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel this->submitCommandBuffer(kSkip_SyncQueue); 837fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel } 838fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel 83966933552f1723c4a2b248711ab3d43921401e8e6egdaniel // We may need to resolve the texture first if it is also a render target 84066933552f1723c4a2b248711ab3d43921401e8e6egdaniel GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(tex->asRenderTarget()); 84166933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (texRT) { 84266933552f1723c4a2b248711ab3d43921401e8e6egdaniel this->onResolveRenderTarget(texRT); 84366933552f1723c4a2b248711ab3d43921401e8e6egdaniel } 84466933552f1723c4a2b248711ab3d43921401e8e6egdaniel 8457ac5da853457b032781cf865ba018de78508edb7egdaniel int width = tex->width(); 8467ac5da853457b032781cf865ba018de78508edb7egdaniel int height = tex->height(); 8477ac5da853457b032781cf865ba018de78508edb7egdaniel VkImageBlit blitRegion; 8487ac5da853457b032781cf865ba018de78508edb7egdaniel memset(&blitRegion, 0, sizeof(VkImageBlit)); 84962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 85082c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth // SkMipMap doesn't include the base level in the level count so we have to add 1 85182c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height()) + 1; 8527ac5da853457b032781cf865ba018de78508edb7egdaniel if (levelCount != tex->mipLevels()) { 8537ac5da853457b032781cf865ba018de78508edb7egdaniel const GrVkResource* oldResource = tex->resource(); 8547ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource->ref(); 8557ac5da853457b032781cf865ba018de78508edb7egdaniel // grab handle to the original image resource 8567ac5da853457b032781cf865ba018de78508edb7egdaniel VkImage oldImage = tex->image(); 8577ac5da853457b032781cf865ba018de78508edb7egdaniel 8587ac5da853457b032781cf865ba018de78508edb7egdaniel // change the original image's layout so we can copy from it 8597ac5da853457b032781cf865ba018de78508edb7egdaniel tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 8607ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); 8617ac5da853457b032781cf865ba018de78508edb7egdaniel 8627ac5da853457b032781cf865ba018de78508edb7egdaniel if (!tex->reallocForMipmap(this, levelCount)) { 8637ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource->unref(this); 8647ac5da853457b032781cf865ba018de78508edb7egdaniel return; 8657ac5da853457b032781cf865ba018de78508edb7egdaniel } 8667ac5da853457b032781cf865ba018de78508edb7egdaniel // change the new image's layout so we can blit to it 8677ac5da853457b032781cf865ba018de78508edb7egdaniel tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, 8687ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); 86962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 8707ac5da853457b032781cf865ba018de78508edb7egdaniel // Blit original image to top level of new image 8717ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 8727ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.srcOffsets[0] = { 0, 0, 0 }; 8737ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.srcOffsets[1] = { width, height, 1 }; 8747ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 8757ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.dstOffsets[0] = { 0, 0, 0 }; 8767ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.dstOffsets[1] = { width, height, 1 }; 87762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 8787ac5da853457b032781cf865ba018de78508edb7egdaniel fCurrentCmdBuffer->blitImage(this, 8797ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource, 8807ac5da853457b032781cf865ba018de78508edb7egdaniel oldImage, 8817ac5da853457b032781cf865ba018de78508edb7egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 8827ac5da853457b032781cf865ba018de78508edb7egdaniel tex->resource(), 8837ac5da853457b032781cf865ba018de78508edb7egdaniel tex->image(), 8847ac5da853457b032781cf865ba018de78508edb7egdaniel VK_IMAGE_LAYOUT_GENERAL, 8857ac5da853457b032781cf865ba018de78508edb7egdaniel 1, 8867ac5da853457b032781cf865ba018de78508edb7egdaniel &blitRegion, 8877ac5da853457b032781cf865ba018de78508edb7egdaniel VK_FILTER_LINEAR); 88862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 8897ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource->unref(this); 8907ac5da853457b032781cf865ba018de78508edb7egdaniel } else { 8917ac5da853457b032781cf865ba018de78508edb7egdaniel // change layout of the layers so we can write to them. 8927ac5da853457b032781cf865ba018de78508edb7egdaniel tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, 8937ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); 8947ac5da853457b032781cf865ba018de78508edb7egdaniel } 89550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth 89650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth // setup memory barrier 897b2df0c2702329be6380a943d548e7377a51d8565egdaniel SkASSERT(GrVkFormatToPixelConfig(tex->imageFormat(), nullptr)); 89850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; 89950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VkImageMemoryBarrier imageMemoryBarrier = { 90050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 90150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth NULL, // pNext 9027ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask 9037ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask 90450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_IMAGE_LAYOUT_GENERAL, // oldLayout 90550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_IMAGE_LAYOUT_GENERAL, // newLayout 90650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 90750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex 908b2df0c2702329be6380a943d548e7377a51d8565egdaniel tex->image(), // image 90950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth { aspectFlags, 0, 1, 0, 1 } // subresourceRange 91050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth }; 91150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth 91262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // Blit the miplevels 91382c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth uint32_t mipLevel = 1; 91482c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth while (mipLevel < levelCount) { 91582c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth int prevWidth = width; 91682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth int prevHeight = height; 91782c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth width = SkTMax(1, width / 2); 91882c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth height = SkTMax(1, height / 2); 91982c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth 92050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth imageMemoryBarrier.subresourceRange.baseMipLevel = mipLevel - 1; 92150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth this->addImageMemoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 92250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth false, &imageMemoryBarrier); 92350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth 92450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel - 1, 0, 1 }; 92562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth blitRegion.srcOffsets[0] = { 0, 0, 0 }; 926e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman blitRegion.srcOffsets[1] = { prevWidth, prevHeight, 1 }; 92782c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 }; 92862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth blitRegion.dstOffsets[0] = { 0, 0, 0 }; 929e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman blitRegion.dstOffsets[1] = { width, height, 1 }; 93062340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth fCurrentCmdBuffer->blitImage(this, 931b2df0c2702329be6380a943d548e7377a51d8565egdaniel *tex, 932b2df0c2702329be6380a943d548e7377a51d8565egdaniel *tex, 93362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 1, 93462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth &blitRegion, 93562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth VK_FILTER_LINEAR); 93682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth ++mipLevel; 93762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth } 93862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth} 93962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 940164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 941164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 942164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 943164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int width, 944164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int height) { 945164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(width >= rt->width()); 946164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(height >= rt->height()); 947164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 948164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int samples = rt->numStencilSamples(); 949164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 9508f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10egdaniel const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat(); 951164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 952164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this, 953164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel width, 954164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel height, 955164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel samples, 956164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel sFmt)); 957164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fStats.incStencilAttachmentCreates(); 958164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return stencil; 959164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 960164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 961164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 962164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 9639d54afc38b171c01a03b34e773d154fcf83d97dcjvanverthbool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc, 9643602d4f16a01da860d16eb36fb52eb62487495ccegdaniel size_t srcRowBytes, size_t dstRowBytes, int h) { 9653602d4f16a01da860d16eb36fb52eb62487495ccegdaniel void* mapPtr; 9663602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(), 9679d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth alloc.fMemory, 9689d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth alloc.fOffset, 9693602d4f16a01da860d16eb36fb52eb62487495ccegdaniel dstRowBytes * h, 9703602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 0, 9713602d4f16a01da860d16eb36fb52eb62487495ccegdaniel &mapPtr)); 9723602d4f16a01da860d16eb36fb52eb62487495ccegdaniel if (err) { 9733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return false; 9743602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 9753602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 9763602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // If there is no padding on dst we can do a single memcopy. 9773602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // This assumes the srcData comes in with no padding. 9783602d4f16a01da860d16eb36fb52eb62487495ccegdaniel if (srcRowBytes == dstRowBytes) { 9793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memcpy(mapPtr, srcData, srcRowBytes * h); 9803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } else { 9813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkRectMemcpy(mapPtr, static_cast<size_t>(dstRowBytes), srcData, srcRowBytes, 9823602d4f16a01da860d16eb36fb52eb62487495ccegdaniel srcRowBytes, h); 9833602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 9849d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkMemory::FlushMappedAlloc(gpu, alloc); 9859d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GR_VK_CALL(gpu->vkInterface(), UnmapMemory(gpu->device(), alloc.fMemory)); 9863602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return true; 9873602d4f16a01da860d16eb36fb52eb62487495ccegdaniel} 9883602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 989164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h, 9900a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel GrPixelConfig config, 9910a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel bool isRenderTarget) { 992164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 993164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 994164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 995164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 996164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 997164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 998164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 999164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(config)) { 1000164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 1001164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1002164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10030a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) { 10040a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel return 0; 10050a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel } 10060a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel 1007a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel if (fVkCaps->isConfigTexturableLinearly(config) && 10080a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel (!isRenderTarget || fVkCaps->isConfigRenderableLinearly(config, false))) { 1009164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 1010164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1011164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1012164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 1013164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1014164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 10150a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel if (isRenderTarget) { 10160a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 10170a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel } 1018164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1019fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImage image = VK_NULL_HANDLE; 10209d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkAlloc alloc = { VK_NULL_HANDLE, 0, 0, 0 }; 1021164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1022fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 1023fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling) 1024fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth ? VK_IMAGE_LAYOUT_PREINITIALIZED 1025fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth : VK_IMAGE_LAYOUT_UNDEFINED; 1026fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1027fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth // Create Image 1028fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkSampleCountFlagBits vkSamples; 1029fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (!GrSampleCountToVkSampleCount(1, &vkSamples)) { 1030fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return 0; 1031fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 1032fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1033fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const VkImageCreateInfo imageCreateInfo = { 1034fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 1035fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth NULL, // pNext 1036fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // VkImageCreateFlags 1037fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_IMAGE_TYPE_2D, // VkImageType 1038fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth pixelFormat, // VkFormat 1039384b5e9cd36e443437de8df3b0f78ef4150efbacethannicholas { (uint32_t) w, (uint32_t) h, 1 }, // VkExtent3D 1040fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1, // mipLevels 1041fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1, // arrayLayers 1042fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth vkSamples, // samples 1043fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth imageTiling, // VkImageTiling 1044fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth usageFlags, // VkImageUsageFlags 1045fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode 1046fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // queueFamilyCount 1047fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // pQueueFamilyIndices 1048fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth initialLayout // initialLayout 1049fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth }; 1050fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1051fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image)); 1052fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 10536b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth if (!GrVkMemory::AllocAndBindImageMemory(this, image, linearTiling, &alloc)) { 1054fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(DestroyImage(this->device(), image, nullptr)); 1055164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 1056164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1057164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1058164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcData) { 10593602d4f16a01da860d16eb36fb52eb62487495ccegdaniel size_t bpp = GrBytesPerPixel(config); 10603602d4f16a01da860d16eb36fb52eb62487495ccegdaniel size_t rowCopyBytes = bpp * w; 1061164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling) { 1062164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkImageSubresource subres = { 1063164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_ASPECT_COLOR_BIT, 1064164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // mipLevel 1065164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // arraySlice 1066164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 1067164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkSubresourceLayout layout; 1068164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1069fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout)); 1070164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10719d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth if (!copy_testing_data(this, srcData, alloc, rowCopyBytes, 1072583bc2e98d8105fc799897daea28eea03c23fbbcbrianosman static_cast<size_t>(layout.rowPitch), h)) { 10733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 10743602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 10753602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return 0; 10763602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 10773602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } else { 10783602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkASSERT(w && h); 10793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 10803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkBuffer buffer; 10813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkBufferCreateInfo bufInfo; 10823602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memset(&bufInfo, 0, sizeof(VkBufferCreateInfo)); 10833602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 10843602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.flags = 0; 10853602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.size = rowCopyBytes * h; 10863602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 10873602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 10883602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.queueFamilyIndexCount = 0; 10893602d4f16a01da860d16eb36fb52eb62487495ccegdaniel bufInfo.pQueueFamilyIndices = nullptr; 10903602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkResult err; 10913602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(CreateBuffer(fDevice, &bufInfo, nullptr, &buffer)); 10923602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 1093164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 10946b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 10953602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 1096164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 1097164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1098164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10999d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0, 0 }; 11003602d4f16a01da860d16eb36fb52eb62487495ccegdaniel if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type, 11013602d4f16a01da860d16eb36fb52eb62487495ccegdaniel true, &bufferAlloc)) { 11023602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 11033602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 11043602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 11053602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return 0; 1106164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 11073602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11089d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth if (!copy_testing_data(this, srcData, bufferAlloc, rowCopyBytes, rowCopyBytes, h)) { 11093602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 11103602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 11113602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 11123602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 11133602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return 0; 11143602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 11153602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11163602d4f16a01da860d16eb36fb52eb62487495ccegdaniel const VkCommandBufferAllocateInfo cmdInfo = { 11173602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType 11183602d4f16a01da860d16eb36fb52eb62487495ccegdaniel NULL, // pNext 11193602d4f16a01da860d16eb36fb52eb62487495ccegdaniel fCmdPool, // commandPool 11203602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level 11213602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 1 // bufferCount 11223602d4f16a01da860d16eb36fb52eb62487495ccegdaniel }; 11233602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11243602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkCommandBuffer cmdBuffer; 11253602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer)); 11263602d4f16a01da860d16eb36fb52eb62487495ccegdaniel if (err) { 11273602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 11283602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 11293602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 11303602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 11313602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return 0; 11323602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 11333602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11343602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkCommandBufferBeginInfo cmdBufferBeginInfo; 11353602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo)); 11363602d4f16a01da860d16eb36fb52eb62487495ccegdaniel cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 11373602d4f16a01da860d16eb36fb52eb62487495ccegdaniel cmdBufferBeginInfo.pNext = nullptr; 11383602d4f16a01da860d16eb36fb52eb62487495ccegdaniel cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 11393602d4f16a01da860d16eb36fb52eb62487495ccegdaniel cmdBufferBeginInfo.pInheritanceInfo = nullptr; 11403602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11413602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo)); 11423602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkASSERT(!err); 11433602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11443602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // Set image layout and add barrier 11453602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkImageMemoryBarrier barrier; 11463602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memset(&barrier, 0, sizeof(VkImageMemoryBarrier)); 11473602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 11483602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.pNext = nullptr; 11493602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout); 11503602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 11513602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 11523602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11533602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11543602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.image = image; 11553602d4f16a01da860d16eb36fb52eb62487495ccegdaniel barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0 , 1}; 11563602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11573602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(CmdPipelineBarrier(cmdBuffer, 11583602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::LayoutToPipelineStageFlags(initialLayout), 11593602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_PIPELINE_STAGE_TRANSFER_BIT, 11603602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 0, 11613602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 0, nullptr, 11623602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 0, nullptr, 11633602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 1, &barrier)); 11643602d4f16a01da860d16eb36fb52eb62487495ccegdaniel initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 11653602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11663602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // Submit copy command 11673602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkBufferImageCopy region; 11683602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 11693602d4f16a01da860d16eb36fb52eb62487495ccegdaniel region.bufferOffset = 0; 1170a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel region.bufferRowLength = w; 11713602d4f16a01da860d16eb36fb52eb62487495ccegdaniel region.bufferImageHeight = h; 11723602d4f16a01da860d16eb36fb52eb62487495ccegdaniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 11733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel region.imageOffset = { 0, 0, 0 }; 11743602d4f16a01da860d16eb36fb52eb62487495ccegdaniel region.imageExtent = { (uint32_t)w, (uint32_t)h, 1 }; 11753602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11763602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, 1, ®ion)); 11773602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11783602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // End CommandBuffer 11793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(EndCommandBuffer(cmdBuffer)); 11803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkASSERT(!err); 11813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11823602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // Create Fence for queue 11833602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkFence fence; 11843602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkFenceCreateInfo fenceInfo; 11853602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo)); 11863602d4f16a01da860d16eb36fb52eb62487495ccegdaniel fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 11873602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11883602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence)); 11893602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkASSERT(!err); 11903602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 11913602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkSubmitInfo submitInfo; 11923602d4f16a01da860d16eb36fb52eb62487495ccegdaniel memset(&submitInfo, 0, sizeof(VkSubmitInfo)); 11933602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 11943602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.pNext = nullptr; 11953602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.waitSemaphoreCount = 0; 11963602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.pWaitSemaphores = nullptr; 11973602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.pWaitDstStageMask = 0; 11983602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.commandBufferCount = 1; 11993602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.pCommandBuffers = &cmdBuffer; 12003602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.signalSemaphoreCount = 0; 12013602d4f16a01da860d16eb36fb52eb62487495ccegdaniel submitInfo.pSignalSemaphores = nullptr; 12023602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence)); 12033602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkASSERT(!err); 12043602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 12053602d4f16a01da860d16eb36fb52eb62487495ccegdaniel err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX)); 12063602d4f16a01da860d16eb36fb52eb62487495ccegdaniel if (VK_TIMEOUT == err) { 12073602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 12083602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 12093602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 12103602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 12113602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); 12123602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyFence(fDevice, fence, nullptr)); 12133602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkDebugf("Fence failed to signal: %d\n", err); 12143602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkFAIL("failing"); 12153602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 12163602d4f16a01da860d16eb36fb52eb62487495ccegdaniel SkASSERT(!err); 12173602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 12183602d4f16a01da860d16eb36fb52eb62487495ccegdaniel // Clean up transfer resources 12193602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 12203602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 12213602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); 12223602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyFence(fDevice, fence, nullptr)); 1223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1226b2df0c2702329be6380a943d548e7377a51d8565egdaniel GrVkImageInfo* info = new GrVkImageInfo; 1227fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImage = image; 1228fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fAlloc = alloc; 1229fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImageTiling = imageTiling; 1230fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImageLayout = initialLayout; 123158a8d9214a70e0f6c81c88a8b0b563c06bf0f70eegdaniel info->fFormat = pixelFormat; 12322af0f1b014b9aabb6119bf66fac20e4cd3a8279bjvanverth info->fLevelCount = 1; 1233fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1234fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return (GrBackendObject)info; 1235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { 1238b2df0c2702329be6380a943d548e7377a51d8565egdaniel const GrVkImageInfo* backend = reinterpret_cast<const GrVkImageInfo*>(id); 1239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 12401e305ba0d6a4237020d36234e9e286d3b0489401jvanverth if (backend && backend->fImage && backend->fAlloc.fMemory) { 1241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryRequirements req; 1242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&req, 0, sizeof(req)); 1243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, 1244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel backend->fImage, 1245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &req)); 1246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: find a better check 1247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This will probably fail with a different driver 1248164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return (req.size > 0) && (req.size <= 8192 * 8192); 1249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1251164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1252164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) { 12556b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth GrVkImageInfo* backend = reinterpret_cast<GrVkImageInfo*>(id); 1256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (backend) { 1257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!abandon) { 1258fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth // something in the command buffer may still be using this, so force submit 1259fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth this->submitCommandBuffer(kForce_SyncQueue); 12606b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth GrVkImage::DestroyImageInfo(this, backend); 1261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1262fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth delete backend; 1263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 1267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask, 1269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 1270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 1271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryBarrier* barrier) const { 1272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 1273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 1274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 1277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kMemory_BarrierType, 1278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 1279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addBufferMemoryBarrier(VkPipelineStageFlags srcStageMask, 1282164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 1283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 1284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferMemoryBarrier* barrier) const { 1285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 1286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 1287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1289164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 1290164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kBufferMemory_BarrierType, 1291164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 1292164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1293164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1294164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask, 1295164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 1296164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 1297164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageMemoryBarrier* barrier) const { 1298164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 1299164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 1300164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1301164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1302164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 1303164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kImageMemory_BarrierType, 1304164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 1305164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1306164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1307f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillipsvoid GrVkGpu::finishOpList() { 1308164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Submit the current command buffer to the Queue 1309164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 1310164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1311164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 13123d5d9ac426ea926f37eaa47e13acf7492068667begdanielvoid GrVkGpu::clearStencil(GrRenderTarget* target) { 13133d5d9ac426ea926f37eaa47e13acf7492068667begdaniel if (nullptr == target) { 13143d5d9ac426ea926f37eaa47e13acf7492068667begdaniel return; 13153d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 13163d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrStencilAttachment* stencil = target->renderTargetPriv().getStencilAttachment(); 13173d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; 13183d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 13193d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 13203d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkClearDepthStencilValue vkStencilColor; 13213d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); 13223d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 13233d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencil->setImageLayout(this, 13243d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 132550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 132650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 13273d5d9ac426ea926f37eaa47e13acf7492068667begdaniel false); 13283d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 13293d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkImageSubresourceRange subRange; 13303d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&subRange, 0, sizeof(VkImageSubresourceRange)); 13313d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 13323d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.baseMipLevel = 0; 13333d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.levelCount = 1; 13343d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.baseArrayLayer = 0; 13353d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.layerCount = 1; 13363d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 13373d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a 13383d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // draw. Thus we should look into using the load op functions on the render pass to clear out 13393d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // the stencil there. 13403d5d9ac426ea926f37eaa47e13acf7492068667begdaniel fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange); 13413d5d9ac426ea926f37eaa47e13acf7492068667begdaniel} 13423d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 1343164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_image(const GrSurface* dst, 1344164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 1345164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 13464bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrRenderTarget* dstRT = dst->asRenderTarget(); 13474bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrRenderTarget* srcRT = src->asRenderTarget(); 13484bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (dstRT && srcRT) { 13494bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (srcRT->numColorSamples() != dstRT->numColorSamples()) { 13504bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 13514bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 13524bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } else if (dstRT) { 13534bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (dstRT->numColorSamples() > 1) { 13544bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 13554bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 13564bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } else if (srcRT) { 13574bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (srcRT->numColorSamples() > 1) { 13584bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 13594bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 136017b892551465e5a44560a06e4b34dc3592b49622egdaniel } 136117b892551465e5a44560a06e4b34dc3592b49622egdaniel 136217b892551465e5a44560a06e4b34dc3592b49622egdaniel // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src 136317b892551465e5a44560a06e4b34dc3592b49622egdaniel // as image usage flags. 136417b892551465e5a44560a06e4b34dc3592b49622egdaniel if (src->origin() == dst->origin() && 136517b892551465e5a44560a06e4b34dc3592b49622egdaniel GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { 1366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1367164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1368164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1369164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1372164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, 1373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 137417b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* dstImage, 137517b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* srcImage, 1376164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1377164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1378164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(can_copy_image(dst, src, this)); 1379164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // These flags are for flushing/invalidating caches and for the dst image it doesn't matter if 1381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // the cache is flushed since it is only being written to. 138217b892551465e5a44560a06e4b34dc3592b49622egdaniel dstImage->setImageLayout(this, 138350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 138450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 138550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 138650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth false); 1387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 138817b892551465e5a44560a06e4b34dc3592b49622egdaniel srcImage->setImageLayout(this, 138917b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 139050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_READ_BIT, 139150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 139217b892551465e5a44560a06e4b34dc3592b49622egdaniel false); 1393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Flip rect if necessary 1395164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkIRect srcVkRect = srcRect; 1396164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int32_t dstY = dstPoint.fY; 1397164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1398164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 1399164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); 1400164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fTop = src->height() - srcRect.fBottom; 1401164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fBottom = src->height() - srcRect.fTop; 1402164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstY = dst->height() - dstPoint.fY - srcVkRect.height(); 1403164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1404164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1405164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageCopy copyRegion; 1406164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(©Region, 0, sizeof(VkImageCopy)); 1407164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1408164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 1409164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1410164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstOffset = { dstPoint.fX, dstY, 0 }; 1411c355bc8dd117291b63ee7b7b39ec37a0e768eec5egdaniel copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 }; 1412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1413164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImage(this, 141417b892551465e5a44560a06e4b34dc3592b49622egdaniel srcImage, 1415164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 141617b892551465e5a44560a06e4b34dc3592b49622egdaniel dstImage, 1417164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1419164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ©Region); 1420900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 1421900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 1422900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth srcRect.width(), srcRect.height()); 1423900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth this->didWriteToSurface(dst, &dstRect); 1424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1425164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 142617b892551465e5a44560a06e4b34dc3592b49622egdanielinline bool can_copy_as_blit(const GrSurface* dst, 142717b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrSurface* src, 142817b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkImage* dstImage, 142917b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkImage* srcImage, 143017b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkGpu* gpu) { 143166933552f1723c4a2b248711ab3d43921401e8e6egdaniel // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src 143217b892551465e5a44560a06e4b34dc3592b49622egdaniel // as image usage flags. 143317b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkCaps& caps = gpu->vkCaps(); 143417b892551465e5a44560a06e4b34dc3592b49622egdaniel if (!caps.configCanBeDstofBlit(dst->config(), dstImage->isLinearTiled()) || 143517b892551465e5a44560a06e4b34dc3592b49622egdaniel !caps.configCanBeSrcofBlit(src->config(), srcImage->isLinearTiled())) { 143617b892551465e5a44560a06e4b34dc3592b49622egdaniel return false; 143717b892551465e5a44560a06e4b34dc3592b49622egdaniel } 143817b892551465e5a44560a06e4b34dc3592b49622egdaniel 143917b892551465e5a44560a06e4b34dc3592b49622egdaniel // We cannot blit images that are multisampled. Will need to figure out if we can blit the 144017b892551465e5a44560a06e4b34dc3592b49622egdaniel // resolved msaa though. 144117b892551465e5a44560a06e4b34dc3592b49622egdaniel if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || 144217b892551465e5a44560a06e4b34dc3592b49622egdaniel (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) { 144317b892551465e5a44560a06e4b34dc3592b49622egdaniel return false; 144417b892551465e5a44560a06e4b34dc3592b49622egdaniel } 144517b892551465e5a44560a06e4b34dc3592b49622egdaniel 144617b892551465e5a44560a06e4b34dc3592b49622egdaniel return true; 144717b892551465e5a44560a06e4b34dc3592b49622egdaniel} 144817b892551465e5a44560a06e4b34dc3592b49622egdaniel 144917b892551465e5a44560a06e4b34dc3592b49622egdanielvoid GrVkGpu::copySurfaceAsBlit(GrSurface* dst, 145017b892551465e5a44560a06e4b34dc3592b49622egdaniel GrSurface* src, 145117b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* dstImage, 145217b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* srcImage, 145317b892551465e5a44560a06e4b34dc3592b49622egdaniel const SkIRect& srcRect, 145417b892551465e5a44560a06e4b34dc3592b49622egdaniel const SkIPoint& dstPoint) { 145517b892551465e5a44560a06e4b34dc3592b49622egdaniel SkASSERT(can_copy_as_blit(dst, src, dstImage, srcImage, this)); 145617b892551465e5a44560a06e4b34dc3592b49622egdaniel 145717b892551465e5a44560a06e4b34dc3592b49622egdaniel dstImage->setImageLayout(this, 145817b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 145950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 146050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 146117b892551465e5a44560a06e4b34dc3592b49622egdaniel false); 146217b892551465e5a44560a06e4b34dc3592b49622egdaniel 146317b892551465e5a44560a06e4b34dc3592b49622egdaniel srcImage->setImageLayout(this, 146417b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 146550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_READ_BIT, 146650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 146717b892551465e5a44560a06e4b34dc3592b49622egdaniel false); 146817b892551465e5a44560a06e4b34dc3592b49622egdaniel 146917b892551465e5a44560a06e4b34dc3592b49622egdaniel // Flip rect if necessary 147017b892551465e5a44560a06e4b34dc3592b49622egdaniel SkIRect srcVkRect; 14718af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fLeft = srcRect.fLeft; 14728af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fRight = srcRect.fRight; 147317b892551465e5a44560a06e4b34dc3592b49622egdaniel SkIRect dstRect; 147417b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fLeft = dstPoint.fX; 14758af936d3047208def585b7bc824f013b994f6312egdaniel dstRect.fRight = dstPoint.fX + srcRect.width(); 147617b892551465e5a44560a06e4b34dc3592b49622egdaniel 147717b892551465e5a44560a06e4b34dc3592b49622egdaniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 147817b892551465e5a44560a06e4b34dc3592b49622egdaniel srcVkRect.fTop = src->height() - srcRect.fBottom; 147917b892551465e5a44560a06e4b34dc3592b49622egdaniel srcVkRect.fBottom = src->height() - srcRect.fTop; 148017b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 14818af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fTop = srcRect.fTop; 14828af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fBottom = srcRect.fBottom; 148317b892551465e5a44560a06e4b34dc3592b49622egdaniel } 148417b892551465e5a44560a06e4b34dc3592b49622egdaniel 148517b892551465e5a44560a06e4b34dc3592b49622egdaniel if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 148617b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fTop = dst->height() - dstPoint.fY - srcVkRect.height(); 148717b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 148817b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fTop = dstPoint.fY; 148917b892551465e5a44560a06e4b34dc3592b49622egdaniel } 149017b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fBottom = dstRect.fTop + srcVkRect.height(); 149117b892551465e5a44560a06e4b34dc3592b49622egdaniel 149217b892551465e5a44560a06e4b34dc3592b49622egdaniel // If we have different origins, we need to flip the top and bottom of the dst rect so that we 149317b892551465e5a44560a06e4b34dc3592b49622egdaniel // get the correct origintation of the copied data. 149417b892551465e5a44560a06e4b34dc3592b49622egdaniel if (src->origin() != dst->origin()) { 149517b892551465e5a44560a06e4b34dc3592b49622egdaniel SkTSwap(dstRect.fTop, dstRect.fBottom); 149617b892551465e5a44560a06e4b34dc3592b49622egdaniel } 149717b892551465e5a44560a06e4b34dc3592b49622egdaniel 149817b892551465e5a44560a06e4b34dc3592b49622egdaniel VkImageBlit blitRegion; 149917b892551465e5a44560a06e4b34dc3592b49622egdaniel memset(&blitRegion, 0, sizeof(VkImageBlit)); 150017b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 150117b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 1502e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 1 }; 150317b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 150417b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 }; 1505e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 1 }; 150617b892551465e5a44560a06e4b34dc3592b49622egdaniel 150717b892551465e5a44560a06e4b34dc3592b49622egdaniel fCurrentCmdBuffer->blitImage(this, 1508b2df0c2702329be6380a943d548e7377a51d8565egdaniel *srcImage, 1509b2df0c2702329be6380a943d548e7377a51d8565egdaniel *dstImage, 151017b892551465e5a44560a06e4b34dc3592b49622egdaniel 1, 151117b892551465e5a44560a06e4b34dc3592b49622egdaniel &blitRegion, 151217b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_FILTER_NEAREST); // We never scale so any filter works here 1513900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 1514900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth this->didWriteToSurface(dst, &dstRect); 151517b892551465e5a44560a06e4b34dc3592b49622egdaniel} 151617b892551465e5a44560a06e4b34dc3592b49622egdaniel 15174bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielinline bool can_copy_as_resolve(const GrSurface* dst, 15184bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrSurface* src, 15194bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrVkGpu* gpu) { 15204bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // Our src must be a multisampled render target 15214bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (!src->asRenderTarget() || src->asRenderTarget()->numColorSamples() <= 1) { 15224bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 15234bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 15244bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 15254bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // The dst must be a render target but not multisampled 15264bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (!dst->asRenderTarget() || dst->asRenderTarget()->numColorSamples() > 1) { 15274bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 15284bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 15294bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 15304bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // Surfaces must have the same origin. 15314bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (src->origin() != dst->origin()) { 15324bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 15334bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 15344bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 15354bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return true; 15364bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel} 15374bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 15384bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielvoid GrVkGpu::copySurfaceAsResolve(GrSurface* dst, 15394bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrSurface* src, 15404bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIRect& srcRect, 15414bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIPoint& dstPoint) { 15424bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* dstRT = static_cast<GrVkRenderTarget*>(dst->asRenderTarget()); 15434bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget()); 15444bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(dstRT && dstRT->numColorSamples() <= 1); 15454bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel this->resolveImage(dstRT, srcRT, srcRect, dstPoint); 15464bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel} 15474bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 1548164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_as_draw(const GrSurface* dst, 1549164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 1550164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 1551164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1552164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1553164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1554164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsDraw(GrSurface* dst, 1555164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1556164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1557164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1558164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(false); 1559164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1560164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1561164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onCopySurface(GrSurface* dst, 1562164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1563164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1564164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 15654bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (can_copy_as_resolve(dst, src, this)) { 15664bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel this->copySurfaceAsResolve(dst, src, srcRect, dstPoint); 1567ec44099979acd3e83ad93a15dbd9301856a90572egdaniel return true; 15684bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 15694bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 1570fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { 1571fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); 1572fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel } 1573fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel 1574bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel if (fCopyManager.copySurfaceAsDraw(this, dst, src, srcRect, dstPoint)) { 1575bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel return true; 1576bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel } 1577bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel 157817b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* dstImage; 157917b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* srcImage; 15804bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrRenderTarget* dstRT = dst->asRenderTarget(); 15814bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (dstRT) { 15824bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT); 15834bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dstImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; 158417b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 15854bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(dst->asTexture()); 15864bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dstImage = static_cast<GrVkTexture*>(dst->asTexture()); 158717b892551465e5a44560a06e4b34dc3592b49622egdaniel } 15884bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrRenderTarget* srcRT = src->asRenderTarget(); 15894bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (srcRT) { 15904bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT); 15914bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; 159217b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 15934bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(src->asTexture()); 15944bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcImage = static_cast<GrVkTexture*>(src->asTexture()); 159517b892551465e5a44560a06e4b34dc3592b49622egdaniel } 159617b892551465e5a44560a06e4b34dc3592b49622egdaniel 1597164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (can_copy_image(dst, src, this)) { 159817b892551465e5a44560a06e4b34dc3592b49622egdaniel this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstPoint); 159917b892551465e5a44560a06e4b34dc3592b49622egdaniel return true; 160017b892551465e5a44560a06e4b34dc3592b49622egdaniel } 160117b892551465e5a44560a06e4b34dc3592b49622egdaniel 160217b892551465e5a44560a06e4b34dc3592b49622egdaniel if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) { 160317b892551465e5a44560a06e4b34dc3592b49622egdaniel this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint); 1604164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1605164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1606164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1607164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1608164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1609164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 16104bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielbool GrVkGpu::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const { 16114bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa). 16124bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a 16134bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // render target as well. 161437798fbd82a7d064c5cc1516f120546a3408044begdaniel desc->fOrigin = src->origin(); 161537798fbd82a7d064c5cc1516f120546a3408044begdaniel desc->fConfig = src->config(); 1616bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel if (src->numColorSamples() > 1 || 1617bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel (src->asTexture() && this->vkCaps().supportsCopiesAsDraws())) { 1618bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel desc->fFlags = kRenderTarget_GrSurfaceFlag; 1619bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel } else { 1620bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel // Just going to use CopyImage here 1621bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel desc->fFlags = kNone_GrSurfaceFlags; 1622bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel } 1623bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel 162437798fbd82a7d064c5cc1516f120546a3408044begdaniel return true; 162537798fbd82a7d064c5cc1516f120546a3408044begdaniel} 162637798fbd82a7d064c5cc1516f120546a3408044begdaniel 1627c25c5d73e9f4d840dc758c399496d5690709ad58csmartdaltonvoid GrVkGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&, 1628c25c5d73e9f4d840dc758c399496d5690709ad58csmartdalton int* effectiveSampleCnt, SamplePattern*) { 162928f45b949acc746849100fbe112ee5280f0594c9cdalton // TODO: stub. 163028f45b949acc746849100fbe112ee5280f0594c9cdalton SkASSERT(!this->caps()->sampleLocationsSupport()); 163128f45b949acc746849100fbe112ee5280f0594c9cdalton *effectiveSampleCnt = rt->desc().fSampleCnt; 163228f45b949acc746849100fbe112ee5280f0594c9cdalton} 163328f45b949acc746849100fbe112ee5280f0594c9cdalton 1634164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 1635164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig readConfig, DrawPreference* drawPreference, 1636164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ReadPixelTempDrawInfo* tempDrawInfo) { 163788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // These settings we will always want if a temp draw is performed. 163888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; 163988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fWidth = width; 164088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fHeight = height; 164188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 164288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 1643b117ff194ff888ef9107a4797aad053b0d76be30bsalomon tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox; 164488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel 164588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // For now assume no swizzling, we may change that below. 164688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); 164788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel 164888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read 164988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // from will be srcConfig and we will read readConfig pixels from it. 165088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // Not that if we require a draw and return a non-renderable format for the temp surface the 165188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // base class will fail for us. 165288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config(); 165388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fReadConfig = readConfig; 165488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel 16554583ec51d9ddc830eeb854db068235be96ce59c4egdaniel if (srcSurface->config() == readConfig) { 16564583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return true; 1657164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1658164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 165966933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (this->vkCaps().isConfigRenderable(readConfig, srcSurface->desc().fSampleCnt > 1)) { 16604583ec51d9ddc830eeb854db068235be96ce59c4egdaniel ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 16614583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; 16624583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fReadConfig = readConfig; 16634583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return true; 1664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 16664583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return false; 1667164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1668164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1669164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onReadPixels(GrSurface* surface, 1670164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 1671164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config, 1672164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* buffer, 1673164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 1674164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 1675164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 1676164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1677164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1678164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 167966933552f1723c4a2b248711ab3d43921401e8e6egdaniel GrVkImage* image = nullptr; 168066933552f1723c4a2b248711ab3d43921401e8e6egdaniel GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(surface->asRenderTarget()); 168166933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (rt) { 168266933552f1723c4a2b248711ab3d43921401e8e6egdaniel // resolve the render target if necessary 168366933552f1723c4a2b248711ab3d43921401e8e6egdaniel switch (rt->getResolveType()) { 168466933552f1723c4a2b248711ab3d43921401e8e6egdaniel case GrVkRenderTarget::kCantResolve_ResolveType: 168566933552f1723c4a2b248711ab3d43921401e8e6egdaniel return false; 168666933552f1723c4a2b248711ab3d43921401e8e6egdaniel case GrVkRenderTarget::kAutoResolves_ResolveType: 168766933552f1723c4a2b248711ab3d43921401e8e6egdaniel break; 168866933552f1723c4a2b248711ab3d43921401e8e6egdaniel case GrVkRenderTarget::kCanResolve_ResolveType: 168966933552f1723c4a2b248711ab3d43921401e8e6egdaniel this->onResolveRenderTarget(rt); 169066933552f1723c4a2b248711ab3d43921401e8e6egdaniel break; 169166933552f1723c4a2b248711ab3d43921401e8e6egdaniel default: 169266933552f1723c4a2b248711ab3d43921401e8e6egdaniel SkFAIL("Unknown resolve type"); 169366933552f1723c4a2b248711ab3d43921401e8e6egdaniel } 169466933552f1723c4a2b248711ab3d43921401e8e6egdaniel image = rt; 169566933552f1723c4a2b248711ab3d43921401e8e6egdaniel } else { 169666933552f1723c4a2b248711ab3d43921401e8e6egdaniel image = static_cast<GrVkTexture*>(surface->asTexture()); 169766933552f1723c4a2b248711ab3d43921401e8e6egdaniel } 169866933552f1723c4a2b248711ab3d43921401e8e6egdaniel 169966933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (!image) { 1700164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1701164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1702164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1703164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our target so it can be used as copy 170466933552f1723c4a2b248711ab3d43921401e8e6egdaniel image->setImageLayout(this, 170566933552f1723c4a2b248711ab3d43921401e8e6egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 170666933552f1723c4a2b248711ab3d43921401e8e6egdaniel VK_ACCESS_TRANSFER_READ_BIT, 170766933552f1723c4a2b248711ab3d43921401e8e6egdaniel VK_PIPELINE_STAGE_TRANSFER_BIT, 170866933552f1723c4a2b248711ab3d43921401e8e6egdaniel false); 1709164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 17106fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel size_t bpp = GrBytesPerPixel(config); 17116fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel size_t tightRowBytes = bpp * width; 1712164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 1713164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1714164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferImageCopy region; 1715164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 17166fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 17176fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel bool copyFromOrigin = this->vkCaps().mustDoCopiesFromOrigin(); 17186fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel if (copyFromOrigin) { 17196fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageOffset = { 0, 0, 0 }; 17206fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageExtent = { (uint32_t)(left + width), 17216fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel (uint32_t)(flipY ? surface->height() - top : top + height), 17226fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 1 17236fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel }; 17246fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel } else { 17256fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel VkOffset3D offset = { 17266fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel left, 17276fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel flipY ? surface->height() - top - height : top, 17286fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 0 17296fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel }; 17306fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageOffset = offset; 17316fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 17326fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel } 17336fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 17346fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel size_t transBufferRowBytes = bpp * region.imageExtent.width; 17356fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel GrVkTransferBuffer* transferBuffer = 17366fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel static_cast<GrVkTransferBuffer*>(this->createBuffer(transBufferRowBytes * height, 17376fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel kXferGpuToCpu_GrBufferType, 17386fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel kStream_GrAccessPattern)); 17396fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 17406fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel // Copy the image to a buffer so we can map it to cpu memory 1741db37909347d034943bd6b0922710a94c6c6ea572jvanverth region.bufferOffset = transferBuffer->offset(); 174288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel region.bufferRowLength = 0; // Forces RowLength to be width. We handle the rowBytes below. 1743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images. 1744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImageToBuffer(this, 174766933552f1723c4a2b248711ab3d43921401e8e6egdaniel image, 1748164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer, 1750164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1751164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ®ion); 1752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // make sure the copy to buffer has finished 1754164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->addMemoryBarrier(this, 1755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_TRANSFER_WRITE_BIT, 1756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_READ_BIT, 1757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 1758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 1759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We need to submit the current command buffer to the Queue and make sure it finishes before 1762164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // we can copy the data out of the buffer. 1763164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kForce_SyncQueue); 17649d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkMemory::InvalidateMappedAlloc(this, transferBuffer->alloc()); 1765164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mappedMemory = transferBuffer->map(); 1766164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 17676fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel if (copyFromOrigin) { 17686fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel uint32_t skipRows = region.imageExtent.height - height; 17696fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel mappedMemory = (char*)mappedMemory + transBufferRowBytes * skipRows + bpp * left; 17706fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel } 17716fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 1772164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (flipY) { 177388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel const char* srcRow = reinterpret_cast<const char*>(mappedMemory); 177488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes; 177588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel for (int y = 0; y < height; y++) { 177688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel memcpy(dstRow, srcRow, tightRowBytes); 17776fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel srcRow += transBufferRowBytes; 177888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel dstRow -= rowBytes; 177988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel } 178088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel } else { 17816fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel if (transBufferRowBytes == rowBytes) { 178288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel memcpy(buffer, mappedMemory, rowBytes*height); 178388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel } else { 17846fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, 17856fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel height); 1786164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1787164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 178988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel transferBuffer->unmap(); 179088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel transferBuffer->unref(); 1791164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1792164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1793066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 179427bb28473912181cf9a838e9282e86cb62e2d44begdaniel// The RenderArea bounds we pass into BeginRenderPass must have a start x value that is a multiple 179527bb28473912181cf9a838e9282e86cb62e2d44begdaniel// of the granularity. The width must also be a multiple of the granularity or eaqual to the width 179627bb28473912181cf9a838e9282e86cb62e2d44begdaniel// the the entire attachment. Similar requirements for the y and height components. 179727bb28473912181cf9a838e9282e86cb62e2d44begdanielvoid adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds, 179827bb28473912181cf9a838e9282e86cb62e2d44begdaniel const VkExtent2D& granularity, int maxWidth, int maxHeight) { 179927bb28473912181cf9a838e9282e86cb62e2d44begdaniel // Adjust Width 1800d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if ((0 != granularity.width && 1 != granularity.width)) { 1801d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel // Start with the right side of rect so we know if we end up going pass the maxWidth. 1802d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel int rightAdj = srcBounds.fRight % granularity.width; 1803d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (rightAdj != 0) { 1804d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel rightAdj = granularity.width - rightAdj; 1805d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 1806d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fRight = srcBounds.fRight + rightAdj; 1807d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (dstBounds->fRight > maxWidth) { 1808d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fRight = maxWidth; 1809d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fLeft = 0; 1810d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } else { 1811d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fLeft = srcBounds.fLeft - srcBounds.fLeft % granularity.width; 1812d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 181327bb28473912181cf9a838e9282e86cb62e2d44begdaniel } else { 1814d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fLeft = srcBounds.fLeft; 1815d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fRight = srcBounds.fRight; 181627bb28473912181cf9a838e9282e86cb62e2d44begdaniel } 181727bb28473912181cf9a838e9282e86cb62e2d44begdaniel 181827bb28473912181cf9a838e9282e86cb62e2d44begdaniel // Adjust height 1819d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if ((0 != granularity.height && 1 != granularity.height)) { 1820d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel // Start with the bottom side of rect so we know if we end up going pass the maxHeight. 1821d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel int bottomAdj = srcBounds.fBottom % granularity.height; 1822d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (bottomAdj != 0) { 1823d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel bottomAdj = granularity.height - bottomAdj; 1824d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 1825d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fBottom = srcBounds.fBottom + bottomAdj; 1826d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (dstBounds->fBottom > maxHeight) { 1827d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fBottom = maxHeight; 1828d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fTop = 0; 1829d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } else { 1830d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fTop = srcBounds.fTop - srcBounds.fTop % granularity.height; 1831d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 183227bb28473912181cf9a838e9282e86cb62e2d44begdaniel } else { 1833d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fTop = srcBounds.fTop; 1834d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fBottom = srcBounds.fBottom; 183527bb28473912181cf9a838e9282e86cb62e2d44begdaniel } 183627bb28473912181cf9a838e9282e86cb62e2d44begdaniel} 183727bb28473912181cf9a838e9282e86cb62e2d44begdaniel 18387ec92413307c9da43c013d1e4e15716a44059810jvanverthvoid GrVkGpu::submitSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer, 18399cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrVkRenderPass* renderPass, 18409cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const VkClearValue* colorClear, 18419cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkRenderTarget* target, 18429cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const SkIRect& bounds) { 1843e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel const SkIRect* pBounds = &bounds; 1844e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel SkIRect flippedBounds; 1845e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel if (kBottomLeft_GrSurfaceOrigin == target->origin()) { 1846e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel flippedBounds = bounds; 1847e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel flippedBounds.fTop = target->height() - bounds.fBottom; 1848e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel flippedBounds.fBottom = target->height() - bounds.fTop; 1849e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel pBounds = &flippedBounds; 1850e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel } 1851e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel 185227bb28473912181cf9a838e9282e86cb62e2d44begdaniel // The bounds we use for the render pass should be of the granularity supported 185327bb28473912181cf9a838e9282e86cb62e2d44begdaniel // by the device. 185427bb28473912181cf9a838e9282e86cb62e2d44begdaniel const VkExtent2D& granularity = renderPass->granularity(); 185527bb28473912181cf9a838e9282e86cb62e2d44begdaniel SkIRect adjustedBounds; 185627bb28473912181cf9a838e9282e86cb62e2d44begdaniel if ((0 != granularity.width && 1 != granularity.width) || 185727bb28473912181cf9a838e9282e86cb62e2d44begdaniel (0 != granularity.height && 1 != granularity.height)) { 185827bb28473912181cf9a838e9282e86cb62e2d44begdaniel adjust_bounds_to_granularity(&adjustedBounds, *pBounds, granularity, 185927bb28473912181cf9a838e9282e86cb62e2d44begdaniel target->width(), target->height()); 186027bb28473912181cf9a838e9282e86cb62e2d44begdaniel pBounds = &adjustedBounds; 186127bb28473912181cf9a838e9282e86cb62e2d44begdaniel } 186227bb28473912181cf9a838e9282e86cb62e2d44begdaniel 18639cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // Currently it is fine for us to always pass in 1 for the clear count even if no attachment 18649cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // uses it. In the current state, we also only use the LOAD_OP_CLEAR for the color attachment 18659cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel // which is always at the first attachment. 1866e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, 1, colorClear, *target, *pBounds, true); 1867066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel fCurrentCmdBuffer->executeCommands(this, buffer); 1868164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->endRenderPass(this); 186966933552f1723c4a2b248711ab3d43921401e8e6egdaniel 1870ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel this->didWriteToSurface(target, &bounds); 1871164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 18729cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 187384741b308496409f4ff662658167221fc6801bbejvanverthGrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() const { 187484741b308496409f4ff662658167221fc6801bbejvanverth VkFenceCreateInfo createInfo; 187584741b308496409f4ff662658167221fc6801bbejvanverth memset(&createInfo, 0, sizeof(VkFenceCreateInfo)); 187684741b308496409f4ff662658167221fc6801bbejvanverth createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 187784741b308496409f4ff662658167221fc6801bbejvanverth createInfo.pNext = nullptr; 187884741b308496409f4ff662658167221fc6801bbejvanverth createInfo.flags = 0; 187984741b308496409f4ff662658167221fc6801bbejvanverth VkFence fence = VK_NULL_HANDLE; 188084741b308496409f4ff662658167221fc6801bbejvanverth VkResult result = GR_VK_CALL(this->vkInterface(), CreateFence(this->device(), &createInfo, 188184741b308496409f4ff662658167221fc6801bbejvanverth nullptr, &fence)); 188284741b308496409f4ff662658167221fc6801bbejvanverth // TODO: verify that all QueueSubmits before this will finish before this fence signals 188384741b308496409f4ff662658167221fc6801bbejvanverth if (VK_SUCCESS == result) { 188484741b308496409f4ff662658167221fc6801bbejvanverth GR_VK_CALL(this->vkInterface(), QueueSubmit(this->queue(), 0, nullptr, fence)); 188584741b308496409f4ff662658167221fc6801bbejvanverth } 188684741b308496409f4ff662658167221fc6801bbejvanverth return (GrFence)fence; 188784741b308496409f4ff662658167221fc6801bbejvanverth} 188884741b308496409f4ff662658167221fc6801bbejvanverth 188984741b308496409f4ff662658167221fc6801bbejvanverthbool GrVkGpu::waitFence(GrFence fence, uint64_t timeout) const { 189084741b308496409f4ff662658167221fc6801bbejvanverth VkResult result = GR_VK_CALL(this->vkInterface(), WaitForFences(this->device(), 1, 189184741b308496409f4ff662658167221fc6801bbejvanverth (VkFence*)&fence, 189284741b308496409f4ff662658167221fc6801bbejvanverth VK_TRUE, 189384741b308496409f4ff662658167221fc6801bbejvanverth timeout)); 189484741b308496409f4ff662658167221fc6801bbejvanverth return (VK_SUCCESS == result); 189584741b308496409f4ff662658167221fc6801bbejvanverth} 189684741b308496409f4ff662658167221fc6801bbejvanverth 189784741b308496409f4ff662658167221fc6801bbejvanverthvoid GrVkGpu::deleteFence(GrFence fence) const { 189884741b308496409f4ff662658167221fc6801bbejvanverth GR_VK_CALL(this->vkInterface(), DestroyFence(this->device(), (VkFence)fence, nullptr)); 189984741b308496409f4ff662658167221fc6801bbejvanverth} 190084741b308496409f4ff662658167221fc6801bbejvanverth 1901