GrVkGpu.cpp revision 8f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10
1164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/* 2164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * Copyright 2015 Google Inc. 3164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * 4164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * Use of this source code is governed by a BSD-style license that can be 5164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel * found in the LICENSE file. 6164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel */ 7164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkGpu.h" 9164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrContextOptions.h" 11164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGeometryProcessor.h" 12164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrGpuResourceCacheAccess.h" 130e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel#include "GrMesh.h" 14164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrPipeline.h" 15164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrRenderTargetPriv.h" 16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrSurfacePriv.h" 17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrTexturePriv.h" 18164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 19164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkCommandBuffer.h" 20164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkImage.h" 21164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkIndexBuffer.h" 22164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkMemory.h" 23164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkPipeline.h" 2422281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel#include "GrVkPipelineState.h" 25164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkRenderPass.h" 26164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkResourceProvider.h" 27164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h" 28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTextureRenderTarget.h" 29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTransferBuffer.h" 30164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkVertexBuffer.h" 31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "SkConfig8888.h" 33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 34164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vk/GrVkInterface.h" 35fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth#include "vk/GrVkTypes.h" 36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 37164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X) 38164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) 39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) 40164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 41d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#ifdef ENABLE_VK_LAYERS 42d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverthVKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( 43d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportFlagsEXT flags, 44d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportObjectTypeEXT objectType, 45d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth uint64_t object, 46d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth size_t location, 47d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth int32_t messageCode, 48d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth const char* pLayerPrefix, 49d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth const char* pMessage, 50d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth void* pUserData) { 51d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { 52d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 53d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { 54d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 55d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { 56d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 57d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } else { 58d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth SkDebugf("Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage); 59d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } 60d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth return VK_FALSE; 61d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth} 62d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 63d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth 64633b35657c964c32e7010b14bb2d396b4a764c52jvanverthGrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options, 65633b35657c964c32e7010b14bb2d396b4a764c52jvanverth GrContext* context) { 66633b35657c964c32e7010b14bb2d396b4a764c52jvanverth SkAutoTUnref<const GrVkBackendContext> vkBackendContext( 67633b35657c964c32e7010b14bb2d396b4a764c52jvanverth reinterpret_cast<const GrVkBackendContext*>(backendContext)); 68633b35657c964c32e7010b14bb2d396b4a764c52jvanverth if (!vkBackendContext) { 69633b35657c964c32e7010b14bb2d396b4a764c52jvanverth vkBackendContext.reset(GrVkBackendContext::Create()); 70633b35657c964c32e7010b14bb2d396b4a764c52jvanverth if (!vkBackendContext) { 71633b35657c964c32e7010b14bb2d396b4a764c52jvanverth return nullptr; 72164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 73633b35657c964c32e7010b14bb2d396b4a764c52jvanverth } else { 74633b35657c964c32e7010b14bb2d396b4a764c52jvanverth vkBackendContext->ref(); 75164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 76164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 77633b35657c964c32e7010b14bb2d396b4a764c52jvanverth return new GrVkGpu(context, options, vkBackendContext); 78164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 79164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 80164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 81164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 829d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanaryGrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, 83633b35657c964c32e7010b14bb2d396b4a764c52jvanverth const GrVkBackendContext* backendCtx) 84164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : INHERITED(context) 85633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fVkInstance(backendCtx->fInstance) 86633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fDevice(backendCtx->fDevice) 87633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fQueue(backendCtx->fQueue) 88633b35657c964c32e7010b14bb2d396b4a764c52jvanverth , fResourceProvider(this) { 89633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fBackendContext.reset(backendCtx); 90164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 91d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#ifdef ENABLE_VK_LAYERS 92fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth if (backendCtx->fExtensions & kEXT_debug_report_GrVkExtensionFlag) { 93fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth // Setup callback creation information 94d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; 95d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 96d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pNext = nullptr; 97d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | 98d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VK_DEBUG_REPORT_WARNING_BIT_EXT | 99d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth //VK_DEBUG_REPORT_INFORMATION_BIT_EXT | 100d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth //VK_DEBUG_REPORT_DEBUG_BIT_EXT | 101d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; 102d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pfnCallback = &DebugReportCallback; 103d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth callbackCreateInfo.pUserData = nullptr; 104d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth 105fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth // Register the callback 106633b35657c964c32e7010b14bb2d396b4a764c52jvanverth GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateDebugReportCallbackEXT(fVkInstance, 107633b35657c964c32e7010b14bb2d396b4a764c52jvanverth &callbackCreateInfo, nullptr, &fCallback)); 108d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth } 109d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 110633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 111633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCompiler = shaderc_compiler_initialize(); 112633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 113fd7bd45ac2178ce6b4a390f517f605750aaef6c8jvanverth fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice, 114c5ec1408298510410270ea67e895570ccfa76e54egdaniel backendCtx->fFeatures, backendCtx->fExtensions)); 115633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCaps.reset(SkRef(fVkCaps.get())); 116633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 117633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps)); 118633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 119633b35657c964c32e7010b14bb2d396b4a764c52jvanverth const VkCommandPoolCreateInfo cmdPoolInfo = { 120633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType 121633b35657c964c32e7010b14bb2d396b4a764c52jvanverth nullptr, // pNext 122633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // CmdPoolCreateFlags 123633b35657c964c32e7010b14bb2d396b4a764c52jvanverth backendCtx->fQueueFamilyIndex, // queueFamilyIndex 124633b35657c964c32e7010b14bb2d396b4a764c52jvanverth }; 1259d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateCommandPool(fDevice, &cmdPoolInfo, nullptr, 126633b35657c964c32e7010b14bb2d396b4a764c52jvanverth &fCmdPool)); 127633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 128633b35657c964c32e7010b14bb2d396b4a764c52jvanverth // must call this after creating the CommandPool 129633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fResourceProvider.init(); 130633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCurrentCmdBuffer = fResourceProvider.createCommandBuffer(); 131633b35657c964c32e7010b14bb2d396b4a764c52jvanverth SkASSERT(fCurrentCmdBuffer); 132633b35657c964c32e7010b14bb2d396b4a764c52jvanverth fCurrentCmdBuffer->begin(this); 133164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 135164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkGpu::~GrVkGpu() { 136164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 138164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 139164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // wait for all commands to finish 140ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth fResourceProvider.checkCommandBuffers(); 1412cab66be9c47660da6a2cc94b469c14d5bed958eegdaniel SkDEBUGCODE(VkResult res =) VK_CALL(QueueWaitIdle(fQueue)); 142ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth // VK_ERROR_DEVICE_LOST is acceptable when tearing down (see 4.2.4 in spec) 143ddf9835e9cdf512b1d5172d014f00ceb6dacd039jvanverth SkASSERT(VK_SUCCESS == res || VK_ERROR_DEVICE_LOST == res); 1449d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // must call this just before we destroy the VkDevice 146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fResourceProvider.destroyResources(); 147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 148633b35657c964c32e7010b14bb2d396b4a764c52jvanverth VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); 149633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 150633b35657c964c32e7010b14bb2d396b4a764c52jvanverth shaderc_compiler_release(fCompiler); 151633b35657c964c32e7010b14bb2d396b4a764c52jvanverth 152633b35657c964c32e7010b14bb2d396b4a764c52jvanverth#ifdef ENABLE_VK_LAYERS 153d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth VK_CALL(DestroyDebugReportCallbackEXT(fVkInstance, fCallback, nullptr)); 154d2497f35ce9e9e70ab6c7acd82b212c80cb86d3ajvanverth#endif 155164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 156164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::submitCommandBuffer(SyncQueue sync) { 160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->submitToQueue(this, fQueue, sync); 164164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fResourceProvider.checkCommandBuffers(); 165164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Release old command buffer and create a new one 167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer = fResourceProvider.createCommandBuffer(); 169164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 170164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 171164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->begin(this); 172164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 173164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 174164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 175397536cabe12a9936659870dd220c869789424bacdaltonGrBuffer* GrVkGpu::onCreateBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) { 176397536cabe12a9936659870dd220c869789424bacdalton switch (type) { 177397536cabe12a9936659870dd220c869789424bacdalton case kVertex_GrBufferType: 178397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kDynamic_GrAccessPattern == accessPattern || 179397536cabe12a9936659870dd220c869789424bacdalton kStatic_GrAccessPattern == accessPattern); 180397536cabe12a9936659870dd220c869789424bacdalton return GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); 181397536cabe12a9936659870dd220c869789424bacdalton case kIndex_GrBufferType: 182397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kDynamic_GrAccessPattern == accessPattern || 183397536cabe12a9936659870dd220c869789424bacdalton kStatic_GrAccessPattern == accessPattern); 184397536cabe12a9936659870dd220c869789424bacdalton return GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); 185397536cabe12a9936659870dd220c869789424bacdalton case kXferCpuToGpu_GrBufferType: 186397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kStream_GrAccessPattern == accessPattern); 187397536cabe12a9936659870dd220c869789424bacdalton return GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type); 188397536cabe12a9936659870dd220c869789424bacdalton case kXferGpuToCpu_GrBufferType: 189397536cabe12a9936659870dd220c869789424bacdalton SkASSERT(kStream_GrAccessPattern == accessPattern); 190397536cabe12a9936659870dd220c869789424bacdalton return GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type); 191397536cabe12a9936659870dd220c869789424bacdalton default: 192397536cabe12a9936659870dd220c869789424bacdalton SkFAIL("Unknown buffer type."); 193397536cabe12a9936659870dd220c869789424bacdalton return nullptr; 194397536cabe12a9936659870dd220c869789424bacdalton } 195164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 196164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 197164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 198164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 199164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig srcConfig, DrawPreference* drawPreference, 200164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel WritePixelTempDrawInfo* tempDrawInfo) { 201164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurface->config())) { 202164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 203164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 204164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Currently we don't handle draws, so if the caller wants/needs to do a draw we need to fail 206164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kNoDraw_DrawPreference != *drawPreference) { 207164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 209164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 210164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (dstSurface->config() != srcConfig) { 2119d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary // TODO: This should fall back to drawing or copying to change config of dstSurface to 212164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // match that of srcConfig. 213164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 214164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 215164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 216164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onWritePixels(GrSurface* surface, 220164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 221a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon GrPixelConfig config, 222a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon const SkTArray<GrMipLevel>& texels) { 223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture()); 224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!vkTex) { 225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 226164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 227164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 228a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon // TODO: We're ignoring MIP levels here. 22903509eafa3e25819ff69f4d4f339d46264820c38jvanverth if (texels.empty() || !texels.begin()->fPixels) { 23003509eafa3e25819ff69f4d4f339d46264820c38jvanverth return false; 23103509eafa3e25819ff69f4d4f339d46264820c38jvanverth } 232a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon 233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels. 234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 238164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool success = false; 239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) { 240164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo() 241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(config == vkTex->desc().fConfig); 242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: add compressed texture support 243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // delete the following two lines and uncomment the two after that when ready 244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->unref(); 245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false, left, top, width, 247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // height); 248164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = vkTex->isLinearTiled(); 250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling && VK_IMAGE_LAYOUT_PREINITIALIZED != vkTex->currentLayout()) { 251164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Need to change the layout to general in order to perform a host write 252164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = vkTex->currentLayout(); 253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_HOST_BIT; 255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_HOST_WRITE_BIT; 257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->setImageLayout(this, 258164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_GENERAL, 259164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 260164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 262164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel success = this->uploadTexData(vkTex, left, top, width, height, config, 266a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon texels.begin()->fPixels, texels.begin()->fRowBytes); 267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (success) { 270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->texturePriv().dirtyMipMaps(true); 271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::uploadTexData(GrVkTexture* tex, 278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig dataConfig, 280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const void* data, 281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 282164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(data); 283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If we're uploading compressed data then we should be using uploadCompressedTexData 285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = tex->isLinearTiled(); 288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 289164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t bpp = GrBytesPerPixel(dataConfig); 290164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 291164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurfaceDesc& desc = tex->desc(); 292164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 293164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 294164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &width, &height, &data, &rowBytes)) { 295164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 296164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 297164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t trimRowBytes = width * bpp; 298164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 299164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling) { 300164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == tex->currentLayout() || 301164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_GENERAL == tex->currentLayout()); 302164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkImageSubresource subres = { 303164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_ASPECT_COLOR_BIT, 304164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // mipLevel 305164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // arraySlice 306164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 307164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkSubresourceLayout layout; 308164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkResult err; 309164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 310164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkInterface* interface = this->vkInterface(); 311164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 312164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice, 313164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->textureImage(), 314164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &subres, 315164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &layout)); 316164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 317164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int texTop = kBottomLeft_GrSurfaceOrigin == desc.fOrigin ? tex->height() - top - height 318164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : top; 319164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDeviceSize offset = texTop*layout.rowPitch + left*bpp; 320164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDeviceSize size = height*layout.rowPitch; 321164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mapPtr; 3229d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary err = GR_VK_CALL(interface, MapMemory(fDevice, tex->textureMemory(), offset, size, 0, 323164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &mapPtr)); 324164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 325164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 326164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 327164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 328164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 329164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // copy into buffer by rows 330164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const char* srcRow = reinterpret_cast<const char*>(data); 331164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*layout.rowPitch; 332164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int y = 0; y < height; y++) { 333164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(dstRow, srcRow, trimRowBytes); 334164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcRow += rowBytes; 335164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstRow -= layout.rowPitch; 336164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 337164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If there is no padding on the src (rowBytes) or dst (layout.rowPitch) we can memcpy 339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (trimRowBytes == rowBytes && trimRowBytes == layout.rowPitch) { 340164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(mapPtr, data, trimRowBytes * height); 341164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 342a6b439a0af614e2e79b35ad41df7b72736d5d1b9bsalomon SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, 343a6b439a0af614e2e79b35ad41df7b72736d5d1b9bsalomon trimRowBytes, height); 344164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 345164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 346164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 347164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(interface, UnmapMemory(fDevice, tex->textureMemory())); 348164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 349164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTransferBuffer* transferBuffer = 350164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTransferBuffer::Create(this, trimRowBytes * height, GrVkBuffer::kCopyRead_Type); 351164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 352164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mapPtr = transferBuffer->map(); 353164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 354164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 355164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // copy into buffer by rows 356164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const char* srcRow = reinterpret_cast<const char*>(data); 357164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*trimRowBytes; 358164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int y = 0; y < height; y++) { 359164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(dstRow, srcRow, trimRowBytes); 360164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcRow += rowBytes; 361164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstRow -= trimRowBytes; 362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 363164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 364164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If there is no padding on the src data rows, we can do a single memcpy 365164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (trimRowBytes == rowBytes) { 366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(mapPtr, data, trimRowBytes * height); 367164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 368164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkRectMemcpy(mapPtr, trimRowBytes, data, rowBytes, trimRowBytes, height); 369164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 372164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unmap(); 373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 374164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // make sure the unmap has finished 375164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->addMemoryBarrier(this, 376164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_WRITE_BIT, 377164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_TRANSFER_READ_BIT, 378164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 379164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 382164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Set up copy region 383164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool flipY = kBottomLeft_GrSurfaceOrigin == tex->origin(); 384164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkOffset3D offset = { 385164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel left, 386164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel flipY ? tex->height() - top - height : top, 387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0 388164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferImageCopy region; 391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferOffset = 0; 393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferRowLength = width; 394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferImageHeight = height; 395164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 396164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageOffset = offset; 397164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 398164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 399164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our target so it can be copied to 400164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = tex->currentLayout(); 401164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 402164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 403164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 404164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 405164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->setImageLayout(this, 406164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 407164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 408164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 409164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 410164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 411164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 413164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Copy the buffer to the image 414164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyBufferToImage(this, 415164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer, 416164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex, 417164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 419164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ®ion); 420164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 421164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Submit the current command buffer to the Queue 422164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 423164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unref(); 425164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 426164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 427164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 428164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 429164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 430164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 431164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle, 432a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon const SkTArray<GrMipLevel>& texels) { 433164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 434164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 435164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 436164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) { 437164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 438164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 439164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 440164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(desc.fConfig)) { 441164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 442164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 443164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 444164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 445164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (SkToBool(desc.fFlags & kZeroCopy_GrSurfaceFlag)) { 446164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVkCaps->isConfigTexurableLinearly(desc.fConfig) && 447164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel (!renderTarget || fVkCaps->isConfigRenderableLinearly(desc.fConfig, false))) { 448164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 449164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 450164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 451164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 452164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 453164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 454164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 455164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 456164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 457164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 458164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 459164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and 460164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we 461164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // will be using this texture in some copy or not. Also this assumes, as is the current case, 462164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // that all render targets in vulkan are also texutres. If we change this practice of setting 463164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // both bits, we must make sure to set the destination bit if we are uploading srcData to the 464164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // texture. 465164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 466164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 467a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon VkFlags memProps = (!texels.empty() && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : 468a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 469164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 470164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is 471164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // requested, this ImageDesc describes the resolved texutre. Therefore we always have samples set 472164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // to 1. 473164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::ImageDesc imageDesc; 474164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageType = VK_IMAGE_TYPE_2D; 475164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fFormat = pixelFormat; 476164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fWidth = desc.fWidth; 477164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fHeight = desc.fHeight; 478164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fLevels = 1; 479164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fSamples = 1; 480164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 481164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fUsageFlags = usageFlags; 482164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fMemProps = memProps; 483164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 484164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* tex; 485164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 486164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc, lifeCycle, 487164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc); 488164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 489164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc); 490164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 491164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 492164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!tex) { 493164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 494164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 495164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 496a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon // TODO: We're ignoring MIP levels here. 497e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon if (!texels.empty()) { 498e699d0cd25fd059e3f0c4949e613e50c83a52179bsalomon SkASSERT(texels.begin()->fPixels); 499a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon if (!this->uploadTexData(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 500a1e6b3be8124cef85f2e39e3cb85000ad9526d48bsalomon texels.begin()->fPixels, texels.begin()->fRowBytes)) { 501164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->unref(); 502164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 503164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 504164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 505164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 506164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tex; 507164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 508164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 509164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 510164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 511164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) { 512164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // By default, all textures in Vk use TopLeft 513164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kDefault_GrSurfaceOrigin == origin) { 514164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return kTopLeft_GrSurfaceOrigin; 515164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 516164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return origin; 517164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 518164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 519164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 520164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc, 521164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrWrapOwnership ownership) { 522164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat format; 523164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(desc.fConfig, &format)) { 524164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 525164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 526164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 527164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (0 == desc.fTextureHandle) { 528164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 529164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 530164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 531164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int maxSize = this->caps()->maxTextureSize(); 532164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 533164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 534164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 535164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 536fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const GrVkTextureInfo* info = reinterpret_cast<const GrVkTextureInfo*>(desc.fTextureHandle); 537fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (VK_NULL_HANDLE == info->fImage || VK_NULL_HANDLE == info->fAlloc) { 538fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return nullptr; 539fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 540164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 5410fcfb7525f60eabfdaf9761c75c7d4fd1b46d0c5jvanverth GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership) 5420fcfb7525f60eabfdaf9761c75c7d4fd1b46d0c5jvanverth ? GrGpuResource::kAdopted_LifeCycle 5430fcfb7525f60eabfdaf9761c75c7d4fd1b46d0c5jvanverth : GrGpuResource::kBorrowed_LifeCycle; 544164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 545164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc surfDesc; 546164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // next line relies on GrBackendTextureDesc's flags matching GrTexture's 547164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags; 548164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fWidth = desc.fWidth; 549164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fHeight = desc.fHeight; 550164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fConfig = desc.fConfig; 551164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()); 552164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag); 553164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In GL, Chrome assumes all textures are BottomLeft 554164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In VK, we don't have this restriction 555164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fOrigin = resolve_origin(desc.fOrigin); 556164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 557164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* texture = nullptr; 558164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 5599d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary texture = GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(this, surfDesc, 560164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle, format, 561fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info); 562164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 5639d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, format, 564fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info); 565164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 566164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!texture) { 567164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 568164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 569164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 570164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return texture; 571164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 572164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 573164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc, 574164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrWrapOwnership ownership) { 5759d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 576fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const GrVkTextureInfo* info = 577fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth reinterpret_cast<const GrVkTextureInfo*>(wrapDesc.fRenderTargetHandle); 578fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (VK_NULL_HANDLE == info->fImage || 579fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth (VK_NULL_HANDLE == info->fAlloc && kAdopt_GrWrapOwnership == ownership)) { 580fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return nullptr; 581fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 582164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 5830fcfb7525f60eabfdaf9761c75c7d4fd1b46d0c5jvanverth GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership) 5840fcfb7525f60eabfdaf9761c75c7d4fd1b46d0c5jvanverth ? GrGpuResource::kAdopted_LifeCycle 5850fcfb7525f60eabfdaf9761c75c7d4fd1b46d0c5jvanverth : GrGpuResource::kBorrowed_LifeCycle; 586164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 587164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc desc; 588164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fConfig = wrapDesc.fConfig; 589164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fFlags = kCheckAllocation_GrSurfaceFlag; 590164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fWidth = wrapDesc.fWidth; 591164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fHeight = wrapDesc.fHeight; 592164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()); 593164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 594164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fOrigin = resolve_origin(wrapDesc.fOrigin); 595164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 596164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkRenderTarget* tgt = GrVkRenderTarget::CreateWrappedRenderTarget(this, desc, 5979d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary lifeCycle, 598fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info); 599164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (tgt && wrapDesc.fStencilBits) { 600164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeight)) { 601164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tgt->unref(); 602164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 603164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 604164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 605164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tgt; 606164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 607164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 608164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 609164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 610164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, 6110e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrNonInstancedMesh& mesh) { 612164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkVertexBuffer* vbuf; 6130e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer(); 614164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(vbuf); 615164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!vbuf->isMapped()); 616164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 617164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vbuf->addMemoryBarrier(this, 618164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_WRITE_BIT, 619164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, 620164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 621164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 622164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 623164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 624164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->bindVertexBuffer(this, vbuf); 625164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 6260e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (mesh.isIndexed()) { 6270e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer(); 628164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(ibuf); 629164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!ibuf->isMapped()); 630164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 631164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ibuf->addMemoryBarrier(this, 632164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_WRITE_BIT, 633164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_INDEX_READ_BIT, 634164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 635164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 636164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 637164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 638164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->bindIndexBuffer(this, ibuf); 639164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 640164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 641164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 642164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 643164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 644164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 645164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int width, 646164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int height) { 647164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(rt->asTexture()); 648164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(width >= rt->width()); 649164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(height >= rt->height()); 650164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 651164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int samples = rt->numStencilSamples(); 652164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 6538f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10egdaniel const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat(); 654164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 655164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this, 656164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrGpuResource::kCached_LifeCycle, 657164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel width, 658164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel height, 659164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel samples, 660164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel sFmt)); 661164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fStats.incStencilAttachmentCreates(); 662164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return stencil; 663164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 666164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 667164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h, 668164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config) { 669164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 670164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 671164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 672164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 673164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 674164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 675164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 676164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(config)) { 677164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 678164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 679164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 680164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVkCaps->isConfigTexurableLinearly(config)) { 681164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 682164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 683164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 684164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Currently this is not supported since it requires a copy which has not yet been implemented. 685164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcData && !linearTiling) { 686164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 687164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 688164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 689164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 690164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 691164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 692164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 693164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFlags memProps = (srcData && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : 694164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 695164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 696fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImage image = VK_NULL_HANDLE; 697fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkDeviceMemory alloc = VK_NULL_HANDLE; 698164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 699fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImageTiling imageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 700fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkImageLayout initialLayout = (VK_IMAGE_TILING_LINEAR == imageTiling) 701fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth ? VK_IMAGE_LAYOUT_PREINITIALIZED 702fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth : VK_IMAGE_LAYOUT_UNDEFINED; 703fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 704fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth // Create Image 705fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VkSampleCountFlagBits vkSamples; 706fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (!GrSampleCountToVkSampleCount(1, &vkSamples)) { 707fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return 0; 708fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth } 709fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 710fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const VkImageCreateInfo imageCreateInfo = { 711fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 712fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth NULL, // pNext 713fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // VkImageCreateFlags 714fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_IMAGE_TYPE_2D, // VkImageType 715fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth pixelFormat, // VkFormat 716384b5e9cd36e443437de8df3b0f78ef4150efbacethannicholas { (uint32_t) w, (uint32_t) h, 1 }, // VkExtent3D 717fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1, // mipLevels 718fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 1, // arrayLayers 719fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth vkSamples, // samples 720fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth imageTiling, // VkImageTiling 721fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth usageFlags, // VkImageUsageFlags 722fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode 723fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // queueFamilyCount 724fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 0, // pQueueFamilyIndices 725fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth initialLayout // initialLayout 726fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth }; 727fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 728fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image)); 729fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 730fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth if (!GrVkMemory::AllocAndBindImageMemory(this, image, memProps, &alloc)) { 731fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(DestroyImage(this->device(), image, nullptr)); 732164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 733164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 734164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 735164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcData) { 736164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling) { 737164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkImageSubresource subres = { 738164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_ASPECT_COLOR_BIT, 739164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // mipLevel 740164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // arraySlice 741164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 742164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkSubresourceLayout layout; 743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkResult err; 744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 745fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(GetImageSubresourceLayout(fDevice, image, &subres, &layout)); 746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mapPtr; 748fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth err = VK_CALL(MapMemory(fDevice, alloc, 0, layout.rowPitch * h, 0, &mapPtr)); 749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 750fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(FreeMemory(this->device(), alloc, nullptr)); 751fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(DestroyImage(this->device(), image, nullptr)); 752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 754164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t bpp = GrBytesPerPixel(config); 756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowCopyBytes = bpp * w; 757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If there is no padding on dst (layout.rowPitch) we can do a single memcopy. 758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This assumes the srcData comes in with no padding. 759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (rowCopyBytes == layout.rowPitch) { 760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(mapPtr, srcData, rowCopyBytes * h); 761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 762fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), srcData, rowCopyBytes, 763fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth rowCopyBytes, h); 764164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 765fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(UnmapMemory(fDevice, alloc)); 766164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 767164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: Add support for copying to optimal tiling 768164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(false); 769164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 770164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 771164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 772fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth GrVkTextureInfo* info = new GrVkTextureInfo; 773fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImage = image; 774fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fAlloc = alloc; 775fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImageTiling = imageTiling; 776fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth info->fImageLayout = initialLayout; 777fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 778fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth return (GrBackendObject)info; 779164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 780164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 781164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { 782fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const GrVkTextureInfo* backend = reinterpret_cast<const GrVkTextureInfo*>(id); 783164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 784164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (backend && backend->fImage && backend->fAlloc) { 785164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryRequirements req; 786164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&req, 0, sizeof(req)); 787164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, 788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel backend->fImage, 789164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &req)); 790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: find a better check 791164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This will probably fail with a different driver 792164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return (req.size > 0) && (req.size <= 8192 * 8192); 793164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 794164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 795164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 796164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 797164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 798164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) { 799fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth const GrVkTextureInfo* backend = reinterpret_cast<const GrVkTextureInfo*>(id); 800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 801164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (backend) { 802164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!abandon) { 803fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth // something in the command buffer may still be using this, so force submit 804fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth this->submitCommandBuffer(kForce_SyncQueue); 805fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth 806fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(FreeMemory(this->device(), backend->fAlloc, nullptr)); 807fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth VK_CALL(DestroyImage(this->device(), backend->fImage, nullptr)); 808164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 809fd359caf0cbdefd759d1c788d72faba3f65a6386jvanverth delete backend; 810164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 811164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 812164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 813164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 814164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 815164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask, 816164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 817164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 818164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryBarrier* barrier) const { 819164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 820164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 821164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 822164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 823164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 824164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kMemory_BarrierType, 825164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 826164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 827164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 828164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addBufferMemoryBarrier(VkPipelineStageFlags srcStageMask, 829164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 830164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 831164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferMemoryBarrier* barrier) const { 832164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 833164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 834164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 835164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 836164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 837164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kBufferMemory_BarrierType, 838164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 839164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 840164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 841164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask, 842164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 843164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 844164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageMemoryBarrier* barrier) const { 845164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 846164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 847164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 848164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 849164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 850164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kImageMemory_BarrierType, 851164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 852164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 853164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 854164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::finishDrawTarget() { 855164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Submit the current command buffer to the Queue 856164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 857164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 858164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 8593d5d9ac426ea926f37eaa47e13acf7492068667begdanielvoid GrVkGpu::clearStencil(GrRenderTarget* target) { 8603d5d9ac426ea926f37eaa47e13acf7492068667begdaniel if (nullptr == target) { 8613d5d9ac426ea926f37eaa47e13acf7492068667begdaniel return; 8623d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 8633d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrStencilAttachment* stencil = target->renderTargetPriv().getStencilAttachment(); 8643d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; 8653d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8663d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8673d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkClearDepthStencilValue vkStencilColor; 8683d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); 8693d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8703d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkImageLayout origDstLayout = vkStencil->currentLayout(); 8713d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8723d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 8733d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 8743d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8753d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout);; 8763d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 8773d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8783d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencil->setImageLayout(this, 8793d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 8803d5d9ac426ea926f37eaa47e13acf7492068667begdaniel srcAccessMask, 8813d5d9ac426ea926f37eaa47e13acf7492068667begdaniel dstAccessMask, 8823d5d9ac426ea926f37eaa47e13acf7492068667begdaniel srcStageMask, 8833d5d9ac426ea926f37eaa47e13acf7492068667begdaniel dstStageMask, 8843d5d9ac426ea926f37eaa47e13acf7492068667begdaniel false); 8853d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8863d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8873d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkImageSubresourceRange subRange; 8883d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&subRange, 0, sizeof(VkImageSubresourceRange)); 8893d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 8903d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.baseMipLevel = 0; 8913d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.levelCount = 1; 8923d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.baseArrayLayer = 0; 8933d5d9ac426ea926f37eaa47e13acf7492068667begdaniel subRange.layerCount = 1; 8943d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 8953d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // TODO: I imagine that most times we want to clear a stencil it will be at the beginning of a 8963d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // draw. Thus we should look into using the load op functions on the render pass to clear out 8973d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // the stencil there. 8983d5d9ac426ea926f37eaa47e13acf7492068667begdaniel fCurrentCmdBuffer->clearDepthStencilImage(this, vkStencil, &vkStencilColor, 1, &subRange); 8993d5d9ac426ea926f37eaa47e13acf7492068667begdaniel} 9003d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9013d5d9ac426ea926f37eaa47e13acf7492068667begdanielvoid GrVkGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) { 9023d5d9ac426ea926f37eaa47e13acf7492068667begdaniel SkASSERT(target); 9033d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9043d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); 9053d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); 9063d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)sb; 9073d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9083d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // this should only be called internally when we know we have a 9093d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // stencil buffer. 9103d5d9ac426ea926f37eaa47e13acf7492068667begdaniel SkASSERT(sb); 9113d5d9ac426ea926f37eaa47e13acf7492068667begdaniel int stencilBitCount = sb->bits(); 9123d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9133d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // The contract with the callers does not guarantee that we preserve all bits in the stencil 9143d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // during this clear. Thus we will clear the entire stencil to the desired value. 9153d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9163d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkClearDepthStencilValue vkStencilColor; 9173d5d9ac426ea926f37eaa47e13acf7492068667begdaniel memset(&vkStencilColor, 0, sizeof(VkClearDepthStencilValue)); 9183d5d9ac426ea926f37eaa47e13acf7492068667begdaniel if (insideClip) { 9193d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencilColor.stencil = (1 << (stencilBitCount - 1)); 9203d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } else { 9213d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencilColor.stencil = 0; 9223d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 9233d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9243d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkImageLayout origDstLayout = vkStencil->currentLayout(); 9253d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout); 9263d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 9273d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkPipelineStageFlags srcStageMask = 9283d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 9293d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 9303d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencil->setImageLayout(this, 9313d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 9323d5d9ac426ea926f37eaa47e13acf7492068667begdaniel srcAccessMask, 9333d5d9ac426ea926f37eaa47e13acf7492068667begdaniel dstAccessMask, 9343d5d9ac426ea926f37eaa47e13acf7492068667begdaniel srcStageMask, 9353d5d9ac426ea926f37eaa47e13acf7492068667begdaniel dstStageMask, 9363d5d9ac426ea926f37eaa47e13acf7492068667begdaniel false); 9373d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9383d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkClearRect clearRect; 9393d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // Flip rect if necessary 9403d5d9ac426ea926f37eaa47e13acf7492068667begdaniel SkIRect vkRect = rect; 9413d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9423d5d9ac426ea926f37eaa47e13acf7492068667begdaniel if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) { 9433d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkRect.fTop = vkRT->height() - rect.fBottom; 9443d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkRect.fBottom = vkRT->height() - rect.fTop; 9453d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 9463d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9473d5d9ac426ea926f37eaa47e13acf7492068667begdaniel clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; 9483d5d9ac426ea926f37eaa47e13acf7492068667begdaniel clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; 9493d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9503d5d9ac426ea926f37eaa47e13acf7492068667begdaniel clearRect.baseArrayLayer = 0; 9513d5d9ac426ea926f37eaa47e13acf7492068667begdaniel clearRect.layerCount = 1; 9523d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9533d5d9ac426ea926f37eaa47e13acf7492068667begdaniel const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 9543d5d9ac426ea926f37eaa47e13acf7492068667begdaniel SkASSERT(renderPass); 9553d5d9ac426ea926f37eaa47e13acf7492068667begdaniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); 9563d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9573d5d9ac426ea926f37eaa47e13acf7492068667begdaniel uint32_t stencilIndex; 9583d5d9ac426ea926f37eaa47e13acf7492068667begdaniel SkAssertResult(renderPass->stencilAttachmentIndex(&stencilIndex)); 9593d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9603d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkClearAttachment attachment; 9613d5d9ac426ea926f37eaa47e13acf7492068667begdaniel attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 9623d5d9ac426ea926f37eaa47e13acf7492068667begdaniel attachment.colorAttachment = 0; // this value shouldn't matter 9633d5d9ac426ea926f37eaa47e13acf7492068667begdaniel attachment.clearValue.depthStencil = vkStencilColor; 9643d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9653d5d9ac426ea926f37eaa47e13acf7492068667begdaniel fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect); 9663d5d9ac426ea926f37eaa47e13acf7492068667begdaniel fCurrentCmdBuffer->endRenderPass(this); 9673d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 9683d5d9ac426ea926f37eaa47e13acf7492068667begdaniel return; 9693d5d9ac426ea926f37eaa47e13acf7492068667begdaniel} 9703d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 971164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color) { 972164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // parent class should never let us get here with no RT 973164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(target); 974164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 975164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkClearColorValue vkColor; 976164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrColorToRGBAFloat(color, vkColor.float32); 9779d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 978164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); 979164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout origDstLayout = vkRT->currentLayout(); 980164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 981164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (rect.width() != target->width() || rect.height() != target->height()) { 982164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout); 983164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 984164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = 9853d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 986164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 987164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT->setImageLayout(this, 988164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 989164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 990164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 991164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 992164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 993164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 994164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 995164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkClearRect clearRect; 9963d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // Flip rect if necessary 9973d5d9ac426ea926f37eaa47e13acf7492068667begdaniel SkIRect vkRect = rect; 9983d5d9ac426ea926f37eaa47e13acf7492068667begdaniel if (kBottomLeft_GrSurfaceOrigin == vkRT->origin()) { 9993d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkRect.fTop = vkRT->height() - rect.fBottom; 10003d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkRect.fBottom = vkRT->height() - rect.fTop; 10013d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 10023d5d9ac426ea926f37eaa47e13acf7492068667begdaniel clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop }; 10033d5d9ac426ea926f37eaa47e13acf7492068667begdaniel clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() }; 1004e77875aa425d51cc8db3463343a6308f9d2aadccjvanverth clearRect.baseArrayLayer = 0; 1005e77875aa425d51cc8db3463343a6308f9d2aadccjvanverth clearRect.layerCount = 1; 1006164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1007164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 1008164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(renderPass); 1009164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); 1010164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1011164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t colorIndex; 1012164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkAssertResult(renderPass->colorAttachmentIndex(&colorIndex)); 1013164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1014164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkClearAttachment attachment; 1015164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1016164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel attachment.colorAttachment = colorIndex; 1017164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel attachment.clearValue.color = vkColor; 1018164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1019164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect); 1020164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->endRenderPass(this); 1021164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return; 1022164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1023164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1024164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 1025164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 1026164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1027164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout);; 1028164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1029164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1030164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT->setImageLayout(this, 1031164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1032164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1033164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1034164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1035164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1036164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1037164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1038164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1039164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageSubresourceRange subRange; 1040164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&subRange, 0, sizeof(VkImageSubresourceRange)); 1041164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1042164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.baseMipLevel = 0; 1043164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.levelCount = 1; 1044164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.baseArrayLayer = 0; 1045164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.layerCount = 1; 1046164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 10479d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary // In the future we may not actually be doing this type of clear at all. If we are inside a 1048164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // render pass or doing a non full clear then we will use CmdClearColorAttachment. The more 1049164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // common use case will be clearing an attachment at the start of a render pass, in which case 1050164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // we will use the clear load ops. 1051164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->clearColorImage(this, 1052164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT, 1053164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &vkColor, 1054164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, &subRange); 1055164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1056164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1057164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_image(const GrSurface* dst, 1058164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 1059164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 1060164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (src->asTexture() && 1061164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dst->asTexture() && 1062164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel src->origin() == dst->origin() && 1063164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel src->config() == dst->config()) { 1064164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1065164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1066164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1067164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // How does msaa play into this? If a VkTexture is multisampled, are we copying the multisampled 1068164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // or the resolved image here? 1069164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1070164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1071164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1072164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1073164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, 1074164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1075164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1076164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1077164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(can_copy_image(dst, src, this)); 1078164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1079164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Insert memory barriers to switch src and dst to transfer_source and transfer_dst layouts 1080164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* dstTex = static_cast<GrVkTexture*>(dst->asTexture()); 1081164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* srcTex = static_cast<GrVkTexture*>(src->asTexture()); 1082164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1083164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout origDstLayout = dstTex->currentLayout(); 1084164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout origSrcLayout = srcTex->currentLayout(); 1085164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1086164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 1087164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 1088164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1089164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // These flags are for flushing/invalidating caches and for the dst image it doesn't matter if 1090164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // the cache is flushed since it is only being written to. 1091164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout);; 1092164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 10939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 1094164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstTex->setImageLayout(this, 1095164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1096164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1097164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1098164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1099164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 11019d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 1102164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origSrcLayout); 1103164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 1104164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1105164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origSrcLayout); 1106164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 1107164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1108164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcTex->setImageLayout(this, 1109164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1110164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1111164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1112164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1113164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1114164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1115164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1116164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Flip rect if necessary 1117164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkIRect srcVkRect = srcRect; 1118164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int32_t dstY = dstPoint.fY; 1119164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1120164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 1121164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); 1122164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fTop = src->height() - srcRect.fBottom; 1123164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fBottom = src->height() - srcRect.fTop; 1124164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstY = dst->height() - dstPoint.fY - srcVkRect.height(); 1125164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1126164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1127164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageCopy copyRegion; 1128164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(©Region, 0, sizeof(VkImageCopy)); 1129164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1130164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 1131164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1132164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstOffset = { dstPoint.fX, dstY, 0 }; 1133164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 0 }; 1134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1135164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImage(this, 1136164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcTex, 1137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1138164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstTex, 1139164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1140164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1141164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ©Region); 1142164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1143164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1144164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_as_draw(const GrSurface* dst, 1145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 1146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 1147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1148164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1149164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1150164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsDraw(GrSurface* dst, 1151164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1152164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1153164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1154164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(false); 1155164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1156164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onCopySurface(GrSurface* dst, 1158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (can_copy_image(dst, src, this)) { 1162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->copySurfaceAsCopyImage(dst, src, srcRect, dstPoint); 1163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1164164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1165164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (can_copy_as_draw(dst, src, this)) { 1167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); 1168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1169164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1170164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1171164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1172164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1173164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 117428f45b949acc746849100fbe112ee5280f0594c9cdaltonvoid GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&, 117528f45b949acc746849100fbe112ee5280f0594c9cdalton int* effectiveSampleCnt, SkAutoTDeleteArray<SkPoint>*) { 117628f45b949acc746849100fbe112ee5280f0594c9cdalton // TODO: stub. 117728f45b949acc746849100fbe112ee5280f0594c9cdalton SkASSERT(!this->caps()->sampleLocationsSupport()); 117828f45b949acc746849100fbe112ee5280f0594c9cdalton *effectiveSampleCnt = rt->desc().fSampleCnt; 117928f45b949acc746849100fbe112ee5280f0594c9cdalton} 118028f45b949acc746849100fbe112ee5280f0594c9cdalton 1181164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 1182164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig readConfig, DrawPreference* drawPreference, 1183164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ReadPixelTempDrawInfo* tempDrawInfo) { 1184164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Currently we don't handle draws, so if the caller wants/needs to do a draw we need to fail 1185164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kNoDraw_DrawPreference != *drawPreference) { 1186164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1187164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1188164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1189164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcSurface->config() != readConfig) { 1190164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: This should fall back to drawing or copying to change config of srcSurface to match 1191164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // that of readConfig. 1192164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1193164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1194164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1195164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1196164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1197164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1198164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onReadPixels(GrSurface* surface, 1199164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 1200164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config, 1201164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* buffer, 1202164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 1203164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 1204164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 1205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1206164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1207164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* tgt = static_cast<GrVkTexture*>(surface->asTexture()); 1209164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!tgt) { 1210164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1211164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1212164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1213164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our target so it can be used as copy 1214164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = tgt->currentLayout(); 1215164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 1216164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 1217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 1218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 1219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tgt->setImageLayout(this, 1220164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1221164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1222164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1226164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 12279d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary GrVkTransferBuffer* transferBuffer = 1228397536cabe12a9936659870dd220c869789424bacdalton static_cast<GrVkTransferBuffer*>(this->createBuffer(kXferGpuToCpu_GrBufferType, 1229397536cabe12a9936659870dd220c869789424bacdalton rowBytes * height, 1230397536cabe12a9936659870dd220c869789424bacdalton kStream_GrAccessPattern)); 1231164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 1233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkOffset3D offset = { 1234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel left, 1235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel flipY ? surface->height() - top - height : top, 1236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0 1237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 1238164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Copy the image to a buffer so we can map it to cpu memory 1240164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferImageCopy region; 1241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 1242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferOffset = 0; 1243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferRowLength = 0; // Forces RowLength to be imageExtent.width 1244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images. 1245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageOffset = offset; 1247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 1248164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImageToBuffer(this, 1250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tgt, 1251164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1252164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer, 1253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ®ion); 1255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // make sure the copy to buffer has finished 1257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->addMemoryBarrier(this, 1258164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_TRANSFER_WRITE_BIT, 1259164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_READ_BIT, 1260164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 1261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 1262164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We need to submit the current command buffer to the Queue and make sure it finishes before 1265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // we can copy the data out of the buffer. 1266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kForce_SyncQueue); 1267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mappedMemory = transferBuffer->map(); 1269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(buffer, mappedMemory, rowBytes*height); 1271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unmap(); 1273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unref(); 1274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (flipY) { 1276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkAutoSMalloc<32 * sizeof(GrColor)> scratch; 1277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t tightRowBytes = GrBytesPerPixel(config) * width; 1278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel scratch.reset(tightRowBytes); 1279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* tmpRow = scratch.get(); 1280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // flip y in-place by rows 1281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const int halfY = height >> 1; 1282164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* top = reinterpret_cast<char*>(buffer); 1283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* bottom = top + (height - 1) * rowBytes; 1284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int y = 0; y < halfY; y++) { 1285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(tmpRow, top, tightRowBytes); 1286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(top, bottom, tightRowBytes); 1287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(bottom, tmpRow, tightRowBytes); 1288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel top += rowBytes; 1289164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bottom -= rowBytes; 1290164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1291164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1292164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1293164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1294164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1295af132770a9462f6bb9cff47254e44675d9241fe8egdanielsk_sp<GrVkPipelineState> GrVkGpu::prepareDrawState(const GrPipeline& pipeline, 1296af132770a9462f6bb9cff47254e44675d9241fe8egdaniel const GrPrimitiveProcessor& primProc, 1297af132770a9462f6bb9cff47254e44675d9241fe8egdaniel GrPrimitiveType primitiveType, 1298af132770a9462f6bb9cff47254e44675d9241fe8egdaniel const GrVkRenderPass& renderPass) { 1299af132770a9462f6bb9cff47254e44675d9241fe8egdaniel sk_sp<GrVkPipelineState> pipelineState = 1300af132770a9462f6bb9cff47254e44675d9241fe8egdaniel fResourceProvider.findOrCreateCompatiblePipelineState(pipeline, 1301af132770a9462f6bb9cff47254e44675d9241fe8egdaniel primProc, 1302af132770a9462f6bb9cff47254e44675d9241fe8egdaniel primitiveType, 1303af132770a9462f6bb9cff47254e44675d9241fe8egdaniel renderPass); 130422281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel if (!pipelineState) { 1305af132770a9462f6bb9cff47254e44675d9241fe8egdaniel return pipelineState; 1306164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1307164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1308af132770a9462f6bb9cff47254e44675d9241fe8egdaniel pipelineState->setData(this, primProc, pipeline); 1309164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1310af132770a9462f6bb9cff47254e44675d9241fe8egdaniel pipelineState->bind(this, fCurrentCmdBuffer); 1311470d77a1d7dc286cdad98b145dac735cd7638e56egdaniel 1312470d77a1d7dc286cdad98b145dac735cd7638e56egdaniel GrVkPipeline::SetDynamicState(this, fCurrentCmdBuffer, pipeline); 1313470d77a1d7dc286cdad98b145dac735cd7638e56egdaniel 1314af132770a9462f6bb9cff47254e44675d9241fe8egdaniel return pipelineState; 13150e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel} 1316164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 13170e1853c89615d14d0d03c87c7e0c604e5285cc54egdanielvoid GrVkGpu::onDraw(const GrPipeline& pipeline, 13180e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrPrimitiveProcessor& primProc, 13190e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrMesh* meshes, 13200e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel int meshCount) { 13210e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (!meshCount) { 13220e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel return; 13230e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 13240e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrRenderTarget* rt = pipeline.getRenderTarget(); 13250e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); 13260e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 13270e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel SkASSERT(renderPass); 1328164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1329470d77a1d7dc286cdad98b145dac735cd7638e56egdaniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); 1330470d77a1d7dc286cdad98b145dac735cd7638e56egdaniel 13310e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrPrimitiveType primitiveType = meshes[0].primitiveType(); 1332af132770a9462f6bb9cff47254e44675d9241fe8egdaniel sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline, 1333af132770a9462f6bb9cff47254e44675d9241fe8egdaniel primProc, 1334af132770a9462f6bb9cff47254e44675d9241fe8egdaniel primitiveType, 1335af132770a9462f6bb9cff47254e44675d9241fe8egdaniel *renderPass); 1336af132770a9462f6bb9cff47254e44675d9241fe8egdaniel if (!pipelineState) { 13370e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel return; 13380e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 1339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1340164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our render target so it can be used as the color attachment 1341164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = vkRT->currentLayout(); 1342164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Our color attachment is purely a destination and won't be read so don't need to flush or 1343164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // invalidate any caches 1344164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 1345164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1346164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 1347164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1348164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT->setImageLayout(this, 1349164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1350164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1351164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1352164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1353164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1354164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1355164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 13563d5d9ac426ea926f37eaa47e13acf7492068667begdaniel // If we are using a stencil attachment we also need to update its layout 13570e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (!pipeline.getStencil().isDisabled()) { 13583d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrStencilAttachment* stencil = vkRT->renderTargetPriv().getStencilAttachment(); 13593d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil; 13603d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkImageLayout origDstLayout = vkStencil->currentLayout(); 13613d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout); 13623d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkAccessFlags dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 13630e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; 13643d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkPipelineStageFlags srcStageMask = 13653d5d9ac426ea926f37eaa47e13acf7492068667begdaniel GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 13663d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 13673d5d9ac426ea926f37eaa47e13acf7492068667begdaniel vkStencil->setImageLayout(this, 13683d5d9ac426ea926f37eaa47e13acf7492068667begdaniel VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 13693d5d9ac426ea926f37eaa47e13acf7492068667begdaniel srcAccessMask, 13703d5d9ac426ea926f37eaa47e13acf7492068667begdaniel dstAccessMask, 13713d5d9ac426ea926f37eaa47e13acf7492068667begdaniel srcStageMask, 13723d5d9ac426ea926f37eaa47e13acf7492068667begdaniel dstStageMask, 13733d5d9ac426ea926f37eaa47e13acf7492068667begdaniel false); 13743d5d9ac426ea926f37eaa47e13acf7492068667begdaniel } 13753d5d9ac426ea926f37eaa47e13acf7492068667begdaniel 13760e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 13770e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel for (int i = 0; i < meshCount; ++i) { 13780e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) { 13790e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel this->xferBarrier(pipeline.getRenderTarget(), barrierType); 13800e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 13810e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 13820e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrMesh& mesh = meshes[i]; 13830e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel GrMesh::Iterator iter; 13840e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh); 13850e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel do { 13860e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (nonIdxMesh->primitiveType() != primitiveType) { 13870e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel // Technically we don't have to call this here (since there is a safety check in 138822281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel // pipelineState:setData but this will allow for quicker freeing of resources if the 138922281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel // pipelineState sits in a cache for a while. 139022281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel pipelineState->freeTempResources(this); 139122281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel SkDEBUGCODE(pipelineState = nullptr); 13920e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel primitiveType = nonIdxMesh->primitiveType(); 1393af132770a9462f6bb9cff47254e44675d9241fe8egdaniel pipelineState = this->prepareDrawState(pipeline, 1394af132770a9462f6bb9cff47254e44675d9241fe8egdaniel primProc, 1395af132770a9462f6bb9cff47254e44675d9241fe8egdaniel primitiveType, 1396af132770a9462f6bb9cff47254e44675d9241fe8egdaniel *renderPass); 1397af132770a9462f6bb9cff47254e44675d9241fe8egdaniel if (!pipelineState) { 13980e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel return; 13990e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 14000e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 140122281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel SkASSERT(pipelineState); 14020e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel this->bindGeometry(primProc, *nonIdxMesh); 14030e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 14040e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel if (nonIdxMesh->isIndexed()) { 14050e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fCurrentCmdBuffer->drawIndexed(this, 14060e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel nonIdxMesh->indexCount(), 14070e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 1, 14080e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel nonIdxMesh->startIndex(), 14090e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel nonIdxMesh->startVertex(), 14100e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 0); 14110e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } else { 14120e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fCurrentCmdBuffer->draw(this, 14130e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel nonIdxMesh->vertexCount(), 14140e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 1, 14150e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel nonIdxMesh->startVertex(), 14160e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 0); 14170e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } 14180e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel 14190e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel fStats.incNumDraws(); 14200e1853c89615d14d0d03c87c7e0c604e5285cc54egdaniel } while ((nonIdxMesh = iter.next())); 1421164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1422164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1423164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->endRenderPass(this); 1424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 142522281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel // Technically we don't have to call this here (since there is a safety check in 142622281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel // pipelineState:setData but this will allow for quicker freeing of resources if the 142722281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel // pipelineState sits in a cache for a while. 142822281c13a13c4b4e275516e9fe02185a53a7e5aaegdaniel pipelineState->freeTempResources(this); 1429164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1430164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#if SWAP_PER_DRAW 1431164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel glFlush(); 1432164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#if defined(SK_BUILD_FOR_MAC) 1433164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel aglSwapBuffers(aglGetCurrentContext()); 1434164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int set_a_break_pt_here = 9; 1435164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel aglSwapBuffers(aglGetCurrentContext()); 1436164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#elif defined(SK_BUILD_FOR_WIN32) 1437164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SwapBuf(); 1438164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int set_a_break_pt_here = 9; 1439164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SwapBuf(); 1440164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif 1441164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif 1442164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1443