GrVkGpu.cpp revision 13dddce65fd87a8175a209a49f35615735a2886a
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 107ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel#include "GrBackendSurface.h" 11164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrContextOptions.h" 12164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGeometryProcessor.h" 13164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGpuResourceCacheAccess.h" 140e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel#include "GrMesh.h" 15164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrPipeline.h" 16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrRenderTargetPriv.h" 17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrSurfacePriv.h" 18164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrTexturePriv.h" 19164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 20164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkCommandBuffer.h" 21066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel#include "GrVkGpuCommandBuffer.h" 22164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkImage.h" 23164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkIndexBuffer.h" 24164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkMemory.h" 25164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkPipeline.h" 2622281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel#include "GrVkPipelineState.h" 27164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkRenderPass.h" 28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkResourceProvider.h" 296be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel#include "GrVkSemaphore.h" 30c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel#include "GrVkTexelBuffer.h" 31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h" 32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTextureRenderTarget.h" 33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTransferBuffer.h" 34164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkVertexBuffer.h" 35164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 36485c499a2797c1eb0e750fa4aaec57192799b424Matt Sarett#include "SkConvertPixels.h" 37900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth#include "SkMipMap.h" 38164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vk/GrVkInterface.h" 40fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth#include "vk/GrVkTypes.h" 41164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 42b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#include "SkSLCompiler.h" 43b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 4444f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling#if !defined(SK_BUILD_FOR_WIN) 4544f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling#include <unistd.h> 4644f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling#endif // !defined(SK_BUILD_FOR_WIN) 4744f85712f47f68645bb292df70f807f67aaf6d05Forrest Reiling 48164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X) 49164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) 50164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) 51164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 52735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS 53d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverthVKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( 54d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportFlagsEXT flags, 55d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportObjectTypeEXT objectType, 56d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth uint64_t object, 57d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth size_t location, 58d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth int32_t messageCode, 59d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth const char* pLayerPrefix, 60d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth const char* pMessage, 61d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth void* pUserData) { 62d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { 63d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 64ce3fe23c04e93d2aa8d4c09c0c99088207edd509Jim Van Verth return VK_TRUE; // skip further layers 65d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { 66d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 67d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { 68d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 69d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else { 70d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 71d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } 72d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth return VK_FALSE; 73d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth} 74d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 75d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth 76633b35657c964c32e7010b14bb2d396b4a764c52jvanverthGrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options, 77633b35657c964c32e7010b14bb2d396b4a764c52jvanverth GrContext* context) { 78dc0fcd41e75682a8bfd5e285d684461475226330bsalomon const GrVkBackendContext* vkBackendContext = 79dc0fcd41e75682a8bfd5e285d684461475226330bsalomon reinterpret_cast<const GrVkBackendContext*>(backendContext); 80633b35657c964c32e7010b14bb2d396b4a764c52jvanverth if (!vkBackendContext) { 81c1889823de68ffd2ef08b5c1969d41c98034ec6aBrian Salomon return nullptr; 82633b35657c964c32e7010b14bb2d396b4a764c52jvanverth } else { 83633b35657c964c32e7010b14bb2d396b4a764c52jvanverth vkBackendContext->ref(); 84164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 85164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 86fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel if (!vkBackendContext->fInterface->validate(vkBackendContext->fExtensions)) { 87fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel return nullptr; 88fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel } 89fe2965af79d70c7f3fe30204846e430c3db56a4eGreg Daniel 90633b35657c964c32e7010b14bb2d396b4a764c52jvanverth return new GrVkGpu(context, options, vkBackendContext); 91164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 92164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 93164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 94164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 959d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanaryGrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, 96633b35657c964c32e7010b14bb2d396b4a764c52jvanverth const GrVkBackendContext* backendCtx) 97164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : INHERITED(context) 98633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fDevice(backendCtx->fDevice) 99633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fQueue(backendCtx->fQueue) 1008606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel , fResourceProvider(this) 1018606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel , fDisconnected(false) { 102633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fBackendContext.reset(backendCtx); 103164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 104735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS 105419ca64f0f800dc098369b5aa5a604acd017b240brianosman fCallback = VK_NULL_HANDLE; 106fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth if (backendCtx->fExtensions & kEXT_debug_report_GrVkExtensionFlag) { 107fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth // Setup callback creation information 108d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; 109d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 110d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pNext = nullptr; 111d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | 112ef0c10cffefef90646ff2e238d7c2d82247a0370egdaniel VK_DEBUG_REPORT_WARNING_BIT_EXT | 113d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth //VK_DEBUG_REPORT_INFORMATION_BIT_EXT | 114d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth //VK_DEBUG_REPORT_DEBUG_BIT_EXT | 115b4aa36211ca66ef127ac2954108742af1ead5082egdaniel VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; 116d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pfnCallback = &DebugReportCallback; 117d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pUserData = nullptr; 118d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth 119fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth // Register the callback 120a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateDebugReportCallbackEXT( 121a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth backendCtx->fInstance, &callbackCreateInfo, nullptr, &fCallback)); 122d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } 123d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 124633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 125b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas fCompiler = new SkSL::Compiler(); 126633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 127fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice, 128c5ec1408298510410270ea67e895570ccfa76e54egdaniel backendCtx->fFeatures, backendCtx->fExtensions)); 129633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCaps.reset(SkRef(fVkCaps.get())); 130633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 131633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps)); 132633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 133633b35657c964c32e7010b14bb2d396b4a764c52jvanverth const VkCommandPoolCreateInfo cmdPoolInfo = { 1347ec92413307c9da43c013d1e4e15716a44059810jvanverth VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType 1357ec92413307c9da43c013d1e4e15716a44059810jvanverth nullptr, // pNext 1367ec92413307c9da43c013d1e4e15716a44059810jvanverth VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | 1377ec92413307c9da43c013d1e4e15716a44059810jvanverth VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // CmdPoolCreateFlags 1387ec92413307c9da43c013d1e4e15716a44059810jvanverth backendCtx->fGraphicsQueueIndex, // queueFamilyIndex 139633b35657c964c32e7010b14bb2d396b4a764c52jvanverth }; 1409d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateCommandPool(fDevice, &cmdPoolInfo, nullptr, 141633b35657c964c32e7010b14bb2d396b4a764c52jvanverth &fCmdPool)); 142633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 143633b35657c964c32e7010b14bb2d396b4a764c52jvanverth // must call this after creating the CommandPool 144633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fResourceProvider.init(); 1457ec92413307c9da43c013d1e4e15716a44059810jvanverth fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer(); 146633b35657c964c32e7010b14bb2d396b4a764c52jvanverth SkASSERT(fCurrentCmdBuffer); 147633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCurrentCmdBuffer->begin(this); 1486b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth 1496b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth // set up our heaps 1506b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kLinearImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024)); 1514f7d97c16fd159f72d2ad9c105542e2c6c097ad6Greg Daniel fHeaps[kOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 64*1024*1024)); 1526b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kSmallOptimalImage_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 2*1024*1024)); 1536b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kVertexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1546b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kIndexBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1554c6e47a8a827077e36fa5feb4ab5ac7435d8276bjvanverth fHeaps[kUniformBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 256*1024)); 156c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel fHeaps[kTexelBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1576b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kCopyReadBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSingleAlloc_Strategy, 0)); 1586b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth fHeaps[kCopyWriteBuffer_Heap].reset(new GrVkHeap(this, GrVkHeap::kSubAlloc_Strategy, 16*1024*1024)); 159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1618606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Danielvoid GrVkGpu::destroyResources() { 1628606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel if (fCurrentCmdBuffer) { 1638606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCurrentCmdBuffer->end(this); 1648606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCurrentCmdBuffer->unref(this); 1658606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } 166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // wait for all commands to finish 168ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth fResourceProvider.checkCommandBuffers(); 16909557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth VkResult res = VK_CALL(QueueWaitIdle(fQueue)); 170f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel 171f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // On windows, sometimes calls to QueueWaitIdle return before actually signalling the fences 172f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // on the command buffers even though they have completed. This causes an assert to fire when 173f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel // destroying the command buffers. Currently this ony seems to happen on windows, so we add a 17409557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth // sleep to make sure the fence signals. 175f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#ifdef SK_DEBUG 17680a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel if (this->vkCaps().mustSleepOnTearDown()) { 177f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#if defined(SK_BUILD_FOR_WIN) 17880a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel Sleep(10); // In milliseconds 179f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#else 18080a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel sleep(1); // In seconds 181f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif 18280a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel } 183f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel#endif 184f8c2be3fbccc4be0ccfce25327200e07fc99fd1fegdaniel 185be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#ifdef SK_DEBUG 1868a8668b4721097de657ad8b30d45f60f62433c6fGreg Daniel SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res); 187be9d82161d8347929a66ef942dabbe56abf592a4egdaniel#endif 1889d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 1896be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) { 1906be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel fSemaphoresToWaitOn[i]->unref(this); 1916be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel } 1926be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel fSemaphoresToWaitOn.reset(); 1936be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 194bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel fCopyManager.destroyResources(this); 195bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel 19609557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth // must call this just before we destroy the command pool and VkDevice 19709557d7c0409ca1194d06d9dd9664fb5530c3f46Jim Van Verth fResourceProvider.destroyResources(VK_ERROR_DEVICE_LOST == res); 198164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1998606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel if (fCmdPool != VK_NULL_HANDLE) { 2008606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); 2018606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } 202633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 203735109c24892a95290974c9665527b57b01e5440egdaniel#ifdef SK_ENABLE_VK_LAYERS 204a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth if (fCallback) { 205a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth VK_CALL(DestroyDebugReportCallbackEXT(fBackendContext->fInstance, fCallback, nullptr)); 206a00980e58037fa36d066be80d7fcc0f73b2dfd40jvanverth } 207d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 2088606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel 2098606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel} 2108606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel 2118606cf836e2cdbabe7fd917b7cba88b6673c9175Greg DanielGrVkGpu::~GrVkGpu() { 2128606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel if (!fDisconnected) { 2138606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel this->destroyResources(); 2148606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } 2158606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel delete fCompiler; 2168606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel} 2178606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel 2188606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel 2198606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Danielvoid GrVkGpu::disconnect(DisconnectType type) { 2208606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel INHERITED::disconnect(type); 2218606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel if (!fDisconnected) { 2228606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel if (DisconnectType::kCleanup == type) { 2238606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel this->destroyResources(); 2248606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } else { 2258606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCurrentCmdBuffer->unrefAndAbandon(); 2268606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) { 2278606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fSemaphoresToWaitOn[i]->unrefAndAbandon(); 2288606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } 2298606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCopyManager.abandonResources(); 2308606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel 2318606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel // must call this just before we destroy the command pool and VkDevice 2328606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fResourceProvider.abandonResources(); 2338606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } 2348606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fSemaphoresToWaitOn.reset(); 2358606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel#ifdef SK_ENABLE_VK_LAYERS 2368606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCallback = VK_NULL_HANDLE; 2378606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel#endif 2388606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCurrentCmdBuffer = nullptr; 2398606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fCmdPool = VK_NULL_HANDLE; 2408606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel fDisconnected = true; 2418606cf836e2cdbabe7fd917b7cba88b6673c9175Greg Daniel } 242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 2469cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielGrGpuCommandBuffer* GrVkGpu::createCommandBuffer( 2479cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo, 2489cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) { 249c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon return new GrVkGpuCommandBuffer(this, colorInfo, stencilInfo); 250066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel} 251066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 2526be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrVkGpu::submitCommandBuffer(SyncQueue sync, 2536be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel const GrVkSemaphore::Resource* signalSemaphore) { 254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 2576be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel fCurrentCmdBuffer->submitToQueue(this, fQueue, sync, signalSemaphore, fSemaphoresToWaitOn); 2586be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 2596be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) { 2606be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel fSemaphoresToWaitOn[i]->unref(this); 2616be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel } 2626be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel fSemaphoresToWaitOn.reset(); 2636be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fResourceProvider.checkCommandBuffers(); 265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Release old command buffer and create a new one 267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 2687ec92413307c9da43c013d1e4e15716a44059810jvanverth fCurrentCmdBuffer = fResourceProvider.findOrCreatePrimaryCommandBuffer(); 269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->begin(this); 272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 2751bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdaltonGrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern accessPattern, 2761bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton const void* data) { 2771bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton GrBuffer* buff; 278397536cabe12a9936659870dd220c869789424bacdalton switch (type) { 279397536cabe12a9936659870dd220c869789424bacdalton case kVertex_GrBufferType: 280397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kDynamic_GrAccessPattern == accessPattern || 281397536cabe12a9936659870dd220c869789424bacdalton kStatic_GrAccessPattern == accessPattern); 2821bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); 283e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 284397536cabe12a9936659870dd220c869789424bacdalton case kIndex_GrBufferType: 285397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kDynamic_GrAccessPattern == accessPattern || 286397536cabe12a9936659870dd220c869789424bacdalton kStatic_GrAccessPattern == accessPattern); 2871bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); 288e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 289397536cabe12a9936659870dd220c869789424bacdalton case kXferCpuToGpu_GrBufferType: 290c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth SkASSERT(kStream_GrAccessPattern == accessPattern); 2911bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type); 292e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 293397536cabe12a9936659870dd220c869789424bacdalton case kXferGpuToCpu_GrBufferType: 294c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth SkASSERT(kStream_GrAccessPattern == accessPattern); 2951bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type); 296e05bbbba79c569c1d32fa6475feecd1477fd3beeegdaniel break; 297c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel case kTexel_GrBufferType: 298c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel SkASSERT(kDynamic_GrAccessPattern == accessPattern); 299c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel buff = GrVkTexelBuffer::Create(this, size); 300c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel break; 301c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel case kDrawIndirect_GrBufferType: 302c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel SkFAIL("DrawIndirect Buffers not supported in vulkan backend."); 303c2dd5ed93753dc54619fb713ebcf38bd1af08592Greg Daniel return nullptr; 304397536cabe12a9936659870dd220c869789424bacdalton default: 305397536cabe12a9936659870dd220c869789424bacdalton SkFAIL("Unknown buffer type."); 306397536cabe12a9936659870dd220c869789424bacdalton return nullptr; 307397536cabe12a9936659870dd220c869789424bacdalton } 3081bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton if (data && buff) { 3091bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton buff->updateData(data, size); 3101bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton } 3111bf3e71ad06a318613ccc09e1cf47d3c2465b23ccdalton return buff; 312164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 313164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 314164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 315164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 316164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig srcConfig, DrawPreference* drawPreference, 317164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel WritePixelTempDrawInfo* tempDrawInfo) { 318d0be1ef36c64c2a420cbd82f4c033704d4c54a07Brian Osman if (GrPixelConfigIsCompressed(dstSurface->config())) { 319164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 320164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 321164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 3224583ec51d9ddc830eeb854db068235be96ce59c4egdaniel GrRenderTarget* renderTarget = dstSurface->asRenderTarget(); 3234583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 3244583ec51d9ddc830eeb854db068235be96ce59c4egdaniel // Start off assuming no swizzling 3254583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); 3264583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fWriteConfig = srcConfig; 3274583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 3284583ec51d9ddc830eeb854db068235be96ce59c4egdaniel // These settings we will always want if a temp draw is performed. Initially set the config 3294583ec51d9ddc830eeb854db068235be96ce59c4egdaniel // to srcConfig, though that may be modified if we decide to do a R/B swap 3304583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags; 3314583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 3324583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fWidth = width; 3334583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fHeight = height; 3344583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 3354583ec51d9ddc830eeb854db068235be96ce59c4egdaniel tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; 3364583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 337d66110f5972169dbcda8932c3a9a001adff23df4egdaniel if (dstSurface->config() == srcConfig) { 33833910297e032b9af4336bc146c7fbb0f35918de9Brian Osman // We only support writing pixels to textures. Forcing a draw lets us write to pure RTs. 33933910297e032b9af4336bc146c7fbb0f35918de9Brian Osman if (!dstSurface->asTexture()) { 34033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 34133910297e032b9af4336bc146c7fbb0f35918de9Brian Osman } 34233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target. 34333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman if (renderTarget && renderTarget->numColorSamples() > 1) { 34433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 34533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman } 346d66110f5972169dbcda8932c3a9a001adff23df4egdaniel return true; 347d66110f5972169dbcda8932c3a9a001adff23df4egdaniel } 348d66110f5972169dbcda8932c3a9a001adff23df4egdaniel 34933910297e032b9af4336bc146c7fbb0f35918de9Brian Osman // Any config change requires a draw 35033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 3514583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 35233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config(); 3534583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 35433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman if (!this->vkCaps().isConfigTexturable(srcConfig) && configsAreRBSwaps) { 35533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); 35633910297e032b9af4336bc146c7fbb0f35918de9Brian Osman tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 35733910297e032b9af4336bc146c7fbb0f35918de9Brian Osman tempDrawInfo->fWriteConfig = dstSurface->config(); 358164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 35933910297e032b9af4336bc146c7fbb0f35918de9Brian Osman return true; 360164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 361164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onWritePixels(GrSurface* surface, 363164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 364a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon GrPixelConfig config, 365a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon const SkTArray<GrMipLevel>& texels) { 366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture()); 367164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!vkTex) { 368164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 369164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 371900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Make sure we have at least the base level 37203509eafa3e25819ff69f4d4f339d46264820c38jvanverth if (texels.empty() || !texels.begin()->fPixels) { 37303509eafa3e25819ff69f4d4f339d46264820c38jvanverth return false; 37403509eafa3e25819ff69f4d4f339d46264820c38jvanverth } 375a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon 376164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels. 377164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 378164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 379164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool success = false; 382164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) { 383164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo() 384164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(config == vkTex->desc().fConfig); 385164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: add compressed texture support 386164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // delete the following two lines and uncomment the two after that when ready 387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->unref(); 388164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false, left, top, width, 390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // height); 391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = vkTex->isLinearTiled(); 393900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (linearTiling) { 394900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (texels.count() > 1) { 395900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkDebugf("Can't upload mipmap data to linear tiled texture"); 396900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 397900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 398900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (VK_IMAGE_LAYOUT_PREINITIALIZED != vkTex->currentLayout()) { 399900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Need to change the layout to general in order to perform a host write 400900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth vkTex->setImageLayout(this, 401900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_GENERAL, 40250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_HOST_WRITE_BIT, 40350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_HOST_BIT, 404900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth false); 405bdf8811b3126ab08ccff08b5e647b80cae5bd087egdaniel this->submitCommandBuffer(kForce_SyncQueue); 406900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 407900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataLinear(vkTex, left, top, width, height, config, 408900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth texels.begin()->fPixels, texels.begin()->fRowBytes); 409900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else { 410c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int newMipLevels = texels.count(); 41182c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth int currentMipLevels = vkTex->texturePriv().maxMipMapLevel() + 1; 412dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel if (newMipLevels > currentMipLevels) { 413c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth if (!vkTex->reallocForMipmap(this, newMipLevels)) { 414900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 415900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 416900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 417900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataOptimal(vkTex, left, top, width, height, config, texels); 418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 419164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 4204583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 421900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return success; 422164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 423164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 424bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Danielvoid GrVkGpu::resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect, 4254bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIPoint& dstPoint) { 4264bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(dst); 4274bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage()); 4284bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 429fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { 430fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); 431fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel } 432fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel 4334bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // Flip rect if necessary 4344bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkIRect srcVkRect = srcRect; 4354bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel int32_t dstY = dstPoint.fY; 4364bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4374bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 4384bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); 4394bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcVkRect.fTop = src->height() - srcRect.fBottom; 4404bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcVkRect.fBottom = src->height() - srcRect.fTop; 4414bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dstY = dst->height() - dstPoint.fY - srcVkRect.height(); 4424bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 4434bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4444bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VkImageResolve resolveInfo; 4454bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 4464bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 4474bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 4484bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.dstOffset = { dstPoint.fX, dstY, 0 }; 4494bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 }; 4504bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 451bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel GrVkImage* dstImage; 452bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel GrRenderTarget* dstRT = dst->asRenderTarget(); 453bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel if (dstRT) { 454bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT); 455bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel dstImage = vkRT; 456bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel } else { 457bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel SkASSERT(dst->asTexture()); 458bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel dstImage = static_cast<GrVkTexture*>(dst->asTexture()); 459bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel } 460bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel dstImage->setImageLayout(this, 461bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 462bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel VK_ACCESS_TRANSFER_WRITE_BIT, 463bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 464bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel false); 4654bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 4664bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel src->msaaImage()->setImageLayout(this, 4674bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4684bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_ACCESS_TRANSFER_READ_BIT, 4694bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel VK_PIPELINE_STAGE_TRANSFER_BIT, 4704bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel false); 4714bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 472bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel fCurrentCmdBuffer->resolveImage(this, *src->msaaImage(), *dstImage, 1, &resolveInfo); 4734bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel} 4744bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 47569d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Danielvoid GrVkGpu::internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit) { 47666933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (target->needsResolve()) { 47766933552f1723c4a2b248711ab3d43921401e8e6egdaniel SkASSERT(target->numColorSamples() > 1); 47852ad25151a1c7d1ac3872971f56adf15200c437eegdaniel GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); 47952ad25151a1c7d1ac3872971f56adf15200c437eegdaniel SkASSERT(rt->msaaImage()); 48069d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel 4814bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIRect& srcRect = rt->getResolveRect(); 48252ad25151a1c7d1ac3872971f56adf15200c437eegdaniel 483bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel this->resolveImage(target, rt, srcRect, SkIPoint::Make(srcRect.fLeft, srcRect.fTop)); 48452ad25151a1c7d1ac3872971f56adf15200c437eegdaniel 48552ad25151a1c7d1ac3872971f56adf15200c437eegdaniel rt->flagAsResolved(); 48669d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel 48769d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel if (requiresSubmit) { 48869d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 48969d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel } 49052ad25151a1c7d1ac3872971f56adf15200c437eegdaniel } 49152ad25151a1c7d1ac3872971f56adf15200c437eegdaniel} 49252ad25151a1c7d1ac3872971f56adf15200c437eegdaniel 493900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex, 494900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth int left, int top, int width, int height, 495900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GrPixelConfig dataConfig, 496900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const void* data, 497900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth size_t rowBytes) { 498164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(data); 499900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(tex->isLinearTiled()); 500164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 501164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If we're uploading compressed data then we should be using uploadCompressedTexData 502164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 503164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 504164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t bpp = GrBytesPerPixel(dataConfig); 505164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 506164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurfaceDesc& desc = tex->desc(); 507164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 508164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 509164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &width, &height, &data, &rowBytes)) { 510164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 511164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 512164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t trimRowBytes = width * bpp; 513164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 514900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == tex->currentLayout() || 515900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_GENERAL == tex->currentLayout()); 516900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const VkImageSubresource subres = { 517900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_ASPECT_COLOR_BIT, 518900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 0, // mipLevel 519900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 0, // arraySlice 520900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth }; 521900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkSubresourceLayout layout; 522900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkResult err; 523900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 524900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const GrVkInterface* interface = this->vkInterface(); 525900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 526900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice, 527b2df0c2702329be6380a943d548e7377a51d8565egdaniel tex->image(), 528900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth &subres, 529900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth &layout)); 530900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 531900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth int texTop = kBottomLeft_GrSurfaceOrigin == desc.fOrigin ? tex->height() - top - height : top; 5321e305ba0d6a4237020d36234e9e286d3b0489401jvanverth const GrVkAlloc& alloc = tex->alloc(); 5331e305ba0d6a4237020d36234e9e286d3b0489401jvanverth VkDeviceSize offset = alloc.fOffset + texTop*layout.rowPitch + left*bpp; 534900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkDeviceSize size = height*layout.rowPitch; 535900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth void* mapPtr; 5361e305ba0d6a4237020d36234e9e286d3b0489401jvanverth err = GR_VK_CALL(interface, MapMemory(fDevice, alloc.fMemory, offset, size, 0, &mapPtr)); 537900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (err) { 538900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 539900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 540164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 541900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 542900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // copy into buffer by rows 543900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const char* srcRow = reinterpret_cast<const char*>(data); 544900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*layout.rowPitch; 545900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth for (int y = 0; y < height; y++) { 546900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth memcpy(dstRow, srcRow, trimRowBytes); 547900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth srcRow += rowBytes; 548900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth dstRow -= layout.rowPitch; 549900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 550900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else { 551cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, trimRowBytes, 552cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett height); 553900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 554164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 5559d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkMemory::FlushMappedAlloc(this, alloc); 5561e305ba0d6a4237020d36234e9e286d3b0489401jvanverth GR_VK_CALL(interface, UnmapMemory(fDevice, alloc.fMemory)); 557900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 558900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return true; 559900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth} 560900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 561900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverthbool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, 562a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth int left, int top, int width, int height, 563a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth GrPixelConfig dataConfig, 564a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth const SkTArray<GrMipLevel>& texels) { 565900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(!tex->isLinearTiled()); 566900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // The assumption is either that we have no mipmaps, or that our rect is the entire texture 567900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(1 == texels.count() || 568900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth (0 == left && 0 == top && width == tex->width() && height == tex->height())); 569900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 570dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel // We assume that if the texture has mip levels, we either upload to all the levels or just the 571dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel // first. 572dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel SkASSERT(1 == texels.count() || texels.count() == (tex->texturePriv().maxMipMapLevel() + 1)); 573dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel 574900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // If we're uploading compressed data then we should be using uploadCompressedTexData 575900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 576900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 577900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (width == 0 || height == 0) { 578900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return false; 579900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 580900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 581900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const GrSurfaceDesc& desc = tex->desc(); 582900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 583900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth size_t bpp = GrBytesPerPixel(dataConfig); 584900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 585900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // texels is const. 586c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // But we may need to adjust the fPixels ptr based on the copyRect, or fRowBytes. 587c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // Because of this we need to make a non-const shallow copy of texels. 588c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkTArray<GrMipLevel> texelsShallowCopy(texels); 589900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 590c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0; 591c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentMipLevel--) { 592c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkASSERT(texelsShallowCopy[currentMipLevel].fPixels); 593900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 594900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 595900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Determine whether we need to flip when we copy into the buffer 596c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty()); 597900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 598c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // adjust any params (left, top, currentWidth, currentHeight 599900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // find the combined size of all the mip levels and the relative offset of 600900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // each into the collective buffer 601c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // Do the first level separately because we may need to adjust width and height 602c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth // (for the non-mipped case). 603c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 604c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &width, 605c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &height, 606c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[0].fPixels, 607c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[0].fRowBytes)) { 608c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth return false; 609c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth } 610c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkTArray<size_t> individualMipOffsets(texelsShallowCopy.count()); 611c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth individualMipOffsets.push_back(0); 612c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth size_t combinedBufferSize = width * bpp * height; 613c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int currentWidth = width; 614c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int currentHeight = height; 615468fd63760283c56630d752583b234f44ab03024Greg Daniel // The alignment must be at least 4 bytes and a multiple of the bytes per pixel of the image 616468fd63760283c56630d752583b234f44ab03024Greg Daniel // config. This works with the assumption that the bytes in pixel config is always a power of 2. 617468fd63760283c56630d752583b234f44ab03024Greg Daniel SkASSERT((bpp & (bpp - 1)) == 0); 618468fd63760283c56630d752583b234f44ab03024Greg Daniel const size_t alignmentMask = 0x3 | (bpp - 1); 619c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth for (int currentMipLevel = 1; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 620c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentWidth = SkTMax(1, currentWidth/2); 621c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentHeight = SkTMax(1, currentHeight/2); 622c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 623c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth ¤tWidth, 624c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth ¤tHeight, 625c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[currentMipLevel].fPixels, 626c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth &texelsShallowCopy[currentMipLevel].fRowBytes)) { 627c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth return false; 628c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth } 629900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const size_t trimmedSize = currentWidth * bpp * currentHeight; 630468fd63760283c56630d752583b234f44ab03024Greg Daniel const size_t alignmentDiff = combinedBufferSize & alignmentMask; 631468fd63760283c56630d752583b234f44ab03024Greg Daniel if (alignmentDiff != 0) { 632468fd63760283c56630d752583b234f44ab03024Greg Daniel combinedBufferSize += alignmentMask - alignmentDiff + 1; 633468fd63760283c56630d752583b234f44ab03024Greg Daniel } 634900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth individualMipOffsets.push_back(combinedBufferSize); 635900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth combinedBufferSize += trimmedSize; 636900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 637900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 638900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // allocate buffer to hold our mip data 639900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GrVkTransferBuffer* transferBuffer = 640900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuffer::kCopyRead_Type); 641c04f8450d4701ea2b4494c3cd12f5f972d6d5b54Forrest Reiling if(!transferBuffer) 642c04f8450d4701ea2b4494c3cd12f5f972d6d5b54Forrest Reiling return false; 643900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 644900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth char* buffer = (char*) transferBuffer->map(); 645c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth SkTArray<VkBufferImageCopy> regions(texelsShallowCopy.count()); 646900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 647c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentWidth = width; 648c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentHeight = height; 649a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel int layerHeight = tex->height(); 650c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { 651a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel SkASSERT(1 == texelsShallowCopy.count() || currentHeight == layerHeight); 652900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth const size_t trimRowBytes = currentWidth * bpp; 653c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes; 654900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 655900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // copy data into the buffer, skipping the trailing bytes 656900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth char* dst = buffer + individualMipOffsets[currentMipLevel]; 657c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels; 658900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (flipY) { 659900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth src += (currentHeight - 1) * rowBytes; 660900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth for (int y = 0; y < currentHeight; y++) { 661900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth memcpy(dst, src, trimRowBytes); 662900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth src -= rowBytes; 663900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth dst += trimRowBytes; 664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 666900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, currentHeight); 667164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 668164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 669900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VkBufferImageCopy& region = regions.push_back(); 670164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 671db37909347d034943bd6b0922710a94c6c6ea572jvanverth region.bufferOffset = transferBuffer->offset() + individualMipOffsets[currentMipLevel]; 672900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth region.bufferRowLength = currentWidth; 673900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth region.bufferImageHeight = currentHeight; 674cf942c4ef750712b624867cbb2217c14857db3c6bsalomon region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMipLevel), 0, 1 }; 675a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel region.imageOffset = { left, flipY ? layerHeight - top - currentHeight : top, 0 }; 676900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 }; 6774583ec51d9ddc830eeb854db068235be96ce59c4egdaniel 678c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentWidth = SkTMax(1, currentWidth/2); 679c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth currentHeight = SkTMax(1, currentHeight/2); 680a1b282be3f93a6713e1bf7e1d0fc0caef5940a40Greg Daniel layerHeight = currentHeight; 681900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 682164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 6839d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth // no need to flush non-coherent memory, unmap will do that for us 684900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth transferBuffer->unmap(); 685164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 686900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Change layout of our target so it can be copied to 687900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth tex->setImageLayout(this, 688900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 68950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 69050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 691900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth false); 692900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 693900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // Copy the buffer to the image 694900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth fCurrentCmdBuffer->copyBufferToImage(this, 695900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth transferBuffer, 696900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth tex, 697900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 698900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth regions.count(), 699900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth regions.begin()); 700900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth transferBuffer->unref(); 701dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel if (1 == texelsShallowCopy.count()) { 702dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel tex->texturePriv().dirtyMipMaps(true); 703dd20e918bb3c92a7643a8cbd6760ac66c2694017Greg Daniel } 704164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 705164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 706164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 707164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 708164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 7092e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunenGrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 710a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon const SkTArray<GrMipLevel>& texels) { 711164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 712164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 713164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 714164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) { 715164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 716164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 717164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 718164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(desc.fConfig)) { 719164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 720164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 721164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 7220a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel if (renderTarget && !fVkCaps->isConfigRenderable(desc.fConfig, false)) { 7230a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel return nullptr; 7240a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel } 7250a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel 726164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 727164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (SkToBool(desc.fFlags & kZeroCopy_GrSurfaceFlag)) { 728900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // we can't have a linear texture with a mipmap 729900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (texels.count() > 1) { 730900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkDebugf("Trying to create linear tiled texture with mipmap"); 731900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth return nullptr; 732900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 733a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel if (fVkCaps->isConfigTexturableLinearly(desc.fConfig) && 734164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel (!renderTarget || fVkCaps->isConfigRenderableLinearly(desc.fConfig, false))) { 735164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 736164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 737164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 738164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 739164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 740164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 741164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 742164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and 747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we 748164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // will be using this texture in some copy or not. Also this assumes, as is the current case, 74962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // that all render targets in vulkan are also textures. If we change this practice of setting 750164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // both bits, we must make sure to set the destination bit if we are uploading srcData to the 751164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // texture. 752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 754a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : 755a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is 75862340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // requested, this ImageDesc describes the resolved texture. Therefore we always have samples set 759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // to 1. 760c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth int mipLevels = texels.empty() ? 1 : texels.count(); 761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::ImageDesc imageDesc; 762164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageType = VK_IMAGE_TYPE_2D; 763164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fFormat = pixelFormat; 764164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fWidth = desc.fWidth; 765164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fHeight = desc.fHeight; 766c578b06319f271ac46ac78e3b86f74fbceed360ejvanverth imageDesc.fLevels = linearTiling ? 1 : mipLevels; 767164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fSamples = 1; 768164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 769164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fUsageFlags = usageFlags; 770164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fMemProps = memProps; 771164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 772164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* tex; 773164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 7742e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, desc, 775164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc); 776164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 7772e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc); 778164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 779164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 780164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!tex) { 781164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 782164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 783164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 784e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (!texels.empty()) { 785e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon SkASSERT(texels.begin()->fPixels); 786900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth bool success; 787900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (linearTiling) { 788900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataLinear(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 789900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth texels.begin()->fPixels, texels.begin()->fRowBytes); 790900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } else { 791900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth success = this->uploadTexDataOptimal(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 792900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth texels); 793900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth } 794900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth if (!success) { 795164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->unref(); 796164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 797164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 798164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 799164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tex; 801164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 802164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 803164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 804164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 805db37909347d034943bd6b0922710a94c6c6ea572jvanverthbool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src, 806db37909347d034943bd6b0922710a94c6c6ea572jvanverth VkDeviceSize offset, VkDeviceSize size) { 807a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 808a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth // Update the buffer 809db37909347d034943bd6b0922710a94c6c6ea572jvanverth fCurrentCmdBuffer->updateBuffer(this, buffer, offset, size, src); 810a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 811a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth return true; 812a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth} 813a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 814a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth//////////////////////////////////////////////////////////////////////////////// 815a584de966a4f7ab71f3f07077cf1e226def9d730jvanverth 816164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) { 817164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // By default, all textures in Vk use TopLeft 818164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kDefault_GrSurfaceOrigin == origin) { 819164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return kTopLeft_GrSurfaceOrigin; 820164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 821164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return origin; 822164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 823164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 824164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8257ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Danielsk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTex, 8267ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrSurfaceOrigin origin, 8277ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendTextureFlags flags, 8287ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel int sampleCnt, 8296bd5284415bd983b0628c4941dff5def40018f5abungeman GrWrapOwnership ownership) { 8307ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel const GrVkImageInfo* info = backendTex.getVkImageInfo(); 8317ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel if (!info) { 832164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 833164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 834164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 835164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int maxSize = this->caps()->maxTextureSize(); 8367ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel if (backendTex.width() > maxSize || backendTex.height() > maxSize) { 837164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 838164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 839164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8401e305ba0d6a4237020d36234e9e286d3b0489401jvanverth if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc.fMemory) { 841fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return nullptr; 842fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 8437ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 8447ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel SkASSERT(backendTex.config() == GrVkFormatToPixelConfig(info->fFormat)); 845164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 846164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc surfDesc; 8477ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel // next line relies on GrBackendTextureFlags matching GrTexture's 8487ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel surfDesc.fFlags = (GrSurfaceFlags)flags; 8497ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel surfDesc.fWidth = backendTex.width(); 8507ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel surfDesc.fHeight = backendTex.height(); 8517ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel surfDesc.fConfig = backendTex.config(); 8527ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel surfDesc.fSampleCnt = SkTMin(sampleCnt, this->caps()->maxSampleCount()); 8537ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel bool renderTarget = SkToBool(flags & kRenderTarget_GrBackendTextureFlag); 854766fcbb01cece88ad88808581b4ecc5a5cb60e01Brian Osman SkASSERT(!renderTarget || kAdoptAndCache_GrWrapOwnership != ownership); // Not supported 855164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In GL, Chrome assumes all textures are BottomLeft 856164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In VK, we don't have this restriction 8577ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel surfDesc.fOrigin = resolve_origin(origin); 858164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8596bd5284415bd983b0628c4941dff5def40018f5abungeman if (!renderTarget) { 8606bd5284415bd983b0628c4941dff5def40018f5abungeman return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, info); 861164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 8626bd5284415bd983b0628c4941dff5def40018f5abungeman return GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, ownership, info); 863164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 864164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 865bcf612b5d0032f09d58c2ea5671de977130395dbGreg Danielsk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT, 866bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel GrSurfaceOrigin origin){ 867e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel // Currently the Vulkan backend does not support wrapping of msaa render targets directly. In 868e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel // general this is not an issue since swapchain images in vulkan are never multisampled. Thus if 869e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel // you want a multisampled RT it is best to wrap the swapchain images and then let Skia handle 870e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel // creating and owning the MSAA images. 871bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel if (backendRT.sampleCnt()) { 872e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel return nullptr; 873e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel } 8749d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 875bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel const GrVkImageInfo* info = backendRT.getVkImageInfo(); 876bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel if (!info) { 877bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel return nullptr; 878bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel } 8790b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman if (VK_NULL_HANDLE == info->fImage) { 880fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return nullptr; 881fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 882164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 883164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc desc; 884bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel desc.fConfig = backendRT.config(); 8853667b4970d6972675be58a331be7c5ba02f3d39eRobert Phillips desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; 886bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel desc.fWidth = backendRT.width(); 887bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel desc.fHeight = backendRT.height(); 888e79b473714866682dea85b66c005c5bb2ff6a397Greg Daniel desc.fSampleCnt = 0; 889164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 890bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel SkASSERT(kDefault_GrSurfaceOrigin != origin); 891bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel desc.fOrigin = origin; 892164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8930b791f57c4a158fa3cab7250f0955b7f8abd5755Brian Osman sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info); 894bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel if (tgt && backendRT.stencilBits()) { 8956bd5284415bd983b0628c4941dff5def40018f5abungeman if (!createStencilAttachmentForRenderTarget(tgt.get(), desc.fWidth, desc.fHeight)) { 896164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 897164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 898164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 899164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tgt; 900164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 901164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 9027ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Danielsk_sp<GrRenderTarget> GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex, 9037ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrSurfaceOrigin origin, 9047ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel int sampleCnt) { 90533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman 9067ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel const GrVkImageInfo* info = tex.getVkImageInfo(); 907bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel if (!info) { 908bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel return nullptr; 909bcf612b5d0032f09d58c2ea5671de977130395dbGreg Daniel } 91033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman if (VK_NULL_HANDLE == info->fImage) { 91133910297e032b9af4336bc146c7fbb0f35918de9Brian Osman return nullptr; 91233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman } 91333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman 91433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman GrSurfaceDesc desc; 9157ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel desc.fFlags = kRenderTarget_GrSurfaceFlag; 9167ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel desc.fConfig = tex.config(); 9177ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel desc.fWidth = tex.width(); 9187ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel desc.fHeight = tex.height(); 9197ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel desc.fSampleCnt = SkTMin(sampleCnt, this->caps()->maxSampleCount()); 92033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman 9217ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel desc.fOrigin = resolve_origin(origin); 92233910297e032b9af4336bc146c7fbb0f35918de9Brian Osman 92333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman sk_sp<GrVkRenderTarget> tgt = GrVkRenderTarget::MakeWrappedRenderTarget(this, desc, info); 92433910297e032b9af4336bc146c7fbb0f35918de9Brian Osman return tgt; 92533910297e032b9af4336bc146c7fbb0f35918de9Brian Osman} 92633910297e032b9af4336bc146c7fbb0f35918de9Brian Osman 92750ead53ac97deb23310916e3736c3f5e2d8f7f4begdanielvoid GrVkGpu::generateMipmap(GrVkTexture* tex) { 928900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth // don't do anything for linearly tiled textures (can't have mipmaps) 92962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth if (tex->isLinearTiled()) { 930900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkDebugf("Trying to create mipmap for linear tiled texture"); 93162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth return; 93262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth } 93362340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 93462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // determine if we can blit to and from this format 93562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth const GrVkCaps& caps = this->vkCaps(); 93662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth if (!caps.configCanBeDstofBlit(tex->config(), false) || 9372f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel !caps.configCanBeSrcofBlit(tex->config(), false) || 9382f5792a06c87efd5f9295b7b7bb714aac118bd2aegdaniel !caps.mipMapSupport()) { 93962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth return; 94062340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth } 94162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 942fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { 943fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel this->submitCommandBuffer(kSkip_SyncQueue); 944fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel } 945fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel 94666933552f1723c4a2b248711ab3d43921401e8e6egdaniel // We may need to resolve the texture first if it is also a render target 94766933552f1723c4a2b248711ab3d43921401e8e6egdaniel GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(tex->asRenderTarget()); 94866933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (texRT) { 94969d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel this->internalResolveRenderTarget(texRT, false); 95066933552f1723c4a2b248711ab3d43921401e8e6egdaniel } 95166933552f1723c4a2b248711ab3d43921401e8e6egdaniel 9527ac5da853457b032781cf865ba018de78508edb7egdaniel int width = tex->width(); 9537ac5da853457b032781cf865ba018de78508edb7egdaniel int height = tex->height(); 9547ac5da853457b032781cf865ba018de78508edb7egdaniel VkImageBlit blitRegion; 9557ac5da853457b032781cf865ba018de78508edb7egdaniel memset(&blitRegion, 0, sizeof(VkImageBlit)); 95662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 95782c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth // SkMipMap doesn't include the base level in the level count so we have to add 1 95882c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth uint32_t levelCount = SkMipMap::ComputeLevelCount(tex->width(), tex->height()) + 1; 9597ac5da853457b032781cf865ba018de78508edb7egdaniel if (levelCount != tex->mipLevels()) { 9607ac5da853457b032781cf865ba018de78508edb7egdaniel const GrVkResource* oldResource = tex->resource(); 9617ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource->ref(); 9627ac5da853457b032781cf865ba018de78508edb7egdaniel // grab handle to the original image resource 9637ac5da853457b032781cf865ba018de78508edb7egdaniel VkImage oldImage = tex->image(); 9647ac5da853457b032781cf865ba018de78508edb7egdaniel 9657ac5da853457b032781cf865ba018de78508edb7egdaniel // change the original image's layout so we can copy from it 9667ac5da853457b032781cf865ba018de78508edb7egdaniel tex->setImageLayout(this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 9677ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); 9687ac5da853457b032781cf865ba018de78508edb7egdaniel 9697ac5da853457b032781cf865ba018de78508edb7egdaniel if (!tex->reallocForMipmap(this, levelCount)) { 9707ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource->unref(this); 9717ac5da853457b032781cf865ba018de78508edb7egdaniel return; 9727ac5da853457b032781cf865ba018de78508edb7egdaniel } 9737ac5da853457b032781cf865ba018de78508edb7egdaniel // change the new image's layout so we can blit to it 9747ac5da853457b032781cf865ba018de78508edb7egdaniel tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, 9757ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); 97662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 9777ac5da853457b032781cf865ba018de78508edb7egdaniel // Blit original image to top level of new image 9787ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 9797ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.srcOffsets[0] = { 0, 0, 0 }; 9807ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.srcOffsets[1] = { width, height, 1 }; 9817ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 9827ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.dstOffsets[0] = { 0, 0, 0 }; 9837ac5da853457b032781cf865ba018de78508edb7egdaniel blitRegion.dstOffsets[1] = { width, height, 1 }; 98462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 9857ac5da853457b032781cf865ba018de78508edb7egdaniel fCurrentCmdBuffer->blitImage(this, 9867ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource, 9877ac5da853457b032781cf865ba018de78508edb7egdaniel oldImage, 9887ac5da853457b032781cf865ba018de78508edb7egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 9897ac5da853457b032781cf865ba018de78508edb7egdaniel tex->resource(), 9907ac5da853457b032781cf865ba018de78508edb7egdaniel tex->image(), 9917ac5da853457b032781cf865ba018de78508edb7egdaniel VK_IMAGE_LAYOUT_GENERAL, 9927ac5da853457b032781cf865ba018de78508edb7egdaniel 1, 9937ac5da853457b032781cf865ba018de78508edb7egdaniel &blitRegion, 9947ac5da853457b032781cf865ba018de78508edb7egdaniel VK_FILTER_LINEAR); 99562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 9967ac5da853457b032781cf865ba018de78508edb7egdaniel oldResource->unref(this); 9977ac5da853457b032781cf865ba018de78508edb7egdaniel } else { 9987ac5da853457b032781cf865ba018de78508edb7egdaniel // change layout of the layers so we can write to them. 9997ac5da853457b032781cf865ba018de78508edb7egdaniel tex->setImageLayout(this, VK_IMAGE_LAYOUT_GENERAL, 10007ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, false); 10017ac5da853457b032781cf865ba018de78508edb7egdaniel } 100250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth 100350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth // setup memory barrier 10049440345a81d6c2372ac0aed937080f3da67439ddGreg Daniel SkASSERT(kUnknown_GrPixelConfig != GrVkFormatToPixelConfig(tex->imageFormat())); 100550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; 100650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VkImageMemoryBarrier imageMemoryBarrier = { 100750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 100850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth NULL, // pNext 10097ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask 10107ac5da853457b032781cf865ba018de78508edb7egdaniel VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask 101150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_IMAGE_LAYOUT_GENERAL, // oldLayout 101250c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_IMAGE_LAYOUT_GENERAL, // newLayout 101350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 101450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex 1015b2df0c2702329be6380a943d548e7377a51d8565egdaniel tex->image(), // image 101650c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth { aspectFlags, 0, 1, 0, 1 } // subresourceRange 101750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth }; 101850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth 101962340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth // Blit the miplevels 102082c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth uint32_t mipLevel = 1; 102182c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth while (mipLevel < levelCount) { 102282c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth int prevWidth = width; 102382c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth int prevHeight = height; 102482c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth width = SkTMax(1, width / 2); 102582c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth height = SkTMax(1, height / 2); 102682c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth 102750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth imageMemoryBarrier.subresourceRange.baseMipLevel = mipLevel - 1; 102850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth this->addImageMemoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 102950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth false, &imageMemoryBarrier); 103050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth 103150c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel - 1, 0, 1 }; 103262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth blitRegion.srcOffsets[0] = { 0, 0, 0 }; 1033e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman blitRegion.srcOffsets[1] = { prevWidth, prevHeight, 1 }; 103482c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 0, 1 }; 103562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth blitRegion.dstOffsets[0] = { 0, 0, 0 }; 1036e9906e71fbc29968ea10680f0fcd53a4153c7568brianosman blitRegion.dstOffsets[1] = { width, height, 1 }; 103762340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth fCurrentCmdBuffer->blitImage(this, 1038b2df0c2702329be6380a943d548e7377a51d8565egdaniel *tex, 1039b2df0c2702329be6380a943d548e7377a51d8565egdaniel *tex, 104062340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 1, 104162340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth &blitRegion, 104262340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth VK_FILTER_LINEAR); 104382c0558d93b15e13f5ad431eeef44055af25bbcbjvanverth ++mipLevel; 104462340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth } 104562340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth} 104662340067270c5c3365afa6b40b8e995ae6a6c1ecjvanverth 1047164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 1048164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1049164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 1050164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int width, 1051164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int height) { 1052164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(width >= rt->width()); 1053164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(height >= rt->height()); 1054164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1055164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int samples = rt->numStencilSamples(); 1056164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10578f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10egdaniel const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat(); 1058164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1059164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this, 1060164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel width, 1061164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel height, 1062164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel samples, 1063164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel sFmt)); 1064164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fStats.incStencilAttachmentCreates(); 1065164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return stencil; 1066164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1067164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1068164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 1069164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10709d54afc38b171c01a03b34e773d154fcf83d97dcjvanverthbool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc, 10713602d4f16a01da860d16eb36fb52eb62487495ccegdaniel size_t srcRowBytes, size_t dstRowBytes, int h) { 10723602d4f16a01da860d16eb36fb52eb62487495ccegdaniel void* mapPtr; 10733602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VkResult err = GR_VK_CALL(gpu->vkInterface(), MapMemory(gpu->device(), 10749d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth alloc.fMemory, 10759d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth alloc.fOffset, 10763602d4f16a01da860d16eb36fb52eb62487495ccegdaniel dstRowBytes * h, 10773602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 0, 10783602d4f16a01da860d16eb36fb52eb62487495ccegdaniel &mapPtr)); 10793602d4f16a01da860d16eb36fb52eb62487495ccegdaniel if (err) { 10803602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return false; 10813602d4f16a01da860d16eb36fb52eb62487495ccegdaniel } 10823602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 108320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (srcData) { 108420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // If there is no padding on dst we can do a single memcopy. 108520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // This assumes the srcData comes in with no padding. 108620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkRectMemcpy(mapPtr, static_cast<size_t>(dstRowBytes), 108720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel srcData, srcRowBytes, srcRowBytes, h); 108820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } else { 108920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // If there is no srcdata we always copy 0's into the textures so that it is initialized 109020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // with some data. 109120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (srcRowBytes == static_cast<size_t>(dstRowBytes)) { 109220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(mapPtr, 0, srcRowBytes * h); 109320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } else { 109420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel for (int i = 0; i < h; ++i) { 109520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(mapPtr, 0, srcRowBytes); 109620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel mapPtr = SkTAddOffset<void>(mapPtr, static_cast<size_t>(dstRowBytes)); 109720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 109820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 109920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 11009d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkMemory::FlushMappedAlloc(gpu, alloc); 11019d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GR_VK_CALL(gpu->vkInterface(), UnmapMemory(gpu->device(), alloc.fMemory)); 11023602d4f16a01da860d16eb36fb52eb62487495ccegdaniel return true; 11033602d4f16a01da860d16eb36fb52eb62487495ccegdaniel} 11043602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 1105164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h, 11060a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel GrPixelConfig config, 11070a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel bool isRenderTarget) { 1108164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1109164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 1110164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 1111164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 1112164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1113164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1114164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 1115164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(config)) { 1116164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 1117164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1118164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 11190a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel if (isRenderTarget && !fVkCaps->isConfigRenderable(config, false)) { 11200a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel return 0; 11210a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel } 11220a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel 1123a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel if (fVkCaps->isConfigTexturableLinearly(config) && 11240a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel (!isRenderTarget || fVkCaps->isConfigRenderableLinearly(config, false))) { 1125164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 1126164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1127164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1128164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 1129164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1130164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 11310a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel if (isRenderTarget) { 11320a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 11330a3a7f7303273151f1585b3cf5f6968e3932bfedegdaniel } 1134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1135fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImage image = VK_NULL_HANDLE; 11369d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkAlloc alloc = { VK_NULL_HANDLE, 0, 0, 0 }; 1137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1138fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 1139fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling) 1140fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth ? VK_IMAGE_LAYOUT_PREINITIALIZED 1141fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth : VK_IMAGE_LAYOUT_UNDEFINED; 1142fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1143fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth // Create Image 1144fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkSampleCountFlagBits vkSamples; 1145fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (!GrSampleCountToVkSampleCount(1, &vkSamples)) { 1146fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return 0; 1147fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 1148fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1149fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const VkImageCreateInfo imageCreateInfo = { 1150fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 1151fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth NULL, // pNext 1152fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // VkImageCreateFlags 1153fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_IMAGE_TYPE_2D, // VkImageType 1154fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth pixelFormat, // VkFormat 1155384b5e9cd36e443437de8df3b0f78ef4150efbacethannicholas { (uint32_t) w, (uint32_t) h, 1 }, // VkExtent3D 1156fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1, // mipLevels 1157fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1, // arrayLayers 1158fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth vkSamples, // samples 1159fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth imageTiling, // VkImageTiling 1160fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth usageFlags, // VkImageUsageFlags 1161fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode 1162fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // queueFamilyCount 1163fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // pQueueFamilyIndices 1164fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth initialLayout // initialLayout 1165fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth }; 1166fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1167fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image)); 1168fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 11696b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth if (!GrVkMemory::AllocAndBindImageMemory(this, image, linearTiling, &alloc)) { 1170fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(DestroyImage(this->device(), image, nullptr)); 1171164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 1172164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1173164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 117420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel size_t bpp = GrBytesPerPixel(config); 117520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel size_t rowCopyBytes = bpp * w; 117620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (linearTiling) { 117720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel const VkImageSubresource subres = { 117820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_IMAGE_ASPECT_COLOR_BIT, 117920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 0, // mipLevel 118020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 0, // arraySlice 118120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel }; 118220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkSubresourceLayout layout; 118320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 118420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout)); 118520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 118620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (!copy_testing_data(this, srcData, alloc, rowCopyBytes, 118720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel static_cast<size_t>(layout.rowPitch), h)) { 118820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 118920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 119020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel return 0; 119120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 119220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } else { 119320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkASSERT(w && h); 119420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 119520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkBuffer buffer; 119620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkBufferCreateInfo bufInfo; 119720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(&bufInfo, 0, sizeof(VkBufferCreateInfo)); 119820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 119920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.flags = 0; 120020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.size = rowCopyBytes * h; 120120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 120220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 120320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.queueFamilyIndexCount = 0; 120420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel bufInfo.pQueueFamilyIndices = nullptr; 120520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkResult err; 120620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(CreateBuffer(fDevice, &bufInfo, nullptr, &buffer)); 120720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 120820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (err) { 120920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 121020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 121120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel return 0; 121220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 12133602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 121420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkAlloc bufferAlloc = { VK_NULL_HANDLE, 0, 0, 0 }; 121520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type, 121620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel true, &bufferAlloc)) { 121720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 121820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 121920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 122020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel return 0; 122120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 12223602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 122320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (!copy_testing_data(this, srcData, bufferAlloc, rowCopyBytes, rowCopyBytes, h)) { 122420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 122520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 122620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 122720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 122820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel return 0; 122920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 12303602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 123120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel const VkCommandBufferAllocateInfo cmdInfo = { 123220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType 123320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel NULL, // pNext 123420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel fCmdPool, // commandPool 123520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level 123620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 1 // bufferCount 123720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel }; 123820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 123920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkCommandBuffer cmdBuffer; 124020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(AllocateCommandBuffers(fDevice, &cmdInfo, &cmdBuffer)); 124120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (err) { 124220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 124320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 124420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 124520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 124620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel return 0; 124720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel } 12483602d4f16a01da860d16eb36fb52eb62487495ccegdaniel 124920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkCommandBufferBeginInfo cmdBufferBeginInfo; 125020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo)); 125120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 125220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel cmdBufferBeginInfo.pNext = nullptr; 125320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 125420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel cmdBufferBeginInfo.pInheritanceInfo = nullptr; 125520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 125620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo)); 125720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkASSERT(!err); 125820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 125920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // Set image layout and add barrier 126020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkImageMemoryBarrier barrier; 126120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(&barrier, 0, sizeof(VkImageMemoryBarrier)); 126220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 126320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.pNext = nullptr; 126420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout); 126520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 126620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 126720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 126820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 126920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.image = image; 127020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0 , 1}; 127120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 127220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(CmdPipelineBarrier(cmdBuffer, 127320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::LayoutToPipelineStageFlags(initialLayout), 127420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 127520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 0, 127620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 0, nullptr, 127720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 0, nullptr, 127820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 1, &barrier)); 127920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 128020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 128120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // Submit copy command 128220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkBufferImageCopy region; 128320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 128420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel region.bufferOffset = 0; 128520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel region.bufferRowLength = w; 128620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel region.bufferImageHeight = h; 128720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 128820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel region.imageOffset = { 0, 0, 0 }; 128920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel region.imageExtent = { (uint32_t)w, (uint32_t)h, 1 }; 129020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 129120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, 1, ®ion)); 129220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 129320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // End CommandBuffer 129420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(EndCommandBuffer(cmdBuffer)); 129520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkASSERT(!err); 129620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 129720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // Create Fence for queue 129820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkFence fence; 129920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkFenceCreateInfo fenceInfo; 130020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo)); 130120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 130220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 130320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence)); 130420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkASSERT(!err); 130520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 130620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VkSubmitInfo submitInfo; 130720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel memset(&submitInfo, 0, sizeof(VkSubmitInfo)); 130820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 130920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.pNext = nullptr; 131020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.waitSemaphoreCount = 0; 131120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.pWaitSemaphores = nullptr; 131220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.pWaitDstStageMask = 0; 131320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.commandBufferCount = 1; 131420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.pCommandBuffers = &cmdBuffer; 131520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.signalSemaphoreCount = 0; 131620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel submitInfo.pSignalSemaphores = nullptr; 131720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence)); 131820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkASSERT(!err); 131920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 132020ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX)); 132120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel if (VK_TIMEOUT == err) { 132220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeImageMemory(this, linearTiling, alloc); 132320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyImage(fDevice, image, nullptr)); 13243602d4f16a01da860d16eb36fb52eb62487495ccegdaniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 13253602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 13263602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); 13273602d4f16a01da860d16eb36fb52eb62487495ccegdaniel VK_CALL(DestroyFence(fDevice, fence, nullptr)); 132820ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkDebugf("Fence failed to signal: %d\n", err); 132920ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkFAIL("failing"); 1330164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 133120ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel SkASSERT(!err); 133220ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel 133320ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel // Clean up transfer resources 133420ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc); 133520ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); 133620ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); 133720ece3a966708bf2886034cda15aea7f4946f4b1Greg Daniel VK_CALL(DestroyFence(fDevice, fence, nullptr)); 1338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1340b2df0c2702329be6380a943d548e7377a51d8565egdaniel GrVkImageInfo* info = new GrVkImageInfo; 1341fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImage = image; 1342fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fAlloc = alloc; 1343fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImageTiling = imageTiling; 1344fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImageLayout = initialLayout; 134558a8d9214a70e0f6c81c88a8b0b563c06bf0f70eegdaniel info->fFormat = pixelFormat; 13462af0f1b014b9aabb6119bf66fac20e4cd3a8279bjvanverth info->fLevelCount = 1; 1347fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1348fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return (GrBackendObject)info; 1349164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1350164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1351164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { 1352b2df0c2702329be6380a943d548e7377a51d8565egdaniel const GrVkImageInfo* backend = reinterpret_cast<const GrVkImageInfo*>(id); 1353164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 13541e305ba0d6a4237020d36234e9e286d3b0489401jvanverth if (backend && backend->fImage && backend->fAlloc.fMemory) { 1355164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryRequirements req; 1356164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&req, 0, sizeof(req)); 1357164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, 1358164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel backend->fImage, 1359164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &req)); 1360164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: find a better check 1361164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This will probably fail with a different driver 1362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return (req.size > 0) && (req.size <= 8192 * 8192); 1363164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1364164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1365164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1367164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1368164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) { 13696b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth GrVkImageInfo* backend = reinterpret_cast<GrVkImageInfo*>(id); 1370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (backend) { 1371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!abandon) { 1372fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth // something in the command buffer may still be using this, so force submit 1373fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth this->submitCommandBuffer(kForce_SyncQueue); 13746b6ffc4ab6ecee9f46425a5467ef0fbebbb8c9cdjvanverth GrVkImage::DestroyImageInfo(this, backend); 1375164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1376fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth delete backend; 1377164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1378164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1379164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 1381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1382164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask, 1383164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 1384164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 1385164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryBarrier* barrier) const { 1386164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 1387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 1388164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 1391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kMemory_BarrierType, 1392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 1393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1395164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addBufferMemoryBarrier(VkPipelineStageFlags srcStageMask, 1396164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 1397164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 1398164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferMemoryBarrier* barrier) const { 1399164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 1400164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 1401164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1402164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1403164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 1404164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kBufferMemory_BarrierType, 1405164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 1406164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1407164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1408164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask, 1409164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 1410164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 1411164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageMemoryBarrier* barrier) const { 1412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 1413164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 1414164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1415164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1416164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 1417164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kImageMemory_BarrierType, 1418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 1419164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1420164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1421f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillipsvoid GrVkGpu::finishOpList() { 1422164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Submit the current command buffer to the Queue 1423164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 1424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1425164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 14263d5d9ac426ea926f37eaa47e13acf7492068667begdanielvoid GrVkGpu::clearStencil(GrRenderTarget* target) { 14273d5d9ac426ea926f37eaa47e13acf7492068667begdaniel if (nullptr == target) { 14283d5d9ac426ea926f37eaa47e13acf7492068667begdaniel return; 14293d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 14303d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrStencilAttachment* stencil = target->renderTargetPriv().getStencilAttachment(); 14313d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; 14323d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 14333d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 14343d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkClearDepthStencilValue vkStencilColor; 14353d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); 14363d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 14373d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencil->setImageLayout(this, 14383d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 143950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 144050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 14413d5d9ac426ea926f37eaa47e13acf7492068667begdaniel false); 14423d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 14433d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkImageSubresourceRange subRange; 14443d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&subRange, 0, sizeof(VkImageSubresourceRange)); 14453d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 14463d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.baseMipLevel = 0; 14473d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.levelCount = 1; 14483d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.baseArrayLayer = 0; 14493d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.layerCount = 1; 14503d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 14513d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a 14523d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // draw. Thus we should look into using the load op functions on the render pass to clear out 14533d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // the stencil there. 14543d5d9ac426ea926f37eaa47e13acf7492068667begdaniel fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange); 14553d5d9ac426ea926f37eaa47e13acf7492068667begdaniel} 14563d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 1457164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_image(const GrSurface* dst, 1458164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 1459164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 14604bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrRenderTarget* dstRT = dst->asRenderTarget(); 14614bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrRenderTarget* srcRT = src->asRenderTarget(); 14624bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (dstRT && srcRT) { 14634bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (srcRT->numColorSamples() != dstRT->numColorSamples()) { 14644bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 14654bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 14664bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } else if (dstRT) { 14674bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (dstRT->numColorSamples() > 1) { 14684bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 14694bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 14704bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } else if (srcRT) { 14714bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (srcRT->numColorSamples() > 1) { 14724bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 14734bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 147417b892551465e5a44560a06e4b34dc3592b49622egdaniel } 147517b892551465e5a44560a06e4b34dc3592b49622egdaniel 14763251ed84052ced22d1e4c285524a835a82f7dd12Michael Jurka // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src 147717b892551465e5a44560a06e4b34dc3592b49622egdaniel // as image usage flags. 147817b892551465e5a44560a06e4b34dc3592b49622egdaniel if (src->origin() == dst->origin() && 147917b892551465e5a44560a06e4b34dc3592b49622egdaniel GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { 1480164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1481164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1482164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1483164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1484164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1485164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1486164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, 1487164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 148817b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* dstImage, 148917b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* srcImage, 1490164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1491164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1492164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(can_copy_image(dst, src, this)); 1493164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1494164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // These flags are for flushing/invalidating caches and for the dst image it doesn't matter if 1495164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // the cache is flushed since it is only being written to. 149617b892551465e5a44560a06e4b34dc3592b49622egdaniel dstImage->setImageLayout(this, 149750c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 149850c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 149950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 150050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth false); 1501164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 150217b892551465e5a44560a06e4b34dc3592b49622egdaniel srcImage->setImageLayout(this, 150317b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 150450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_READ_BIT, 150550c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 150617b892551465e5a44560a06e4b34dc3592b49622egdaniel false); 1507164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1508164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Flip rect if necessary 1509164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkIRect srcVkRect = srcRect; 1510164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int32_t dstY = dstPoint.fY; 1511164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1512164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 1513164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); 1514164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fTop = src->height() - srcRect.fBottom; 1515164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fBottom = src->height() - srcRect.fTop; 1516164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstY = dst->height() - dstPoint.fY - srcVkRect.height(); 1517164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1518164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1519164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageCopy copyRegion; 1520164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(©Region, 0, sizeof(VkImageCopy)); 1521164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1522164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 1523164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1524164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstOffset = { dstPoint.fX, dstY, 0 }; 1525c355bc8dd117291b63ee7b7b39ec37a0e768eec5egdaniel copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 }; 1526164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1527164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImage(this, 152817b892551465e5a44560a06e4b34dc3592b49622egdaniel srcImage, 1529164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 153017b892551465e5a44560a06e4b34dc3592b49622egdaniel dstImage, 1531164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1532164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1533164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ©Region); 1534900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 1535900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 1536900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth srcRect.width(), srcRect.height()); 1537900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth this->didWriteToSurface(dst, &dstRect); 1538164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1539164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 154017b892551465e5a44560a06e4b34dc3592b49622egdanielinline bool can_copy_as_blit(const GrSurface* dst, 154117b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrSurface* src, 154217b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkImage* dstImage, 154317b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkImage* srcImage, 154417b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkGpu* gpu) { 154566933552f1723c4a2b248711ab3d43921401e8e6egdaniel // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src 154617b892551465e5a44560a06e4b34dc3592b49622egdaniel // as image usage flags. 154717b892551465e5a44560a06e4b34dc3592b49622egdaniel const GrVkCaps& caps = gpu->vkCaps(); 154817b892551465e5a44560a06e4b34dc3592b49622egdaniel if (!caps.configCanBeDstofBlit(dst->config(), dstImage->isLinearTiled()) || 154917b892551465e5a44560a06e4b34dc3592b49622egdaniel !caps.configCanBeSrcofBlit(src->config(), srcImage->isLinearTiled())) { 155017b892551465e5a44560a06e4b34dc3592b49622egdaniel return false; 155117b892551465e5a44560a06e4b34dc3592b49622egdaniel } 155217b892551465e5a44560a06e4b34dc3592b49622egdaniel 155317b892551465e5a44560a06e4b34dc3592b49622egdaniel // We cannot blit images that are multisampled. Will need to figure out if we can blit the 155417b892551465e5a44560a06e4b34dc3592b49622egdaniel // resolved msaa though. 155517b892551465e5a44560a06e4b34dc3592b49622egdaniel if ((dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1) || 155617b892551465e5a44560a06e4b34dc3592b49622egdaniel (src->asRenderTarget() && src->asRenderTarget()->numColorSamples() > 1)) { 155717b892551465e5a44560a06e4b34dc3592b49622egdaniel return false; 155817b892551465e5a44560a06e4b34dc3592b49622egdaniel } 155917b892551465e5a44560a06e4b34dc3592b49622egdaniel 156017b892551465e5a44560a06e4b34dc3592b49622egdaniel return true; 156117b892551465e5a44560a06e4b34dc3592b49622egdaniel} 156217b892551465e5a44560a06e4b34dc3592b49622egdaniel 156317b892551465e5a44560a06e4b34dc3592b49622egdanielvoid GrVkGpu::copySurfaceAsBlit(GrSurface* dst, 156417b892551465e5a44560a06e4b34dc3592b49622egdaniel GrSurface* src, 156517b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* dstImage, 156617b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* srcImage, 156717b892551465e5a44560a06e4b34dc3592b49622egdaniel const SkIRect& srcRect, 156817b892551465e5a44560a06e4b34dc3592b49622egdaniel const SkIPoint& dstPoint) { 156917b892551465e5a44560a06e4b34dc3592b49622egdaniel SkASSERT(can_copy_as_blit(dst, src, dstImage, srcImage, this)); 157017b892551465e5a44560a06e4b34dc3592b49622egdaniel 157117b892551465e5a44560a06e4b34dc3592b49622egdaniel dstImage->setImageLayout(this, 157217b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 157350c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_WRITE_BIT, 157450c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 157517b892551465e5a44560a06e4b34dc3592b49622egdaniel false); 157617b892551465e5a44560a06e4b34dc3592b49622egdaniel 157717b892551465e5a44560a06e4b34dc3592b49622egdaniel srcImage->setImageLayout(this, 157817b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 157950c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_ACCESS_TRANSFER_READ_BIT, 158050c46c7b189caf94abb79cdc125245a6c0de0b4ejvanverth VK_PIPELINE_STAGE_TRANSFER_BIT, 158117b892551465e5a44560a06e4b34dc3592b49622egdaniel false); 158217b892551465e5a44560a06e4b34dc3592b49622egdaniel 158317b892551465e5a44560a06e4b34dc3592b49622egdaniel // Flip rect if necessary 158417b892551465e5a44560a06e4b34dc3592b49622egdaniel SkIRect srcVkRect; 15858af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fLeft = srcRect.fLeft; 15868af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fRight = srcRect.fRight; 158717b892551465e5a44560a06e4b34dc3592b49622egdaniel SkIRect dstRect; 158817b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fLeft = dstPoint.fX; 15898af936d3047208def585b7bc824f013b994f6312egdaniel dstRect.fRight = dstPoint.fX + srcRect.width(); 159017b892551465e5a44560a06e4b34dc3592b49622egdaniel 159117b892551465e5a44560a06e4b34dc3592b49622egdaniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 159217b892551465e5a44560a06e4b34dc3592b49622egdaniel srcVkRect.fTop = src->height() - srcRect.fBottom; 159317b892551465e5a44560a06e4b34dc3592b49622egdaniel srcVkRect.fBottom = src->height() - srcRect.fTop; 159417b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 15958af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fTop = srcRect.fTop; 15968af936d3047208def585b7bc824f013b994f6312egdaniel srcVkRect.fBottom = srcRect.fBottom; 159717b892551465e5a44560a06e4b34dc3592b49622egdaniel } 159817b892551465e5a44560a06e4b34dc3592b49622egdaniel 159917b892551465e5a44560a06e4b34dc3592b49622egdaniel if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 160017b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fTop = dst->height() - dstPoint.fY - srcVkRect.height(); 160117b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 160217b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fTop = dstPoint.fY; 160317b892551465e5a44560a06e4b34dc3592b49622egdaniel } 160417b892551465e5a44560a06e4b34dc3592b49622egdaniel dstRect.fBottom = dstRect.fTop + srcVkRect.height(); 160517b892551465e5a44560a06e4b34dc3592b49622egdaniel 160617b892551465e5a44560a06e4b34dc3592b49622egdaniel // If we have different origins, we need to flip the top and bottom of the dst rect so that we 160717b892551465e5a44560a06e4b34dc3592b49622egdaniel // get the correct origintation of the copied data. 160817b892551465e5a44560a06e4b34dc3592b49622egdaniel if (src->origin() != dst->origin()) { 160917b892551465e5a44560a06e4b34dc3592b49622egdaniel SkTSwap(dstRect.fTop, dstRect.fBottom); 161017b892551465e5a44560a06e4b34dc3592b49622egdaniel } 161117b892551465e5a44560a06e4b34dc3592b49622egdaniel 161217b892551465e5a44560a06e4b34dc3592b49622egdaniel VkImageBlit blitRegion; 161317b892551465e5a44560a06e4b34dc3592b49622egdaniel memset(&blitRegion, 0, sizeof(VkImageBlit)); 161417b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 161517b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 1616e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 1 }; 161717b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 161817b892551465e5a44560a06e4b34dc3592b49622egdaniel blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 }; 1619e76071ca0f98cb4d7e2d1789c46aa3037637b309Greg Daniel blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 1 }; 162017b892551465e5a44560a06e4b34dc3592b49622egdaniel 162117b892551465e5a44560a06e4b34dc3592b49622egdaniel fCurrentCmdBuffer->blitImage(this, 1622b2df0c2702329be6380a943d548e7377a51d8565egdaniel *srcImage, 1623b2df0c2702329be6380a943d548e7377a51d8565egdaniel *dstImage, 162417b892551465e5a44560a06e4b34dc3592b49622egdaniel 1, 162517b892551465e5a44560a06e4b34dc3592b49622egdaniel &blitRegion, 162617b892551465e5a44560a06e4b34dc3592b49622egdaniel VK_FILTER_NEAREST); // We never scale so any filter works here 1627900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth 1628900bd4a0463bc6471ef07a77120b413bd8f472b2jvanverth this->didWriteToSurface(dst, &dstRect); 162917b892551465e5a44560a06e4b34dc3592b49622egdaniel} 163017b892551465e5a44560a06e4b34dc3592b49622egdaniel 16314bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielinline bool can_copy_as_resolve(const GrSurface* dst, 16324bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrSurface* src, 16334bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const GrVkGpu* gpu) { 16344bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // Our src must be a multisampled render target 16354bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (!src->asRenderTarget() || src->asRenderTarget()->numColorSamples() <= 1) { 16364bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 16374bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 16384bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 16397d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel // The dst must not be a multisampled render target, expect in the case where the dst is the 16407d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel // resolve texture connected to the msaa src. We check for this in case we are copying a part of 16417d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel // a surface to a different region in the same surface. 16427d6f6666fe8f3b45734f9dd1a9d1d34b7bdd6b60Greg Daniel if (dst->asRenderTarget() && dst->asRenderTarget()->numColorSamples() > 1 && dst != src) { 16434bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 16444bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 16454bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 16464bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel // Surfaces must have the same origin. 16474bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (src->origin() != dst->origin()) { 16484bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return false; 16494bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 16504bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 16514bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel return true; 16524bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel} 16534bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 16544bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdanielvoid GrVkGpu::copySurfaceAsResolve(GrSurface* dst, 16554bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrSurface* src, 16564bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIRect& srcRect, 16574bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel const SkIPoint& dstPoint) { 16584bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget()); 1659bc26c392b2f2e27ea554347dfdb5f994b6dc54f2Greg Daniel this->resolveImage(dst, srcRT, srcRect, dstPoint); 16604bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel} 16614bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 1662164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onCopySurface(GrSurface* dst, 1663164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 16664bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (can_copy_as_resolve(dst, src, this)) { 16674bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel this->copySurfaceAsResolve(dst, src, srcRect, dstPoint); 1668ec44099979acd3e83ad93a15dbd9301856a90572egdaniel return true; 16694bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel } 16704bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel 1671fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel if (this->vkCaps().mustSubmitCommandsBeforeCopyOp()) { 1672fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); 1673fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel } 1674fd016d7a69f0415f2497d25ec3a7b71de1545826egdaniel 1675bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel if (fCopyManager.copySurfaceAsDraw(this, dst, src, srcRect, dstPoint)) { 1676bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel return true; 1677bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel } 1678bc9b2963bf9e39c47ae5c3ab94b8503b476f4f0eegdaniel 167917b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* dstImage; 168017b892551465e5a44560a06e4b34dc3592b49622egdaniel GrVkImage* srcImage; 16814bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrRenderTarget* dstRT = dst->asRenderTarget(); 16824bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (dstRT) { 16834bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(dstRT); 16844bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dstImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; 168517b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 16864bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(dst->asTexture()); 16874bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel dstImage = static_cast<GrVkTexture*>(dst->asTexture()); 168817b892551465e5a44560a06e4b34dc3592b49622egdaniel } 16894bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrRenderTarget* srcRT = src->asRenderTarget(); 16904bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel if (srcRT) { 16914bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(srcRT); 16924bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcImage = vkRT->numColorSamples() > 1 ? vkRT->msaaImage() : vkRT; 169317b892551465e5a44560a06e4b34dc3592b49622egdaniel } else { 16944bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel SkASSERT(src->asTexture()); 16954bcd62e3313da60c3aa96ccd12b7ea440c7266d4egdaniel srcImage = static_cast<GrVkTexture*>(src->asTexture()); 169617b892551465e5a44560a06e4b34dc3592b49622egdaniel } 169717b892551465e5a44560a06e4b34dc3592b49622egdaniel 169813dddce65fd87a8175a209a49f35615735a2886aBrian Osman // For borrowed textures, we *only* want to copy using draws (to avoid layout changes) 169913dddce65fd87a8175a209a49f35615735a2886aBrian Osman if (srcImage->isBorrowed()) { 170013dddce65fd87a8175a209a49f35615735a2886aBrian Osman return false; 170113dddce65fd87a8175a209a49f35615735a2886aBrian Osman } 170213dddce65fd87a8175a209a49f35615735a2886aBrian Osman 1703164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (can_copy_image(dst, src, this)) { 170417b892551465e5a44560a06e4b34dc3592b49622egdaniel this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstPoint); 170517b892551465e5a44560a06e4b34dc3592b49622egdaniel return true; 170617b892551465e5a44560a06e4b34dc3592b49622egdaniel } 170717b892551465e5a44560a06e4b34dc3592b49622egdaniel 170817b892551465e5a44560a06e4b34dc3592b49622egdaniel if (can_copy_as_blit(dst, src, dstImage, srcImage, this)) { 170917b892551465e5a44560a06e4b34dc3592b49622egdaniel this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint); 1710164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1711164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1712164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1713164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1714164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1715164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1716c25c5d73e9f4d840dc758c399496d5690709ad58csmartdaltonvoid GrVkGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&, 1717c25c5d73e9f4d840dc758c399496d5690709ad58csmartdalton int* effectiveSampleCnt, SamplePattern*) { 171828f45b949acc746849100fbe112ee5280f0594c9cdalton // TODO: stub. 171928f45b949acc746849100fbe112ee5280f0594c9cdalton SkASSERT(!this->caps()->sampleLocationsSupport()); 172028f45b949acc746849100fbe112ee5280f0594c9cdalton *effectiveSampleCnt = rt->desc().fSampleCnt; 172128f45b949acc746849100fbe112ee5280f0594c9cdalton} 172228f45b949acc746849100fbe112ee5280f0594c9cdalton 1723164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 1724164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig readConfig, DrawPreference* drawPreference, 1725164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ReadPixelTempDrawInfo* tempDrawInfo) { 172688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // These settings we will always want if a temp draw is performed. 172788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; 172888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fWidth = width; 172988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fHeight = height; 173088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 173188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 1732b117ff194ff888ef9107a4797aad053b0d76be30bsalomon tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox; 173388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel 173488e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // For now assume no swizzling, we may change that below. 173588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); 173688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel 173788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read 173888e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // from will be srcConfig and we will read readConfig pixels from it. 173933910297e032b9af4336bc146c7fbb0f35918de9Brian Osman // Note that if we require a draw and return a non-renderable format for the temp surface the 174088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel // base class will fail for us. 174188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config(); 174288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel tempDrawInfo->fReadConfig = readConfig; 174388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel 17444583ec51d9ddc830eeb854db068235be96ce59c4egdaniel if (srcSurface->config() == readConfig) { 17454583ec51d9ddc830eeb854db068235be96ce59c4egdaniel return true; 1746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 174833910297e032b9af4336bc146c7fbb0f35918de9Brian Osman // Any config change requires a draw 174933910297e032b9af4336bc146c7fbb0f35918de9Brian Osman ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 175033910297e032b9af4336bc146c7fbb0f35918de9Brian Osman tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; 175133910297e032b9af4336bc146c7fbb0f35918de9Brian Osman tempDrawInfo->fReadConfig = readConfig; 1752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 175333910297e032b9af4336bc146c7fbb0f35918de9Brian Osman return true; 1754164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onReadPixels(GrSurface* surface, 1757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 1758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config, 1759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* buffer, 1760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 1761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 1762164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 1763164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1764164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1765164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 176666933552f1723c4a2b248711ab3d43921401e8e6egdaniel GrVkImage* image = nullptr; 176766933552f1723c4a2b248711ab3d43921401e8e6egdaniel GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(surface->asRenderTarget()); 176866933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (rt) { 176966933552f1723c4a2b248711ab3d43921401e8e6egdaniel // resolve the render target if necessary 177066933552f1723c4a2b248711ab3d43921401e8e6egdaniel switch (rt->getResolveType()) { 177166933552f1723c4a2b248711ab3d43921401e8e6egdaniel case GrVkRenderTarget::kCantResolve_ResolveType: 177266933552f1723c4a2b248711ab3d43921401e8e6egdaniel return false; 177366933552f1723c4a2b248711ab3d43921401e8e6egdaniel case GrVkRenderTarget::kAutoResolves_ResolveType: 177466933552f1723c4a2b248711ab3d43921401e8e6egdaniel break; 177566933552f1723c4a2b248711ab3d43921401e8e6egdaniel case GrVkRenderTarget::kCanResolve_ResolveType: 177669d4992e69d7b142450d0ccb587b7b26be7cf1eaGreg Daniel this->internalResolveRenderTarget(rt, false); 177766933552f1723c4a2b248711ab3d43921401e8e6egdaniel break; 177866933552f1723c4a2b248711ab3d43921401e8e6egdaniel default: 177966933552f1723c4a2b248711ab3d43921401e8e6egdaniel SkFAIL("Unknown resolve type"); 178066933552f1723c4a2b248711ab3d43921401e8e6egdaniel } 178166933552f1723c4a2b248711ab3d43921401e8e6egdaniel image = rt; 178266933552f1723c4a2b248711ab3d43921401e8e6egdaniel } else { 178366933552f1723c4a2b248711ab3d43921401e8e6egdaniel image = static_cast<GrVkTexture*>(surface->asTexture()); 178466933552f1723c4a2b248711ab3d43921401e8e6egdaniel } 178566933552f1723c4a2b248711ab3d43921401e8e6egdaniel 178666933552f1723c4a2b248711ab3d43921401e8e6egdaniel if (!image) { 1787164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1789164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our target so it can be used as copy 179166933552f1723c4a2b248711ab3d43921401e8e6egdaniel image->setImageLayout(this, 179266933552f1723c4a2b248711ab3d43921401e8e6egdaniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 179366933552f1723c4a2b248711ab3d43921401e8e6egdaniel VK_ACCESS_TRANSFER_READ_BIT, 179466933552f1723c4a2b248711ab3d43921401e8e6egdaniel VK_PIPELINE_STAGE_TRANSFER_BIT, 179566933552f1723c4a2b248711ab3d43921401e8e6egdaniel false); 1796164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 17976fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel size_t bpp = GrBytesPerPixel(config); 17986fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel size_t tightRowBytes = bpp * width; 1799164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 1800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1801164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferImageCopy region; 1802164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 18036fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 18046fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel bool copyFromOrigin = this->vkCaps().mustDoCopiesFromOrigin(); 18056fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel if (copyFromOrigin) { 18066fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageOffset = { 0, 0, 0 }; 18076fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageExtent = { (uint32_t)(left + width), 18086fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel (uint32_t)(flipY ? surface->height() - top : top + height), 18096fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 1 18106fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel }; 18116fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel } else { 18126fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel VkOffset3D offset = { 18136fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel left, 18146fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel flipY ? surface->height() - top - height : top, 18156fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 0 18166fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel }; 18176fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageOffset = offset; 18186fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 18196fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel } 18206fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 18216fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel size_t transBufferRowBytes = bpp * region.imageExtent.width; 18226fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel GrVkTransferBuffer* transferBuffer = 18236fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel static_cast<GrVkTransferBuffer*>(this->createBuffer(transBufferRowBytes * height, 18246fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel kXferGpuToCpu_GrBufferType, 18256fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel kStream_GrAccessPattern)); 18266fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 18276fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel // Copy the image to a buffer so we can map it to cpu memory 1828db37909347d034943bd6b0922710a94c6c6ea572jvanverth region.bufferOffset = transferBuffer->offset(); 182988e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel region.bufferRowLength = 0; // Forces RowLength to be width. We handle the rowBytes below. 1830164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images. 1831164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1832164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1833164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImageToBuffer(this, 183466933552f1723c4a2b248711ab3d43921401e8e6egdaniel image, 1835164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1836164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer, 1837164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1838164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ®ion); 1839164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1840164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // make sure the copy to buffer has finished 1841164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->addMemoryBarrier(this, 1842164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_TRANSFER_WRITE_BIT, 1843164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_READ_BIT, 1844164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 1845164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 1846164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1847164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1848164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We need to submit the current command buffer to the Queue and make sure it finishes before 1849164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // we can copy the data out of the buffer. 1850164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kForce_SyncQueue); 18519d54afc38b171c01a03b34e773d154fcf83d97dcjvanverth GrVkMemory::InvalidateMappedAlloc(this, transferBuffer->alloc()); 1852164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mappedMemory = transferBuffer->map(); 1853164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 18546fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel if (copyFromOrigin) { 18556fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel uint32_t skipRows = region.imageExtent.height - height; 18566fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel mappedMemory = (char*)mappedMemory + transBufferRowBytes * skipRows + bpp * left; 18576fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel } 18586fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel 1859164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (flipY) { 186088e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel const char* srcRow = reinterpret_cast<const char*>(mappedMemory); 186188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes; 186288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel for (int y = 0; y < height; y++) { 186388e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel memcpy(dstRow, srcRow, tightRowBytes); 18646fa0a91e607343a244a8789669d3fd15a98f80f7egdaniel srcRow += transBufferRowBytes; 186588e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel dstRow -= rowBytes; 186688e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel } 186788e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel } else { 1868cf3525a95eea54d00727392463a6fe648914c3eaMatt Sarett SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, height); 1869164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1870164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 187188e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel transferBuffer->unmap(); 187288e8aef3916454e5f6916cc8b3420345b1cf0584egdaniel transferBuffer->unref(); 1873164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1874164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1875066df7ca911b65d416783f3bec6f4f1662948ad5egdaniel 187627bb28473912181cf9a838e9282e86cb62e2d44begdaniel// The RenderArea bounds we pass into BeginRenderPass must have a start x value that is a multiple 187727bb28473912181cf9a838e9282e86cb62e2d44begdaniel// of the granularity. The width must also be a multiple of the granularity or eaqual to the width 187827bb28473912181cf9a838e9282e86cb62e2d44begdaniel// the the entire attachment. Similar requirements for the y and height components. 187927bb28473912181cf9a838e9282e86cb62e2d44begdanielvoid adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds, 188027bb28473912181cf9a838e9282e86cb62e2d44begdaniel const VkExtent2D& granularity, int maxWidth, int maxHeight) { 188127bb28473912181cf9a838e9282e86cb62e2d44begdaniel // Adjust Width 1882d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if ((0 != granularity.width && 1 != granularity.width)) { 1883d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel // Start with the right side of rect so we know if we end up going pass the maxWidth. 1884d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel int rightAdj = srcBounds.fRight % granularity.width; 1885d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (rightAdj != 0) { 1886d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel rightAdj = granularity.width - rightAdj; 1887d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 1888d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fRight = srcBounds.fRight + rightAdj; 1889d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (dstBounds->fRight > maxWidth) { 1890d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fRight = maxWidth; 1891d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fLeft = 0; 1892d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } else { 1893d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fLeft = srcBounds.fLeft - srcBounds.fLeft % granularity.width; 1894d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 189527bb28473912181cf9a838e9282e86cb62e2d44begdaniel } else { 1896d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fLeft = srcBounds.fLeft; 1897d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fRight = srcBounds.fRight; 189827bb28473912181cf9a838e9282e86cb62e2d44begdaniel } 189927bb28473912181cf9a838e9282e86cb62e2d44begdaniel 190027bb28473912181cf9a838e9282e86cb62e2d44begdaniel // Adjust height 1901d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if ((0 != granularity.height && 1 != granularity.height)) { 1902d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel // Start with the bottom side of rect so we know if we end up going pass the maxHeight. 1903d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel int bottomAdj = srcBounds.fBottom % granularity.height; 1904d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (bottomAdj != 0) { 1905d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel bottomAdj = granularity.height - bottomAdj; 1906d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 1907d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fBottom = srcBounds.fBottom + bottomAdj; 1908d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel if (dstBounds->fBottom > maxHeight) { 1909d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fBottom = maxHeight; 1910d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fTop = 0; 1911d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } else { 1912d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fTop = srcBounds.fTop - srcBounds.fTop % granularity.height; 1913d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel } 191427bb28473912181cf9a838e9282e86cb62e2d44begdaniel } else { 1915d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fTop = srcBounds.fTop; 1916d5797b3059a4037a6dce4c0a66693ba471b1588eegdaniel dstBounds->fBottom = srcBounds.fBottom; 191727bb28473912181cf9a838e9282e86cb62e2d44begdaniel } 191827bb28473912181cf9a838e9282e86cb62e2d44begdaniel} 191927bb28473912181cf9a838e9282e86cb62e2d44begdaniel 192022bc8653d704584e13f35844dafb5ddeb9989127Greg Danielvoid GrVkGpu::submitSecondaryCommandBuffer(const SkTArray<GrVkSecondaryCommandBuffer*>& buffers, 19219cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const GrVkRenderPass* renderPass, 19229cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const VkClearValue* colorClear, 19239cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel GrVkRenderTarget* target, 19249cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel const SkIRect& bounds) { 1925e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel const SkIRect* pBounds = &bounds; 1926e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel SkIRect flippedBounds; 1927e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel if (kBottomLeft_GrSurfaceOrigin == target->origin()) { 1928e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel flippedBounds = bounds; 1929e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel flippedBounds.fTop = target->height() - bounds.fBottom; 1930e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel flippedBounds.fBottom = target->height() - bounds.fTop; 1931e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel pBounds = &flippedBounds; 1932e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel } 1933e7d1b24ff0a04686aef54fcb9feaca7a03e19891egdaniel 193427bb28473912181cf9a838e9282e86cb62e2d44begdaniel // The bounds we use for the render pass should be of the granularity supported 193527bb28473912181cf9a838e9282e86cb62e2d44begdaniel // by the device. 193627bb28473912181cf9a838e9282e86cb62e2d44begdaniel const VkExtent2D& granularity = renderPass->granularity(); 193727bb28473912181cf9a838e9282e86cb62e2d44begdaniel SkIRect adjustedBounds; 193827bb28473912181cf9a838e9282e86cb62e2d44begdaniel if ((0 != granularity.width && 1 != granularity.width) || 193927bb28473912181cf9a838e9282e86cb62e2d44begdaniel (0 != granularity.height && 1 != granularity.height)) { 194027bb28473912181cf9a838e9282e86cb62e2d44begdaniel adjust_bounds_to_granularity(&adjustedBounds, *pBounds, granularity, 194127bb28473912181cf9a838e9282e86cb62e2d44begdaniel target->width(), target->height()); 194227bb28473912181cf9a838e9282e86cb62e2d44begdaniel pBounds = &adjustedBounds; 194327bb28473912181cf9a838e9282e86cb62e2d44begdaniel } 194427bb28473912181cf9a838e9282e86cb62e2d44begdaniel 194577a86f81f39227ea53441af2afc647f589a96a0dGreg Daniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, colorClear, *target, *pBounds, true); 194622bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel for (int i = 0; i < buffers.count(); ++i) { 194722bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel fCurrentCmdBuffer->executeCommands(this, buffers[i]); 194822bc8653d704584e13f35844dafb5ddeb9989127Greg Daniel } 1949164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->endRenderPass(this); 195066933552f1723c4a2b248711ab3d43921401e8e6egdaniel 1951ce3bfb1ed155880585b2d0bb0a8d3e43306e23f2egdaniel this->didWriteToSurface(target, &bounds); 1952164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 19539cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel 19546be35238855dbbc7575e78d6723936293a4b38e6Greg DanielGrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() { 195584741b308496409f4ff662658167221fc6801bbejvanverth VkFenceCreateInfo createInfo; 195684741b308496409f4ff662658167221fc6801bbejvanverth memset(&createInfo, 0, sizeof(VkFenceCreateInfo)); 195784741b308496409f4ff662658167221fc6801bbejvanverth createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 195884741b308496409f4ff662658167221fc6801bbejvanverth createInfo.pNext = nullptr; 195984741b308496409f4ff662658167221fc6801bbejvanverth createInfo.flags = 0; 196084741b308496409f4ff662658167221fc6801bbejvanverth VkFence fence = VK_NULL_HANDLE; 19616be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 19626be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel VK_CALL_ERRCHECK(CreateFence(this->device(), &createInfo, nullptr, &fence)); 19636be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel VK_CALL(QueueSubmit(this->queue(), 0, nullptr, fence)); 19646be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 19656be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GR_STATIC_ASSERT(sizeof(GrFence) >= sizeof(VkFence)); 196684741b308496409f4ff662658167221fc6801bbejvanverth return (GrFence)fence; 196784741b308496409f4ff662658167221fc6801bbejvanverth} 196884741b308496409f4ff662658167221fc6801bbejvanverth 19696be35238855dbbc7575e78d6723936293a4b38e6Greg Danielbool GrVkGpu::waitFence(GrFence fence, uint64_t timeout) { 19706be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel SkASSERT(VK_NULL_HANDLE != (VkFence)fence); 19716be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 19726be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel VkResult result = VK_CALL(WaitForFences(this->device(), 1, (VkFence*)&fence, VK_TRUE, timeout)); 197384741b308496409f4ff662658167221fc6801bbejvanverth return (VK_SUCCESS == result); 197484741b308496409f4ff662658167221fc6801bbejvanverth} 197584741b308496409f4ff662658167221fc6801bbejvanverth 197684741b308496409f4ff662658167221fc6801bbejvanverthvoid GrVkGpu::deleteFence(GrFence fence) const { 19776be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel VK_CALL(DestroyFence(this->device(), (VkFence)fence, nullptr)); 19786be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 19796be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 19806be35238855dbbc7575e78d6723936293a4b38e6Greg Danielsk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrVkGpu::makeSemaphore() { 19816be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel return GrVkSemaphore::Make(this); 19826be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 19836be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 1984dc87c95382d5beab7fdae2e654d6de568fbe1671Brian Osmanvoid GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool /*flush*/) { 19856be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get()); 19866be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 1987dc87c95382d5beab7fdae2e654d6de568fbe1671Brian Osman // We *always* flush, so ignore that parameter 19886be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue, vkSem->getResource()); 19896be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel} 19906be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 19916be35238855dbbc7575e78d6723936293a4b38e6Greg Danielvoid GrVkGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) { 19926be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get()); 19936be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel 19946be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel const GrVkSemaphore::Resource* resource = vkSem->getResource(); 19956be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel resource->ref(); 19966be35238855dbbc7575e78d6723936293a4b38e6Greg Daniel fSemaphoresToWaitOn.push_back(resource); 199784741b308496409f4ff662658167221fc6801bbejvanverth} 199813dddce65fd87a8175a209a49f35615735a2886aBrian Osman 199913dddce65fd87a8175a209a49f35615735a2886aBrian Osmansk_sp<GrSemaphore> GrVkGpu::prepareTextureForCrossContextUsage(GrTexture* texture) { 200013dddce65fd87a8175a209a49f35615735a2886aBrian Osman SkASSERT(texture); 200113dddce65fd87a8175a209a49f35615735a2886aBrian Osman GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture); 200213dddce65fd87a8175a209a49f35615735a2886aBrian Osman vkTexture->setImageLayout(this, 200313dddce65fd87a8175a209a49f35615735a2886aBrian Osman VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 200413dddce65fd87a8175a209a49f35615735a2886aBrian Osman VK_ACCESS_SHADER_READ_BIT, 200513dddce65fd87a8175a209a49f35615735a2886aBrian Osman VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 200613dddce65fd87a8175a209a49f35615735a2886aBrian Osman false); 200713dddce65fd87a8175a209a49f35615735a2886aBrian Osman this->submitCommandBuffer(kSkip_SyncQueue); 200813dddce65fd87a8175a209a49f35615735a2886aBrian Osman 200913dddce65fd87a8175a209a49f35615735a2886aBrian Osman // The image layout change serves as a barrier, so no semaphore is needed 201013dddce65fd87a8175a209a49f35615735a2886aBrian Osman return nullptr; 201113dddce65fd87a8175a209a49f35615735a2886aBrian Osman} 2012