blob: c4d19738fc89198fdf9c2fb6c1dec8da7c077415 [file] [log] [blame] [edit]
/*
* Copyright 2023 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GraphiteVulkanWindowContext_DEFINED
#define GraphiteVulkanWindowContext_DEFINED
#include "include/core/SkTypes.h"
#ifdef SK_VULKAN
#include "include/core/SkSurface.h"
#include "include/private/base/SkTemplates.h"
#include "tools/gpu/vk/VkTestUtils.h"
#include "tools/window/WindowContext.h"
namespace skgpu {
struct VulkanInterface;
}
namespace skwindow::internal {
class GraphiteVulkanWindowContext : public WindowContext {
public:
~GraphiteVulkanWindowContext() override;
sk_sp<SkSurface> getBackbufferSurface() override;
bool isValid() override { return fDevice != VK_NULL_HANDLE; }
void resize(int w, int h) override { this->createSwapchain(w, h); }
void setDisplayParams(std::unique_ptr<const DisplayParams> params) override {
this->destroyContext();
fDisplayParams = std::move(params);
this->initializeContext();
}
/* Platform specific function that creates a VkSurfaceKHR for a window */
using CreateVkSurfaceFn = std::function<VkSurfaceKHR(VkInstance)>;
/* Platform specific function that determines whether presentation will succeed. */
using CanPresentFn = sk_gpu_test::CanPresentFn;
GraphiteVulkanWindowContext(std::unique_ptr<const DisplayParams>,
CreateVkSurfaceFn,
CanPresentFn,
PFN_vkGetInstanceProcAddr);
private:
void initializeContext();
void destroyContext();
bool createSwapchain(int width, int height);
bool populateSwapchainImages(VkFormat, VkImageUsageFlags, SkColorType, VkSharingMode);
/**
* Swap backbuffers/frames, presenting the next available image.
*/
void onSwapBuffers() override;
/**
* Define private method to submit work to the GPU (rather than using Window::submitToGpu) in
* order to properly configure semaphores. Submits work to render the image at
* fCurrentImageIndex. Return false upon failure.
*/
bool submitToGpu();
/**
* Reset the container of images (and destroy each image's associated rendering semaphore).
*/
void resetSwapchainImages();
/**
* Define a struct which represents a swapchain image to be presented. Each SwapchainImage
* contains the native VkImage, its image layout while not being used as a color attachment
* (which we initialize as VK_IMAGE_LAYOUT_UNDEFINED), a semaphore for signaling render
* completion, and an SkSurface the client renders to.
*/
struct SwapchainImage {
VkImage fVkImage = VK_NULL_HANDLE;
VkImageLayout fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VkSemaphore fRenderCompletionSemaphore = VK_NULL_HANDLE;
sk_sp<SkSurface> fSurface = nullptr; /* May not be based on rts */
};
skia_private::AutoTArray<SwapchainImage> fImages;
uint32_t fCurrentImageIndex; /* Index of image currently being presented */
VkSemaphore fAcquireSemaphore = VK_NULL_HANDLE; /* Semaphore to signal image acquisition */
sk_sp<const skgpu::VulkanInterface> fInterface;
/* Vulkan driver structs + info */
VkInstance fInstance = VK_NULL_HANDLE;
VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
VkDevice fDevice = VK_NULL_HANDLE;
VkDebugUtilsMessengerEXT fDebugMessenger = VK_NULL_HANDLE;
VkSurfaceKHR fDeviceSurface;
VkSwapchainKHR fSwapchain;
uint32_t fGraphicsQueueIndex;
VkQueue fGraphicsQueue;
uint32_t fPresentQueueIndex;
VkQueue fPresentQueue;
/* Create functions */
CreateVkSurfaceFn fCreateVkSurfaceFn;
CanPresentFn fCanPresentFn;
PFN_vkGetInstanceProcAddr fGetInstanceProcAddr = nullptr;
/* WSI interface functions */
PFN_vkDestroySurfaceKHR fDestroySurfaceKHR = nullptr;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR fGetPhysicalDeviceSurfaceSupportKHR = nullptr;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fGetPhysicalDeviceSurfaceCapabilitiesKHR =
nullptr;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fGetPhysicalDeviceSurfacePresentModesKHR =
nullptr;
PFN_vkCreateSwapchainKHR fCreateSwapchainKHR = nullptr;
PFN_vkDestroySwapchainKHR fDestroySwapchainKHR = nullptr;
PFN_vkGetSwapchainImagesKHR fGetSwapchainImagesKHR = nullptr;
PFN_vkAcquireNextImageKHR fAcquireNextImageKHR = nullptr;
PFN_vkQueuePresentKHR fQueuePresentKHR = nullptr;
PFN_vkDestroyInstance fDestroyInstance = nullptr;
PFN_vkDeviceWaitIdle fDeviceWaitIdle = nullptr;
PFN_vkDestroyDebugUtilsMessengerEXT fDestroyDebugUtilsMessengerEXT = nullptr;
PFN_vkQueueWaitIdle fQueueWaitIdle = nullptr;
PFN_vkDestroyDevice fDestroyDevice = nullptr;
PFN_vkGetDeviceQueue fGetDeviceQueue = nullptr;
};
} // namespace skwindow::internal
#endif // SK_VULKAN
#endif // GraphiteVulkanWindowContext_DEFINED