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