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" 13164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrPipeline.h" 14164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrRenderTargetPriv.h" 15164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrSurfacePriv.h" 16164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrTexturePriv.h" 17164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVertices.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" 24164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkProgram.h" 25164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkProgramBuilder.h" 26164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkProgramDesc.h" 27164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkRenderPass.h" 28164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkResourceProvider.h" 29164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTexture.h" 30164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTextureRenderTarget.h" 31164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkTransferBuffer.h" 32164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "GrVkVertexBuffer.h" 33164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 34164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "SkConfig8888.h" 35164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 36164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#include "vk/GrVkInterface.h" 37164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 38164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X) 39164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X) 40164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X) 41164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 42164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 43164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel// Stuff used to set up a GrVkGpu secrectly for now. 44164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 45164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel// For now the VkGpuCreate is using the same signature as GL. This is mostly for ease of 46164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel// hiding this code from offical skia. In the end the VkGpuCreate will not take a GrBackendContext 47164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel// and mostly likely would take an optional device and queues to use. 48164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrGpu* vk_gpu_create(GrBackendContext backendContext, const GrContextOptions& options, 49164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrContext* context) { 50164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Below is Vulkan setup code that normal would be done by a client, but will do here for now 51164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // for testing purposes. 52164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPhysicalDevice physDev; 53164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDevice device; 54164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkInstance inst; 55164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkResult err; 56164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 57164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkApplicationInfo app_info = { 58164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType 59164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // pNext 60164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel "vktest", // pApplicationName 61164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // applicationVersion 62164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel "vktest", // pEngineName 63164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // engineVerison 64164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_API_VERSION, // apiVersion 65164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 66164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkInstanceCreateInfo instance_create = { 67164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType 68164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // pNext 69164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // flags 70164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &app_info, // pApplicationInfo 71164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // enabledLayerNameCount 72164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // ppEnabledLayerNames 73164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // enabledExtensionNameCount 74164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // ppEnabledExtensionNames 75164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 76164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = vkCreateInstance(&instance_create, nullptr, &inst); 77164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err < 0) { 78164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkDebugf("vkCreateInstanced failed: %d\n", err); 79164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkFAIL("failing"); 80164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 81164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 82164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t gpuCount; 83164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); 84164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 85164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); 86164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkFAIL("failing"); 87164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 88164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(gpuCount > 0); 89164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Just returning the first physical device instead of getting the whole array. 90164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel gpuCount = 1; 91164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = vkEnumeratePhysicalDevices(inst, &gpuCount, &physDev); 92164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 93164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); 94164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkFAIL("failing"); 95164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 96164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 97164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // query to get the initial queue props size 98164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t queueCount; 99164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); 100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(queueCount >= 1); 101164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 102164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties)); 103164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // now get the actual queue props 104164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAlloc.get(); 105164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 106164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps); 107164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 108164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // iterate to find the graphics queue 109164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t graphicsQueueIndex = -1; 110164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (uint32_t i = 0; i < queueCount; i++) { 111164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { 112164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel graphicsQueueIndex = i; 113164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel break; 114164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 115164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 116164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(graphicsQueueIndex < queueCount); 117164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 118164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel float queuePriorities[1] = { 0.0 }; 119164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkDeviceQueueCreateInfo queueInfo = { 120164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType 121164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // pNext 122164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // VkDeviceQueueCreateFlags 123164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // queueFamilyIndex 124164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, // queueCount 125164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel queuePriorities, // pQueuePriorities 126164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 127164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkDeviceCreateInfo deviceInfo = { 128164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType 129164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // pNext 130164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // VkDeviceCreateFlags 131164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, // queueCreateInfoCount 132164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &queueInfo, // pQueueCreateInfos 133164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // layerCount 134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // ppEnabledLayerNames 135164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // extensionCount 136164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // ppEnabledExtensionNames 137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr // ppEnabledFeatures 138164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 139164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 140164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); 141164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 142164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkDebugf("CreateDevice failed: %d\n", err); 143164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkFAIL("failing"); 144164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkQueue queue; 147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); 148164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 149164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkCommandPoolCreateInfo cmdPoolInfo = { 150164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType 151164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel nullptr, // pNext 152164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // CmdPoolCreateFlags 153164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel graphicsQueueIndex, // queueFamilyIndex 154164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 155164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 156164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkCommandPool cmdPool; 157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &cmdPool); 158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkDebugf("CreateCommandPool failed: %d\n", err); 160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkFAIL("failing"); 161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return new GrVkGpu(context, options, physDev, device, queue, cmdPool, inst); 164164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 165164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, 169164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPhysicalDevice physDev, VkDevice device, VkQueue queue, VkCommandPool cmdPool, 170164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkInstance inst) 171164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : INHERITED(context) 172164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fDevice(device) 173164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fQueue(queue) 174164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fCmdPool(cmdPool) 175164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fResourceProvider(this) 176164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel , fVkInstance(inst) { 177164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fInterface.reset(GrVkCreateInterface(fVkInstance)); 178164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCompiler = shaderc_compiler_initialize(); 179164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 180164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fVkCaps.reset(new GrVkCaps(options, fInterface, physDev)); 181164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCaps.reset(SkRef(fVkCaps.get())); 182164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 183164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer = fResourceProvider.createCommandBuffer(); 184164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 185164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->begin(this); 186164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_CALL(GetPhysicalDeviceMemoryProperties(physDev, &fPhysDevMemProps)); 187164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 188164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 189164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 190164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVkGpu::~GrVkGpu() { 191164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel shaderc_compiler_release(fCompiler); 192164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 193164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 194164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 195164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // wait for all commands to finish 196164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_CALL(QueueWaitIdle(fQueue)); 197164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 198164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // must call this just before we destroy the VkDevice 199164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fResourceProvider.destroyResources(); 200164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 201164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr)); 202164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_CALL(DestroyDevice(fDevice, nullptr)); 203164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_CALL(DestroyInstance(fVkInstance, nullptr)); 204164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 206164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 207164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::submitCommandBuffer(SyncQueue sync) { 209164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 210164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->end(this); 211164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 212164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->submitToQueue(this, fQueue, sync); 213164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fResourceProvider.checkCommandBuffers(); 214164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 215164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Release old command buffer and create a new one 216164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->unref(this); 217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer = fResourceProvider.createCommandBuffer(); 218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 220164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->begin(this); 221164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 222164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel/////////////////////////////////////////////////////////////////////////////// 224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrVertexBuffer* GrVkGpu::onCreateVertexBuffer(size_t size, bool dynamic) { 225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return GrVkVertexBuffer::Create(this, size, dynamic); 226164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 227164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 228164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrIndexBuffer* GrVkGpu::onCreateIndexBuffer(size_t size, bool dynamic) { 229164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return GrVkIndexBuffer::Create(this, size, dynamic); 230164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 231164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrTransferBuffer* GrVkGpu::onCreateTransferBuffer(size_t size, TransferType type) { 233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkBuffer::Type bufferType = kCpuToGpu_TransferType ? GrVkBuffer::kCopyRead_Type 234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : GrVkBuffer::kCopyWrite_Type; 235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return GrVkTransferBuffer::Create(this, size, bufferType); 236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 238164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 240164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig srcConfig, DrawPreference* drawPreference, 241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel WritePixelTempDrawInfo* tempDrawInfo) { 242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurface->config())) { 243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Currently we don't handle draws, so if the caller wants/needs to do a draw we need to fail 247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kNoDraw_DrawPreference != *drawPreference) { 248164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 251164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (dstSurface->config() != srcConfig) { 252164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: This should fall back to drawing or copying to change config of dstSurface to 253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // match that of srcConfig. 254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 258164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 259164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 260164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onWritePixels(GrSurface* surface, 261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 262164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config, const void* buffer, 263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture()); 265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!vkTex) { 266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels. 270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 273164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 274164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool success = false; 275164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) { 276164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo() 277164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(config == vkTex->desc().fConfig); 278164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: add compressed texture support 279164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // delete the following two lines and uncomment the two after that when ready 280164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->unref(); 281164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 282164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false, left, top, width, 283164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // height); 284164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 285164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = vkTex->isLinearTiled(); 286164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling && VK_IMAGE_LAYOUT_PREINITIALIZED != vkTex->currentLayout()) { 287164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Need to change the layout to general in order to perform a host write 288164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = vkTex->currentLayout(); 289164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 290164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_HOST_BIT; 291164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 292164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_HOST_WRITE_BIT; 293164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->setImageLayout(this, 294164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_GENERAL, 295164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 296164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 297164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 298164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 299164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 300164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 301164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel success = this->uploadTexData(vkTex, left, top, width, height, config, 302164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel buffer, rowBytes); 303164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 304164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 305164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (success) { 306164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkTex->texturePriv().dirtyMipMaps(true); 307164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 308164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 309164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 310164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 311164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 312164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 313164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::uploadTexData(GrVkTexture* tex, 314164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 315164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig dataConfig, 316164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const void* data, 317164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 318164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(data); 319164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 320164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If we're uploading compressed data then we should be using uploadCompressedTexData 321164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 322164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 323164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = tex->isLinearTiled(); 324164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 325164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t bpp = GrBytesPerPixel(dataConfig); 326164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 327164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurfaceDesc& desc = tex->desc(); 328164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 329164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, 330164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &width, &height, &data, &rowBytes)) { 331164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 332164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 333164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t trimRowBytes = width * bpp; 334164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 335164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling) { 336164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == tex->currentLayout() || 337164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_GENERAL == tex->currentLayout()); 338164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkImageSubresource subres = { 339164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_ASPECT_COLOR_BIT, 340164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // mipLevel 341164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // arraySlice 342164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 343164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkSubresourceLayout layout; 344164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkResult err; 345164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 346164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkInterface* interface = this->vkInterface(); 347164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 348164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice, 349164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->textureImage(), 350164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &subres, 351164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &layout)); 352164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 353164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int texTop = kBottomLeft_GrSurfaceOrigin == desc.fOrigin ? tex->height() - top - height 354164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel : top; 355164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDeviceSize offset = texTop*layout.rowPitch + left*bpp; 356164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkDeviceSize size = height*layout.rowPitch; 357164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mapPtr; 358164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = GR_VK_CALL(interface, MapMemory(fDevice, tex->textureMemory(), offset, size, 0, 359164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &mapPtr)); 360164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 361164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 362164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 363164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 364164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 365164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // copy into buffer by rows 366164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const char* srcRow = reinterpret_cast<const char*>(data); 367164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*layout.rowPitch; 368164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int y = 0; y < height; y++) { 369164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(dstRow, srcRow, trimRowBytes); 370164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcRow += rowBytes; 371164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstRow -= layout.rowPitch; 372164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 373164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 374164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If there is no padding on the src (rowBytes) or dst (layout.rowPitch) we can memcpy 375164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (trimRowBytes == rowBytes && trimRowBytes == layout.rowPitch) { 376164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(mapPtr, data, trimRowBytes * height); 377164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 378164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkRectMemcpy(mapPtr, layout.rowPitch, data, rowBytes, trimRowBytes, height); 379164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 380164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 381164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 382164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(interface, UnmapMemory(fDevice, tex->textureMemory())); 383164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 384164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTransferBuffer* transferBuffer = 385164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTransferBuffer::Create(this, trimRowBytes * height, GrVkBuffer::kCopyRead_Type); 386164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 387164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mapPtr = transferBuffer->map(); 388164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 389164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 390164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // copy into buffer by rows 391164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const char* srcRow = reinterpret_cast<const char*>(data); 392164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* dstRow = reinterpret_cast<char*>(mapPtr)+(height - 1)*trimRowBytes; 393164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int y = 0; y < height; y++) { 394164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(dstRow, srcRow, trimRowBytes); 395164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcRow += rowBytes; 396164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstRow -= trimRowBytes; 397164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 398164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 399164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If there is no padding on the src data rows, we can do a single memcpy 400164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (trimRowBytes == rowBytes) { 401164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(mapPtr, data, trimRowBytes * height); 402164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 403164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkRectMemcpy(mapPtr, trimRowBytes, data, rowBytes, trimRowBytes, height); 404164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 405164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 406164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 407164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unmap(); 408164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 409164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // make sure the unmap has finished 410164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->addMemoryBarrier(this, 411164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_WRITE_BIT, 412164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_TRANSFER_READ_BIT, 413164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 414164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 415164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 416164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 417164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Set up copy region 418164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool flipY = kBottomLeft_GrSurfaceOrigin == tex->origin(); 419164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkOffset3D offset = { 420164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel left, 421164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel flipY ? tex->height() - top - height : top, 422164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0 423164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 424164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 425164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferImageCopy region; 426164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 427164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferOffset = 0; 428164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferRowLength = width; 429164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferImageHeight = height; 430164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 431164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageOffset = offset; 432164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 433164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 434164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our target so it can be copied to 435164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = tex->currentLayout(); 436164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 437164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 438164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 439164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 440164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->setImageLayout(this, 441164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 442164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 443164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 444164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 445164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 446164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 447164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 448164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Copy the buffer to the image 449164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyBufferToImage(this, 450164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer, 451164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex, 452164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 453164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 454164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ®ion); 455164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 456164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Submit the current command buffer to the Queue 457164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 458164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 459164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unref(); 460164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 461164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 462164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 463164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 464164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 465164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 466164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle, 467164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const void* srcData, size_t rowBytes) { 468164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 469164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 470164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 471164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat)) { 472164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 473164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 474164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 475164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(desc.fConfig)) { 476164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 477164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 478164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 479164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 480164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (SkToBool(desc.fFlags & kZeroCopy_GrSurfaceFlag)) { 481164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVkCaps->isConfigTexurableLinearly(desc.fConfig) && 482164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel (!renderTarget || fVkCaps->isConfigRenderableLinearly(desc.fConfig, false))) { 483164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 484164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 485164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 486164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 487164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 488164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 489164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 490164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 491164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 492164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 493164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 494164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // For now we will set the VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT and 495164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT on every texture since we do not know whether or not we 496164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // will be using this texture in some copy or not. Also this assumes, as is the current case, 497164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // that all render targets in vulkan are also texutres. If we change this practice of setting 498164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // both bits, we must make sure to set the destination bit if we are uploading srcData to the 499164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // texture. 500164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 501164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 502164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFlags memProps = (srcData && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : 503164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 504164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 505164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is 506164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // requested, this ImageDesc describes the resolved texutre. Therefore we always have samples set 507164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // to 1. 508164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::ImageDesc imageDesc; 509164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageType = VK_IMAGE_TYPE_2D; 510164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fFormat = pixelFormat; 511164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fWidth = desc.fWidth; 512164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fHeight = desc.fHeight; 513164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fLevels = 1; 514164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fSamples = 1; 515164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 516164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fUsageFlags = usageFlags; 517164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fMemProps = memProps; 518164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 519164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* tex; 520164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 521164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc, lifeCycle, 522164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc); 523164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 524164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc); 525164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 526164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 527164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!tex) { 528164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 529164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 530164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 531164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcData) { 532164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!this->uploadTexData(tex, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, srcData, 533164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel rowBytes)) { 534164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tex->unref(); 535164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 536164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 537164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 538164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 539164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tex; 540164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 541164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 542164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 543164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 544164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielstatic GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) { 545164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // By default, all textures in Vk use TopLeft 546164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kDefault_GrSurfaceOrigin == origin) { 547164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return kTopLeft_GrSurfaceOrigin; 548164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 549164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return origin; 550164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 551164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 552164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 553164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc, 554164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrWrapOwnership ownership) { 555164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat format; 556164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(desc.fConfig, &format)) { 557164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 558164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 559164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 560164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (0 == desc.fTextureHandle) { 561164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 562164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 563164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 564164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int maxSize = this->caps()->maxTextureSize(); 565164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 566164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 567164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 568164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 569164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: determine what format Chrome will actually send us and turn it into a Resource 570164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::Resource* imageRsrc = reinterpret_cast<GrVkImage::Resource*>(desc.fTextureHandle); 571164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 572164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrGpuResource::LifeCycle lifeCycle; 573164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel switch (ownership) { 574164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel case kAdopt_GrWrapOwnership: 575164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle = GrGpuResource::kAdopted_LifeCycle; 576164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel break; 577164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel case kBorrow_GrWrapOwnership: 578164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle = GrGpuResource::kBorrowed_LifeCycle; 579164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel break; 580164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 581164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 582164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc surfDesc; 583164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // next line relies on GrBackendTextureDesc's flags matching GrTexture's 584164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags; 585164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fWidth = desc.fWidth; 586164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fHeight = desc.fHeight; 587164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fConfig = desc.fConfig; 588164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()); 589164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag); 590164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In GL, Chrome assumes all textures are BottomLeft 591164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In VK, we don't have this restriction 592164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel surfDesc.fOrigin = resolve_origin(desc.fOrigin); 593164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 594164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* texture = nullptr; 595164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (renderTarget) { 596164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel texture = GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(this, surfDesc, 597164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle, format, 598164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageRsrc); 599164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 600164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, format, imageRsrc); 601164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 602164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!texture) { 603164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 604164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 605164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 606164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return texture; 607164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 608164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 609164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc, 610164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrWrapOwnership ownership) { 611164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 612164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: determine what format Chrome will actually send us and turn it into a Resource 613164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::Resource* imageRsrc = 614164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel reinterpret_cast<GrVkImage::Resource*>(wrapDesc.fRenderTargetHandle); 615164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 616164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrGpuResource::LifeCycle lifeCycle; 617164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel switch (ownership) { 618164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel case kAdopt_GrWrapOwnership: 619164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle = GrGpuResource::kAdopted_LifeCycle; 620164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel break; 621164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel case kBorrow_GrWrapOwnership: 622164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle = GrGpuResource::kBorrowed_LifeCycle; 623164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel break; 624164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 625164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 626164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurfaceDesc desc; 627164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fConfig = wrapDesc.fConfig; 628164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fFlags = kCheckAllocation_GrSurfaceFlag; 629164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fWidth = wrapDesc.fWidth; 630164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fHeight = wrapDesc.fHeight; 631164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()); 632164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 633164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel desc.fOrigin = resolve_origin(wrapDesc.fOrigin); 634164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 635164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkRenderTarget* tgt = GrVkRenderTarget::CreateWrappedRenderTarget(this, desc, 636164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel lifeCycle, imageRsrc); 637164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (tgt && wrapDesc.fStencilBits) { 638164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeight)) { 639164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tgt->unref(); 640164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return nullptr; 641164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 642164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 643164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return tgt; 644164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 645164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 646164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 647164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 648164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::bindGeometry(const GrPrimitiveProcessor& primProc, 649164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrNonInstancedVertices& vertices) { 650164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkVertexBuffer* vbuf; 651164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vbuf = (GrVkVertexBuffer*)vertices.vertexBuffer(); 652164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(vbuf); 653164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!vbuf->isMapped()); 654164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 655164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vbuf->addMemoryBarrier(this, 656164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_WRITE_BIT, 657164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, 658164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 659164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 660164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 661164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 662164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->bindVertexBuffer(this, vbuf); 663164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 664164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (vertices.isIndexed()) { 665164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)vertices.indexBuffer(); 666164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(ibuf); 667164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(!ibuf->isMapped()); 668164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 669164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ibuf->addMemoryBarrier(this, 670164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_WRITE_BIT, 671164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_INDEX_READ_BIT, 672164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 673164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 674164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 675164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 676164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->bindIndexBuffer(this, ibuf); 677164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 678164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 679164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 680164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::buildProgramDesc(GrProgramDesc* desc, 681164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrPrimitiveProcessor& primProc, 682164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrPipeline& pipeline) const { 683164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrVkProgramDescBuilder::Build(desc, primProc, pipeline, *this->vkCaps().glslCaps())) { 684164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkDEBUGFAIL("Failed to generate GL program descriptor"); 685164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 686164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 687164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 688164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 689164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 690164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 691164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int width, 692164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int height) { 693164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(rt->asTexture()); 694164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(width >= rt->width()); 695164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(height >= rt->height()); 696164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 697164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int samples = rt->numStencilSamples(); 698164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 699164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(this->vkCaps().stencilFormats().count()); 700164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkCaps::StencilFormat& sFmt = this->vkCaps().stencilFormats()[0]; 701164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 702164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this, 703164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrGpuResource::kCached_LifeCycle, 704164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel width, 705164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel height, 706164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel samples, 707164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel sFmt)); 708164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fStats.incStencilAttachmentCreates(); 709164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return stencil; 710164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 711164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 712164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 713164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 714164a9f061c5186ae931cc23a3c73f32472e80ff5Greg DanielGrBackendObject GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h, 715164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config) { 716164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 717164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 718164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 719164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 720164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 721164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 722164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool linearTiling = false; 723164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!fVkCaps->isConfigTexturable(config)) { 724164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 725164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 726164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 727164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (fVkCaps->isConfigTexurableLinearly(config)) { 728164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel linearTiling = true; 729164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 730164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 731164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Currently this is not supported since it requires a copy which has not yet been implemented. 732164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcData && !linearTiling) { 733164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 734164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 735164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 736164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; 737164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 738164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 739164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 740164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFlags memProps = (srcData && linearTiling) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : 741164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 742164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 743164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This ImageDesc refers to the texture that will be read by the client. Thus even if msaa is 744164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // requested, this ImageDesc describes the resolved texutre. Therefore we always have samples set 745164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // to 1. 746164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::ImageDesc imageDesc; 747164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageType = VK_IMAGE_TYPE_2D; 748164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fFormat = pixelFormat; 749164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fWidth = w; 750164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fHeight = h; 751164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fLevels = 1; 752164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fSamples = 1; 753164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fImageTiling = linearTiling ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; 754164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fUsageFlags = usageFlags; 755164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageDesc.fMemProps = memProps; 756164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 757164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkImage::Resource* imageRsrc = GrVkImage::CreateResource(this, imageDesc); 758164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!imageRsrc) { 759164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 760164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 761164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 762164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcData) { 763164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (linearTiling) { 764164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const VkImageSubresource subres = { 765164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_ASPECT_COLOR_BIT, 766164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // mipLevel 767164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, // arraySlice 768164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 769164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkSubresourceLayout layout; 770164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkResult err; 771164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 772164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkInterface* interface = this->vkInterface(); 773164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 774164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(interface, GetImageSubresourceLayout(fDevice, 775164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageRsrc->fImage, 776164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &subres, 777164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &layout)); 778164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 779164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mapPtr; 780164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel err = GR_VK_CALL(interface, MapMemory(fDevice, 781164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageRsrc->fAlloc, 782164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, 783164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel layout.rowPitch * h, 784164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0, 785164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &mapPtr)); 786164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (err) { 787164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel imageRsrc->unref(this); 788164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return 0; 789164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 790164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 791164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t bpp = GrBytesPerPixel(config); 792164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowCopyBytes = bpp * w; 793164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // If there is no padding on dst (layout.rowPitch) we can do a single memcopy. 794164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This assumes the srcData comes in with no padding. 795164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (rowCopyBytes == layout.rowPitch) { 796164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(mapPtr, srcData, rowCopyBytes * h); 797164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 798164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkRectMemcpy(mapPtr, layout.rowPitch, srcData, w, rowCopyBytes, h); 799164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 800164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(interface, UnmapMemory(fDevice, imageRsrc->fAlloc)); 801164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 802164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: Add support for copying to optimal tiling 803164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(false); 804164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 805164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 806164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 807164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return (GrBackendObject)imageRsrc; 808164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 809164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 810164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::isTestingOnlyBackendTexture(GrBackendObject id) const { 811164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::Resource* backend = reinterpret_cast<GrVkImage::Resource*>(id); 812164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 813164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (backend && backend->fImage && backend->fAlloc) { 814164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryRequirements req; 815164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&req, 0, sizeof(req)); 816164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GR_VK_CALL(this->vkInterface(), GetImageMemoryRequirements(fDevice, 817164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel backend->fImage, 818164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &req)); 819164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: find a better check 820164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This will probably fail with a different driver 821164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return (req.size > 0) && (req.size <= 8192 * 8192); 822164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 823164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 824164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 825164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 826164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 827164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendObject id, bool abandon) { 828164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkImage::Resource* backend = reinterpret_cast<GrVkImage::Resource*>(id); 829164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 830164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (backend) { 831164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!abandon) { 832164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel backend->unref(this); 833164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 834164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel backend->unrefAndAbandon(); 835164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 836164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 837164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 838164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 839164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel//////////////////////////////////////////////////////////////////////////////// 840164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 841164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addMemoryBarrier(VkPipelineStageFlags srcStageMask, 842164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 843164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 844164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkMemoryBarrier* barrier) const { 845164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 846164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 847164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 848164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 849164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 850164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kMemory_BarrierType, 851164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 852164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 853164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 854164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addBufferMemoryBarrier(VkPipelineStageFlags srcStageMask, 855164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 856164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 857164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferMemoryBarrier* barrier) const { 858164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 859164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 860164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 861164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 862164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 863164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kBufferMemory_BarrierType, 864164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 865164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 866164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 867164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask, 868164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask, 869164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool byRegion, 870164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageMemoryBarrier* barrier) const { 871164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(fCurrentCmdBuffer); 872164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->pipelineBarrier(this, 873164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 874164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 875164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel byRegion, 876164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkCommandBuffer::kImageMemory_BarrierType, 877164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel barrier); 878164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 879164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 880164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::finishDrawTarget() { 881164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Submit the current command buffer to the Queue 882164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kSkip_SyncQueue); 883164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 884164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 885164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::onClear(GrRenderTarget* target, const SkIRect& rect, GrColor color) { 886164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // parent class should never let us get here with no RT 887164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(target); 888164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 889164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkClearColorValue vkColor; 890164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrColorToRGBAFloat(color, vkColor.float32); 891164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 892164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target); 893164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout origDstLayout = vkRT->currentLayout(); 894164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 895164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (rect.width() != target->width() || rect.height() != target->height()) { 896164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout); 897164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 898164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = 899164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkMemory::LayoutToPipelineStageFlags(vkRT->currentLayout()); 900164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 901164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT->setImageLayout(this, 902164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 903164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 904164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 905164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 906164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 907164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 908164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 909164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkClearRect clearRect; 910164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel clearRect.rect.offset = { rect.fLeft, rect.fTop }; 911164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel clearRect.rect.extent = { (uint32_t)rect.width(), (uint32_t)rect.height() }; 912164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel clearRect.baseArrayLayer = 0; 913164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel clearRect.layerCount = 1; 914164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 915164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 916164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 917164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 918164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(renderPass); 919164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); 920164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 921164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel uint32_t colorIndex; 922164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkAssertResult(renderPass->colorAttachmentIndex(&colorIndex)); 923164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 924164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkClearAttachment attachment; 925164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 926164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel attachment.colorAttachment = colorIndex; 927164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel attachment.clearValue.color = vkColor; 928164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 929164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->clearAttachments(this, 1, &attachment, 1, &clearRect); 930164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->endRenderPass(this); 931164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return; 932164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 933164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 934164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 935164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 936164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 937164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout);; 938164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 939164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 940164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT->setImageLayout(this, 941164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 942164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 943164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 944164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 945164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 946164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 947164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 948164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 949164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageSubresourceRange subRange; 950164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(&subRange, 0, sizeof(VkImageSubresourceRange)); 951164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 952164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.baseMipLevel = 0; 953164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.levelCount = 1; 954164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.baseArrayLayer = 0; 955164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel subRange.layerCount = 1; 956164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 957164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // In the future we may not actually be doing this type of clear at all. If we are inside a 958164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // render pass or doing a non full clear then we will use CmdClearColorAttachment. The more 959164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // common use case will be clearing an attachment at the start of a render pass, in which case 960164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // we will use the clear load ops. 961164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->clearColorImage(this, 962164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT, 963164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel &vkColor, 964164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, &subRange); 965164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 966164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 967164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_image(const GrSurface* dst, 968164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 969164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 970164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (src->asTexture() && 971164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dst->asTexture() && 972164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel src->origin() == dst->origin() && 973164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel src->config() == dst->config()) { 974164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 975164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 976164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 977164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // How does msaa play into this? If a VkTexture is multisampled, are we copying the multisampled 978164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // or the resolved image here? 979164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 980164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 981164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 982164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 983164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, 984164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 985164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 986164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 987164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(can_copy_image(dst, src, this)); 988164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 989164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Insert memory barriers to switch src and dst to transfer_source and transfer_dst layouts 990164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* dstTex = static_cast<GrVkTexture*>(dst->asTexture()); 991164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* srcTex = static_cast<GrVkTexture*>(src->asTexture()); 992164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 993164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout origDstLayout = dstTex->currentLayout(); 994164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout origSrcLayout = srcTex->currentLayout(); 995164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 996164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origDstLayout); 997164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 998164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 999164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // These flags are for flushing/invalidating caches and for the dst image it doesn't matter if 1000164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // the cache is flushed since it is only being written to. 1001164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origDstLayout);; 1002164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1003164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1004164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstTex->setImageLayout(this, 1005164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1006164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1007164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1008164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1009164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1010164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1011164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1012164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(origSrcLayout); 1013164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 1014164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1015164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(origSrcLayout); 1016164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 1017164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1018164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcTex->setImageLayout(this, 1019164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1020164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1021164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1022164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1023164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1024164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1025164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1026164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Flip rect if necessary 1027164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkIRect srcVkRect = srcRect; 1028164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int32_t dstY = dstPoint.fY; 1029164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1030164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 1031164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(kBottomLeft_GrSurfaceOrigin == dst->origin()); 1032164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fTop = src->height() - srcRect.fBottom; 1033164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcVkRect.fBottom = src->height() - srcRect.fTop; 1034164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstY = dst->height() - dstPoint.fY - srcVkRect.height(); 1035164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1036164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1037164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageCopy copyRegion; 1038164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(©Region, 0, sizeof(VkImageCopy)); 1039164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1040164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; 1041164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1042164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.dstOffset = { dstPoint.fX, dstY, 0 }; 1043164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 0 }; 1044164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1045164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImage(this, 1046164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcTex, 1047164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1048164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstTex, 1049164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1050164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1051164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ©Region); 1052164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1053164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1054164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielinline bool can_copy_as_draw(const GrSurface* dst, 1055164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrSurface* src, 1056164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkGpu* gpu) { 1057164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1058164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1059164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1060164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::copySurfaceAsDraw(GrSurface* dst, 1061164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1062164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1063164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1064164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(false); 1065164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1066164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1067164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onCopySurface(GrSurface* dst, 1068164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrSurface* src, 1069164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIRect& srcRect, 1070164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const SkIPoint& dstPoint) { 1071164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (can_copy_image(dst, src, this)) { 1072164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->copySurfaceAsCopyImage(dst, src, srcRect, dstPoint); 1073164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1074164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1075164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1076164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (can_copy_as_draw(dst, src, this)) { 1077164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); 1078164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1079164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1080164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1081164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1082164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1083164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1084164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 1085164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig readConfig, DrawPreference* drawPreference, 1086164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ReadPixelTempDrawInfo* tempDrawInfo) { 1087164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Currently we don't handle draws, so if the caller wants/needs to do a draw we need to fail 1088164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (kNoDraw_DrawPreference != *drawPreference) { 1089164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1090164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1091164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1092164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (srcSurface->config() != readConfig) { 1093164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // TODO: This should fall back to drawing or copying to change config of srcSurface to match 1094164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // that of readConfig. 1095164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1096164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1097164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1098164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1099164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1100164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1101164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielbool GrVkGpu::onReadPixels(GrSurface* surface, 1102164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int left, int top, int width, int height, 1103164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrPixelConfig config, 1104164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* buffer, 1105164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t rowBytes) { 1106164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkFormat pixelFormat; 1107164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { 1108164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1109164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1110164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1111164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTexture* tgt = static_cast<GrVkTexture*>(surface->asTexture()); 1112164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!tgt) { 1113164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return false; 1114164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1115164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1116164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our target so it can be used as copy 1117164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = tgt->currentLayout(); 1118164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 1119164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 1120164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 1121164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 1122164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tgt->setImageLayout(this, 1123164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1124164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1125164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1126164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1127164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1128164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1129164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1130164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkTransferBuffer* transferBuffer = 1131164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel reinterpret_cast<GrVkTransferBuffer*>(this->createTransferBuffer(rowBytes * height, 1132164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel kGpuToCpu_TransferType)); 1133164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1134164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 1135164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkOffset3D offset = { 1136164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel left, 1137164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel flipY ? surface->height() - top - height : top, 1138164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0 1139164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel }; 1140164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1141164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Copy the image to a buffer so we can map it to cpu memory 1142164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkBufferImageCopy region; 1143164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memset(®ion, 0, sizeof(VkBufferImageCopy)); 1144164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferOffset = 0; 1145164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferRowLength = 0; // Forces RowLength to be imageExtent.width 1146164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images. 1147164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; 1148164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageOffset = offset; 1149164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; 1150164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1151164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->copyImageToBuffer(this, 1152164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel tgt, 1153164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 1154164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer, 1155164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1156164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel ®ion); 1157164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1158164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // make sure the copy to buffer has finished 1159164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->addMemoryBarrier(this, 1160164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_TRANSFER_WRITE_BIT, 1161164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_ACCESS_HOST_READ_BIT, 1162164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_TRANSFER_BIT, 1163164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_PIPELINE_STAGE_HOST_BIT, 1164164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1165164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1166164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // We need to submit the current command buffer to the Queue and make sure it finishes before 1167164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // we can copy the data out of the buffer. 1168164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->submitCommandBuffer(kForce_SyncQueue); 1169164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1170164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* mappedMemory = transferBuffer->map(); 1171164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1172164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(buffer, mappedMemory, rowBytes*height); 1173164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1174164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unmap(); 1175164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel transferBuffer->unref(); 1176164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1177164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (flipY) { 1178164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkAutoSMalloc<32 * sizeof(GrColor)> scratch; 1179164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel size_t tightRowBytes = GrBytesPerPixel(config) * width; 1180164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel scratch.reset(tightRowBytes); 1181164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel void* tmpRow = scratch.get(); 1182164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // flip y in-place by rows 1183164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const int halfY = height >> 1; 1184164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* top = reinterpret_cast<char*>(buffer); 1185164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel char* bottom = top + (height - 1) * rowBytes; 1186164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel for (int y = 0; y < halfY; y++) { 1187164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(tmpRow, top, tightRowBytes); 1188164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(top, bottom, tightRowBytes); 1189164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel memcpy(bottom, tmpRow, tightRowBytes); 1190164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel top += rowBytes; 1191164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel bottom -= rowBytes; 1192164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1193164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1194164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1195164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return true; 1196164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1197164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1198164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Danielvoid GrVkGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertices) { 1199164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrRenderTarget* rt = args.fPipeline->getRenderTarget(); 1200164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); 1201164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel const GrVkRenderPass* renderPass = vkRT->simpleRenderPass(); 1202164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SkASSERT(renderPass); 1203164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1204164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1205164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel GrVkProgram* program = GrVkProgramBuilder::CreateProgram(this, args, 1206164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertices.primitiveType(), 1207164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel *renderPass); 1208164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1209164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (!program) { 1210164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel return; 1211164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1212164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1213164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel program->setData(this, *args.fPrimitiveProcessor, *args.fPipeline); 1214164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1215164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->beginRenderPass(this, renderPass, *vkRT); 1216164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1217164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel program->bind(this, fCurrentCmdBuffer); 1218164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1219164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel this->bindGeometry(*args.fPrimitiveProcessor, vertices); 1220164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1221164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Change layout of our render target so it can be used as the color attachment 1222164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkImageLayout layout = vkRT->currentLayout(); 1223164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Our color attachment is purely a destination and won't be read so don't need to flush or 1224164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // invalidate any caches 1225164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); 1226164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1227164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); 1228164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1229164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vkRT->setImageLayout(this, 1230164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1231164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcAccessMask, 1232164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstAccessMask, 1233164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel srcStageMask, 1234164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel dstStageMask, 1235164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel false); 1236164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1237164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel if (vertices.isIndexed()) { 1238164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->drawIndexed(this, 1239164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertices.indexCount(), 1240164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1, 1241164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertices.startIndex(), 1242164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel vertices.startVertex(), 1243164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 0); 1244164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } else { 1245164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->draw(this, vertices.vertexCount(), 1, vertices.startVertex(), 0); 1246164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel } 1247164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1248164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel fCurrentCmdBuffer->endRenderPass(this); 1249164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1250164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // Technically we don't have to call this here (since there is a safety check in program:setData 1251164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // but this will allow for quicker freeing of resources if the program sits in a cache for a 1252164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // while. 1253164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel program->freeTempResources(this); 1254164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // This free will go away once we setup a program cache, and then the cache will be responsible 1255164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel // for call freeGpuResources. 1256164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel program->freeGPUResources(this); 1257164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel program->unref(); 1258164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1259164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#if SWAP_PER_DRAW 1260164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel glFlush(); 1261164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#if defined(SK_BUILD_FOR_MAC) 1262164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel aglSwapBuffers(aglGetCurrentContext()); 1263164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int set_a_break_pt_here = 9; 1264164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel aglSwapBuffers(aglGetCurrentContext()); 1265164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#elif defined(SK_BUILD_FOR_WIN32) 1266164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SwapBuf(); 1267164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel int set_a_break_pt_here = 9; 1268164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel SwapBuf(); 1269164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif 1270164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel#endif 1271164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel} 1272164a9f061c5186ae931cc23a3c73f32472e80ff5Greg Daniel 1273