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