VulkanManager.cpp revision 0e3cba31460e0698def0310003b7d291f1174afa
10e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger/* 20e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * Copyright (C) 2016 The Android Open Source Project 30e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * 40e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * Licensed under the Apache License, Version 2.0 (the "License"); 50e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * you may not use this file except in compliance with the License. 60e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * You may obtain a copy of the License at 70e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * 80e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * http://www.apache.org/licenses/LICENSE-2.0 90e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * 100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * Unless required by applicable law or agreed to in writing, software 110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * distributed under the License is distributed on an "AS IS" BASIS, 120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * See the License for the specific language governing permissions and 140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger * limitations under the License. 150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger */ 160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include "VulkanManager.h" 180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include "DeviceInfo.h" 200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include "RenderThread.h" 210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <GrContext.h> 230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <GrTypes.h> 240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#include <vk/GrVkTypes.h> 250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergernamespace android { 270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergernamespace uirenderer { 280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergernamespace renderthread { 290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#define GET_PROC(F) m ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk" #F) 310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#define GET_DEV_PROC(F) m ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk" #F) 320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 330e3cba31460e0698def0310003b7d291f1174afaDerek SollenbergerVulkanManager::VulkanManager(RenderThread& thread) : mRenderThread(thread) { 340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergervoid VulkanManager::destroy() { 370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (!hasVkContext()) return; 380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_NULL_HANDLE != mCommandPool) { 400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroyCommandPool(mBackendContext->fDevice, mCommandPool, nullptr); 410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mCommandPool = VK_NULL_HANDLE; 420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergervoid VulkanManager::initialize() { 460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (hasVkContext()) { return; } 470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; }; 490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mBackendContext.reset(GrVkBackendContext::Create(&mPresentQueueIndex, canPresent)); 510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Get all the addresses of needed vulkan functions 530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkInstance instance = mBackendContext->fInstance; 540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkDevice device = mBackendContext->fDevice; 550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_PROC(CreateAndroidSurfaceKHR); 560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_PROC(DestroySurfaceKHR); 570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_PROC(GetPhysicalDeviceSurfaceSupportKHR); 580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR); 590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR); 600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR); 610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(CreateSwapchainKHR); 620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(DestroySwapchainKHR); 630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(GetSwapchainImagesKHR); 640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(AcquireNextImageKHR); 650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(QueuePresentKHR); 660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(CreateCommandPool); 670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(DestroyCommandPool); 680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(AllocateCommandBuffers); 690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(FreeCommandBuffers); 700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(ResetCommandBuffer); 710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(BeginCommandBuffer); 720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(EndCommandBuffer); 730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(CmdPipelineBarrier); 740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(GetDeviceQueue); 750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(QueueSubmit); 760e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(QueueWaitIdle); 770e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(DeviceWaitIdle); 780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(CreateSemaphore); 790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(DestroySemaphore); 800e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(CreateFence); 810e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(DestroyFence); 820e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(WaitForFences); 830e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GET_DEV_PROC(ResetFences); 840e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // create the command pool for the command buffers 860e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_NULL_HANDLE == mCommandPool) { 870e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkCommandPoolCreateInfo commandPoolInfo; 880e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo)); 890e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 900e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // this needs to be on the render queue 910e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandPoolInfo.queueFamilyIndex = mBackendContext->fGraphicsQueueIndex; 920e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 930e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(VkResult res =) mCreateCommandPool(mBackendContext->fDevice, 940e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &commandPoolInfo, nullptr, &mCommandPool); 950e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(VK_SUCCESS == res); 960e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 970e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 980e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mGetDeviceQueue(mBackendContext->fDevice, mPresentQueueIndex, 0, &mPresentQueue); 990e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1000e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mRenderThread.setGrContext(GrContext::Create(kVulkan_GrBackend, 1010e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger (GrBackendContext) mBackendContext.get())); 1020e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger DeviceInfo::initialize(mRenderThread.getGrContext()->caps()->maxRenderTargetSize()); 1030e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 1040e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger// Returns the next BackbufferInfo to use for the next draw. The function will make sure all 1060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger// previous uses have finished before returning. 1070e3cba31460e0698def0310003b7d291f1174afaDerek SollenbergerVulkanSurface::BackbufferInfo* VulkanManager::getAvailableBackbuffer(VulkanSurface* surface) { 1080e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(surface->mBackbuffers); 1090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger ++surface->mCurrentBackbufferIndex; 1110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (surface->mCurrentBackbufferIndex > surface->mImageCount) { 1120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mCurrentBackbufferIndex = 0; 1130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 1140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VulkanSurface::BackbufferInfo* backbuffer = surface->mBackbuffers + 1160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mCurrentBackbufferIndex; 1170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Before we reuse a backbuffer, make sure its fences have all signaled so that we can safely 1190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // reuse its commands buffers. 1200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkResult res = mWaitForFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences, 1210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger true, UINT64_MAX); 1220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (res != VK_SUCCESS) { 1230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 1240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 1250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return backbuffer; 1270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 1280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1300e3cba31460e0698def0310003b7d291f1174afaDerek SollenbergerSkSurface* VulkanManager::getBackbufferSurface(VulkanSurface* surface) { 1310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VulkanSurface::BackbufferInfo* backbuffer = getAvailableBackbuffer(surface); 1320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(backbuffer); 1330e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkResult res; 1350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mResetFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences); 1370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(VK_SUCCESS == res); 1380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // The acquire will signal the attached mAcquireSemaphore. We use this to know the image has 1400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // finished presenting and that it is safe to begin sending new commands to the returned image. 1410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX, 1420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger backbuffer->mAcquireSemaphore, VK_NULL_HANDLE, &backbuffer->mImageIndex); 1430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_ERROR_SURFACE_LOST_KHR == res) { 1450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // need to figure out how to create a new vkSurface without the platformData* 1460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // maybe use attach somehow? but need a Window 1470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 1480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 1490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_ERROR_OUT_OF_DATE_KHR == res) { 1500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // tear swapchain down and try again 1510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (!createSwapchain(surface)) { 1520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 1530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 1540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // acquire the image 1560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX, 1570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger backbuffer->mAcquireSemaphore, VK_NULL_HANDLE, &backbuffer->mImageIndex); 1580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 1600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 1610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 1620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 1630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // set up layout transfer from initial to color attachment 1650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkImageLayout layout = surface->mImageLayouts[backbuffer->mImageIndex]; 1660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout || VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout); 1670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPipelineStageFlags srcStageMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ? 1680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT : 1690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 1700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 1710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkAccessFlags srcAccessMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ? 1720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 0 : VK_ACCESS_MEMORY_READ_BIT; 1730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkImageMemoryBarrier imageMemoryBarrier = { 1760e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 1770e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger NULL, // pNext 1780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger srcAccessMask, // outputMask 1790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger dstAccessMask, // inputMask 1800e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger layout, // oldLayout 1810e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout 1820e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mPresentQueueIndex, // srcQueueFamilyIndex 1830e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mBackendContext->fGraphicsQueueIndex, // dstQueueFamilyIndex 1840e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImages[backbuffer->mImageIndex], // image 1850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange 1860e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger }; 1870e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mResetCommandBuffer(backbuffer->mTransitionCmdBuffers[0], 0); 1880e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1890e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkCommandBufferBeginInfo info; 1900e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&info, 0, sizeof(VkCommandBufferBeginInfo)); 1910e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 1920e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.flags = 0; 1930e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mBeginCommandBuffer(backbuffer->mTransitionCmdBuffers[0], &info); 1940e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1950e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mCmdPipelineBarrier(backbuffer->mTransitionCmdBuffers[0], srcStageMask, dstStageMask, 0, 1960e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); 1970e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1980e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mEndCommandBuffer(backbuffer->mTransitionCmdBuffers[0]); 1990e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2000e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 2010e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // insert the layout transfer into the queue and wait on the acquire 2020e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkSubmitInfo submitInfo; 2030e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&submitInfo, 0, sizeof(VkSubmitInfo)); 2040e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 2050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.waitSemaphoreCount = 1; 2060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Wait to make sure aquire semaphore set above has signaled. 2070e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.pWaitSemaphores = &backbuffer->mAcquireSemaphore; 2080e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.pWaitDstStageMask = &waitDstStageFlags; 2090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.commandBufferCount = 1; 2100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.pCommandBuffers = &backbuffer->mTransitionCmdBuffers[0]; 2110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.signalSemaphoreCount = 0; 2120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Attach first fence to submission here so we can track when the command buffer finishes. 2140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mQueueSubmit(mBackendContext->fQueue, 1, &submitInfo, backbuffer->mUsageFences[0]); 2150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // We need to notify Skia that we changed the layout of the wrapped VkImage 2170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GrVkImageInfo* imageInfo; 2180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger sk_sp<SkSurface> skSurface = surface->mSurfaces[backbuffer->mImageIndex]; 2190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger skSurface->getRenderTargetHandle((GrBackendObject*)&imageInfo, 2200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkSurface::kFlushRead_BackendHandleAccess); 2210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger imageInfo->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 2220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffer = std::move(skSurface); 2240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return surface->mBackbuffer.get(); 2250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 2260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergervoid VulkanManager::destroyBuffers(VulkanSurface* surface) { 2280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (surface->mBackbuffers) { 2290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger for (uint32_t i = 0; i < surface->mImageCount + 1; ++i) { 2300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mWaitForFences(mBackendContext->fDevice, 2, surface->mBackbuffers[i].mUsageFences, true, 2310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger UINT64_MAX); 2320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffers[i].mImageIndex = -1; 2330e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroySemaphore(mBackendContext->fDevice, surface->mBackbuffers[i].mAcquireSemaphore, 2340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger nullptr); 2350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroySemaphore(mBackendContext->fDevice, surface->mBackbuffers[i].mRenderSemaphore, 2360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger nullptr); 2370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mFreeCommandBuffers(mBackendContext->fDevice, mCommandPool, 2, 2380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffers[i].mTransitionCmdBuffers); 2390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroyFence(mBackendContext->fDevice, surface->mBackbuffers[i].mUsageFences[0], 0); 2400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroyFence(mBackendContext->fDevice, surface->mBackbuffers[i].mUsageFences[1], 0); 2410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 2420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 2430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger delete[] surface->mBackbuffers; 2450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffers = nullptr; 2460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger delete[] surface->mSurfaces; 2470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mSurfaces = nullptr; 2480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger delete[] surface->mImageLayouts; 2490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImageLayouts = nullptr; 2500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger delete[] surface->mImages; 2510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImages = nullptr; 2520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 2530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergervoid VulkanManager::destroySurface(VulkanSurface* surface) { 2550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Make sure all submit commands have finished before starting to destroy objects. 2560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_NULL_HANDLE != mPresentQueue) { 2570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mQueueWaitIdle(mPresentQueue); 2580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 2590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDeviceWaitIdle(mBackendContext->fDevice); 2600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger destroyBuffers(surface); 2620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_NULL_HANDLE != surface->mSwapchain) { 2640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroySwapchainKHR(mBackendContext->fDevice, surface->mSwapchain, nullptr); 2650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mSwapchain = VK_NULL_HANDLE; 2660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 2670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_NULL_HANDLE != surface->mVkSurface) { 2690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroySurfaceKHR(mBackendContext->fInstance, surface->mVkSurface, nullptr); 2700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mVkSurface = VK_NULL_HANDLE; 2710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 2720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger delete surface; 2730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 2740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergervoid VulkanManager::createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent) { 2760e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mGetSwapchainImagesKHR(mBackendContext->fDevice, surface->mSwapchain, &surface->mImageCount, 2770e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger nullptr); 2780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(surface->mImageCount); 2790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImages = new VkImage[surface->mImageCount]; 2800e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mGetSwapchainImagesKHR(mBackendContext->fDevice, surface->mSwapchain, 2810e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mImageCount, surface->mImages); 2820e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2830e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkSurfaceProps props(0, kUnknown_SkPixelGeometry); 2840e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger bool wantSRGB = VK_FORMAT_R8G8B8A8_SRGB == format; 2860e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GrPixelConfig config = wantSRGB ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig; 2870e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 2880e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // set up initial image layouts and create surfaces 2890e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImageLayouts = new VkImageLayout[surface->mImageCount]; 2900e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mSurfaces = new sk_sp<SkSurface>[surface->mImageCount]; 2910e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger for (uint32_t i = 0; i < surface->mImageCount; ++i) { 2920e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GrBackendRenderTargetDesc desc; 2930e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GrVkImageInfo info; 2940e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.fImage = surface->mImages[i]; 2950e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.fAlloc = { VK_NULL_HANDLE, 0, 0, 0 }; 2960e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 2970e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.fImageTiling = VK_IMAGE_TILING_OPTIMAL; 2980e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.fFormat = format; 2990e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.fLevelCount = 1; 3000e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3010e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fWidth = extent.width; 3020e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fHeight = extent.height; 3030e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fConfig = config; 3040e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fOrigin = kTopLeft_GrSurfaceOrigin; 3050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fSampleCnt = 0; 3060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fStencilBits = 0; 3070e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc.fRenderTargetHandle = (GrBackendObject) &info; 3080e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(mRenderThread.getGrContext(), 3100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger desc, &props); 3110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED; 3120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(mCommandPool != VK_NULL_HANDLE); 3150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // set up the backbuffers 3170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkSemaphoreCreateInfo semaphoreInfo; 3180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo)); 3190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 3200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger semaphoreInfo.pNext = nullptr; 3210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger semaphoreInfo.flags = 0; 3220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkCommandBufferAllocateInfo commandBuffersInfo; 3230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo)); 3240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 3250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandBuffersInfo.pNext = nullptr; 3260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandBuffersInfo.commandPool = mCommandPool; 3270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 3280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger commandBuffersInfo.commandBufferCount = 2; 3290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkFenceCreateInfo fenceInfo; 3300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo)); 3310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 3320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger fenceInfo.pNext = nullptr; 3330e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; 3340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // we create one additional backbuffer structure here, because we want to 3360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // give the command buffers they contain a chance to finish before we cycle back 3370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffers = new VulkanSurface::BackbufferInfo[surface->mImageCount + 1]; 3380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger for (uint32_t i = 0; i < surface->mImageCount + 1; ++i) { 3390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(VkResult res); 3400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffers[i].mImageIndex = -1; 3410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(res = ) mCreateSemaphore(mBackendContext->fDevice, &semaphoreInfo, nullptr, 3420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mBackbuffers[i].mAcquireSemaphore); 3430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(res = ) mCreateSemaphore(mBackendContext->fDevice, &semaphoreInfo, nullptr, 3440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mBackbuffers[i].mRenderSemaphore); 3450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(res = ) mAllocateCommandBuffers(mBackendContext->fDevice, &commandBuffersInfo, 3460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffers[i].mTransitionCmdBuffers); 3470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(res = ) mCreateFence(mBackendContext->fDevice, &fenceInfo, nullptr, 3480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mBackbuffers[i].mUsageFences[0]); 3490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkDEBUGCODE(res = ) mCreateFence(mBackendContext->fDevice, &fenceInfo, nullptr, 3500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mBackbuffers[i].mUsageFences[1]); 3510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(VK_SUCCESS == res); 3520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mCurrentBackbufferIndex = surface->mImageCount; 3540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 3550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergerbool VulkanManager::createSwapchain(VulkanSurface* surface) { 3570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // check for capabilities 3580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkSurfaceCapabilitiesKHR caps; 3590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkResult res = mGetPhysicalDeviceSurfaceCapabilitiesKHR(mBackendContext->fPhysicalDevice, 3600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mVkSurface, &caps); 3610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 3620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 3630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger uint32_t surfaceFormatCount; 3660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mGetPhysicalDeviceSurfaceFormatsKHR(mBackendContext->fPhysicalDevice, surface->mVkSurface, 3670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surfaceFormatCount, nullptr); 3680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 3690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 3700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR)); 3730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get(); 3740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mGetPhysicalDeviceSurfaceFormatsKHR(mBackendContext->fPhysicalDevice, surface->mVkSurface, 3750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surfaceFormatCount, surfaceFormats); 3760e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 3770e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 3780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3800e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger uint32_t presentModeCount; 3810e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mGetPhysicalDeviceSurfacePresentModesKHR(mBackendContext->fPhysicalDevice, 3820e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mVkSurface, &presentModeCount, nullptr); 3830e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 3840e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 3850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3860e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3870e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR)); 3880e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get(); 3890e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mGetPhysicalDeviceSurfacePresentModesKHR(mBackendContext->fPhysicalDevice, 3900e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mVkSurface, &presentModeCount, presentModes); 3910e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 3920e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 3930e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 3940e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 3950e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkExtent2D extent = caps.currentExtent; 3960e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // clamp width; to handle currentExtent of -1 and protect us from broken hints 3970e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (extent.width < caps.minImageExtent.width) { 3980e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger extent.width = caps.minImageExtent.width; 3990e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4000e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(extent.width <= caps.maxImageExtent.width); 4010e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // clamp height 4020e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (extent.height < caps.minImageExtent.height) { 4030e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger extent.height = caps.minImageExtent.height; 4040e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(extent.height <= caps.maxImageExtent.height); 4060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4070e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger uint32_t imageCount = caps.minImageCount + 2; 4080e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) { 4090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Application must settle for fewer images than desired: 4100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger imageCount = caps.maxImageCount; 4110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Currently Skia requires the images to be color attchments and support all transfer 4140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // operations. 4150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 4160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 4170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_USAGE_TRANSFER_DST_BIT; 4180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags); 4190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(caps.supportedTransforms & caps.currentTransform); 4200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR | 4210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)); 4220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkCompositeAlphaFlagBitsKHR composite_alpha = 4230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ? 4240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : 4250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; 4260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Pick our surface format. For now, just make sure it matches our sRGB request: 4280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkFormat surfaceFormat = VK_FORMAT_UNDEFINED; 4290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkColorSpaceKHR colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; 4300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger bool wantSRGB = false; 4320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#ifdef ANDROID_ENABLE_LINEAR_BLENDING 4330e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger wantSRGB = true; 4340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger#endif 4350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger for (uint32_t i = 0; i < surfaceFormatCount; ++i) { 4360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // We are assuming we can get either R8G8B8A8_UNORM or R8G8B8A8_SRGB 4370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkFormat desiredFormat = wantSRGB ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; 4380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (desiredFormat == surfaceFormats[i].format) { 4390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surfaceFormat = surfaceFormats[i].format; 4400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger colorSpace = surfaceFormats[i].colorSpace; 4410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_FORMAT_UNDEFINED == surfaceFormat) { 4450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 4460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // If mailbox mode is available, use it, as it is the lowest-latency non- 4490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // tearing mode. If not, fall back to FIFO which is always available. 4500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR; 4510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger for (uint32_t i = 0; i < presentModeCount; ++i) { 4520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // use mailbox 4530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) { 4540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mode = presentModes[i]; 4550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger break; 4560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkSwapchainCreateInfoKHR swapchainCreateInfo; 4600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR)); 4610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; 4620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.surface = surface->mVkSurface; 4630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.minImageCount = imageCount; 4640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageFormat = surfaceFormat; 4650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageColorSpace = colorSpace; 4660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageExtent = extent; 4670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageArrayLayers = 1; 4680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageUsage = usageFlags; 4690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger uint32_t queueFamilies[] = { mBackendContext->fGraphicsQueueIndex, mPresentQueueIndex }; 4710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (mBackendContext->fGraphicsQueueIndex != mPresentQueueIndex) { 4720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; 4730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.queueFamilyIndexCount = 2; 4740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.pQueueFamilyIndices = queueFamilies; 4750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else { 4760e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; 4770e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.queueFamilyIndexCount = 0; 4780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.pQueueFamilyIndices = nullptr; 4790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4800e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4810e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 4820e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.compositeAlpha = composite_alpha; 4830e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.presentMode = mode; 4840e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.clipped = true; 4850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger swapchainCreateInfo.oldSwapchain = surface->mSwapchain; 4860e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4870e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mCreateSwapchainKHR(mBackendContext->fDevice, &swapchainCreateInfo, nullptr, 4880e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mSwapchain); 4890e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 4900e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return false; 4910e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 4920e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4930e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // destroy the old swapchain 4940e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) { 4950e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDeviceWaitIdle(mBackendContext->fDevice); 4960e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4970e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger destroyBuffers(surface); 4980e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 4990e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mDestroySwapchainKHR(mBackendContext->fDevice, swapchainCreateInfo.oldSwapchain, nullptr); 5000e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 5010e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5020e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger createBuffers(surface, surfaceFormat, extent); 5030e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5040e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return true; 5050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 5060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5070e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5080e3cba31460e0698def0310003b7d291f1174afaDerek SollenbergerVulkanSurface* VulkanManager::createSurface(ANativeWindow* window) { 5090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger initialize(); 5100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (!window) { 5120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 5130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 5140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VulkanSurface* surface = new VulkanSurface(); 5160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo; 5180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR)); 5190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; 5200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surfaceCreateInfo.pNext = nullptr; 5210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surfaceCreateInfo.flags = 0; 5220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surfaceCreateInfo.window = window; 5230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkResult res = mCreateAndroidSurfaceKHR(mBackendContext->fInstance, &surfaceCreateInfo, 5250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger nullptr, &surface->mVkSurface); 5260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_SUCCESS != res) { 5270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger delete surface; 5280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 5290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 5300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5310e3cba31460e0698def0310003b7d291f1174afaDerek SollenbergerSkDEBUGCODE( 5320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkBool32 supported; 5330e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger res = mGetPhysicalDeviceSurfaceSupportKHR(mBackendContext->fPhysicalDevice, 5340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mPresentQueueIndex, surface->mVkSurface, &supported); 5350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // All physical devices and queue families on Android must be capable of presentation with any 5360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // native window. 5370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(VK_SUCCESS == res && supported); 5380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger); 5390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (!createSwapchain(surface)) { 5410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger destroySurface(surface); 5420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return nullptr; 5430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 5440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return surface; 5460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 5470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger// Helper to know which src stage flags we need to set when transitioning to the present layout 5490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergerstatic VkPipelineStageFlags layoutToPipelineStageFlags(const VkImageLayout layout) { 5500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_IMAGE_LAYOUT_GENERAL == layout) { 5510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 5520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout || 5530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) { 5540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return VK_PIPELINE_STAGE_TRANSFER_BIT; 5550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout || 5560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout || 5570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == layout || 5580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) { 5590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; 5600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) { 5610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return VK_PIPELINE_STAGE_HOST_BIT; 5620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 5630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout); 5650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 5660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 5670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger// Helper to know which src access mask we need to set when transitioning to the present layout 5690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergerstatic VkAccessFlags layoutToSrcAccessMask(const VkImageLayout layout) { 5700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkAccessFlags flags = 0; 5710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger if (VK_IMAGE_LAYOUT_GENERAL == layout) { 5720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 5730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 5740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_ACCESS_TRANSFER_WRITE_BIT | 5750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_ACCESS_TRANSFER_READ_BIT | 5760e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_ACCESS_SHADER_READ_BIT | 5770e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_HOST_READ_BIT; 5780e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) { 5790e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_HOST_WRITE_BIT; 5800e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) { 5810e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 5820e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout) { 5830e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 5840e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) { 5850e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_TRANSFER_WRITE_BIT; 5860e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout) { 5870e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_TRANSFER_READ_BIT; 5880e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) { 5890e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger flags = VK_ACCESS_SHADER_READ_BIT; 5900e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger } 5910e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger return flags; 5920e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 5930e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 5940e3cba31460e0698def0310003b7d291f1174afaDerek Sollenbergervoid VulkanManager::swapBuffers(VulkanSurface* surface) { 5950e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VulkanSurface::BackbufferInfo* backbuffer = surface->mBackbuffers + 5960e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mCurrentBackbufferIndex; 5970e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger GrVkImageInfo* imageInfo; 5980e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkSurface* skSurface = surface->mSurfaces[backbuffer->mImageIndex].get(); 5990e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger skSurface->getRenderTargetHandle((GrBackendObject*)&imageInfo, 6000e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkSurface::kFlushRead_BackendHandleAccess); 6010e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Check to make sure we never change the actually wrapped image 6020e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger SkASSERT(imageInfo->fImage == surface->mImages[backbuffer->mImageIndex]); 6030e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6040e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // We need to transition the image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR and make sure that all 6050e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // previous work is complete for before presenting. So we first add the necessary barrier here. 6060e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkImageLayout layout = imageInfo->fImageLayout; 6070e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPipelineStageFlags srcStageMask = layoutToPipelineStageFlags(layout); 6080e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 6090e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkAccessFlags srcAccessMask = layoutToSrcAccessMask(layout); 6100e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkAccessFlags dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; 6110e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6120e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkImageMemoryBarrier imageMemoryBarrier = { 6130e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 6140e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger NULL, // pNext 6150e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger srcAccessMask, // outputMask 6160e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger dstAccessMask, // inputMask 6170e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger layout, // oldLayout 6180e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // newLayout 6190e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mBackendContext->fGraphicsQueueIndex, // srcQueueFamilyIndex 6200e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mPresentQueueIndex, // dstQueueFamilyIndex 6210e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImages[backbuffer->mImageIndex], // image 6220e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // subresourceRange 6230e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger }; 6240e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6250e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mResetCommandBuffer(backbuffer->mTransitionCmdBuffers[1], 0); 6260e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkCommandBufferBeginInfo info; 6270e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&info, 0, sizeof(VkCommandBufferBeginInfo)); 6280e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 6290e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger info.flags = 0; 6300e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mBeginCommandBuffer(backbuffer->mTransitionCmdBuffers[1], &info); 6310e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mCmdPipelineBarrier(backbuffer->mTransitionCmdBuffers[1], srcStageMask, dstStageMask, 0, 6320e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); 6330e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mEndCommandBuffer(backbuffer->mTransitionCmdBuffers[1]); 6340e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6350e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mImageLayouts[backbuffer->mImageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 6360e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6370e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // insert the layout transfer into the queue and wait on the acquire 6380e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VkSubmitInfo submitInfo; 6390e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger memset(&submitInfo, 0, sizeof(VkSubmitInfo)); 6400e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 6410e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.waitSemaphoreCount = 0; 6420e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.pWaitDstStageMask = 0; 6430e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.commandBufferCount = 1; 6440e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.pCommandBuffers = &backbuffer->mTransitionCmdBuffers[1]; 6450e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.signalSemaphoreCount = 1; 6460e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // When this command buffer finishes we will signal this semaphore so that we know it is now 6470e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // safe to present the image to the screen. 6480e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger submitInfo.pSignalSemaphores = &backbuffer->mRenderSemaphore; 6490e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6500e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Attach second fence to submission here so we can track when the command buffer finishes. 6510e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mQueueSubmit(mBackendContext->fQueue, 1, &submitInfo, backbuffer->mUsageFences[1]); 6520e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6530e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // Submit present operation to present queue. We use a semaphore here to make sure all rendering 6540e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // to the image is complete and that the layout has been change to present on the graphics 6550e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger // queue. 6560e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger const VkPresentInfoKHR presentInfo = 6570e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger { 6580e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType 6590e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger NULL, // pNext 6600e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1, // waitSemaphoreCount 6610e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &backbuffer->mRenderSemaphore, // pWaitSemaphores 6620e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 1, // swapchainCount 6630e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &surface->mSwapchain, // pSwapchains 6640e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger &backbuffer->mImageIndex, // pImageIndices 6650e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger NULL // pResults 6660e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger }; 6670e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6680e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger mQueuePresentKHR(mPresentQueue, &presentInfo); 6690e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6700e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger surface->mBackbuffer.reset(); 6710e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} 6720e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger 6730e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} /* namespace renderthread */ 6740e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} /* namespace uirenderer */ 6750e3cba31460e0698def0310003b7d291f1174afaDerek Sollenberger} /* namespace android */ 676