| // Copyright 2020 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_GRAPHICS_LIB_COMPUTE_EXAMPLES_COMMON_VULKAN_WINDOW_H_ | |
| #define SRC_GRAPHICS_LIB_COMPUTE_EXAMPLES_COMMON_VULKAN_WINDOW_H_ | |
| #include <stdint.h> | |
| #include <vulkan/vulkan.h> | |
| // Forward declarations only. | |
| class VulkanDevice; | |
| typedef struct vk_surface vk_surface_t; | |
| typedef struct vk_swapchain vk_swapchain_t; | |
| typedef struct vk_swapchain_queue vk_swapchain_queue_t; | |
| typedef struct vk_swapchain_queue_image vk_swapchain_queue_image_t; | |
| // Simple class used to create a Vulkan-based display window for our demo | |
| // programs. Usage is the following: | |
| // | |
| // 1) Create instance. | |
| // | |
| // 2) Call Init() passing a VulkanWindow::Config struct with appropriate | |
| // configuration settings describing the use case for properly | |
| // initializing a Vulkan instance, device and swapchain. | |
| // | |
| // 3) Use helper methods like instance(), device(), swapchain() to get | |
| // relevant data. | |
| // | |
| class VulkanWindow { | |
| public: | |
| // Configuration information used during initialization. | |
| struct Config | |
| { | |
| // Optional application name, displayed in window title. | |
| const char * app_name = nullptr; | |
| // Display surface dimensions. Note that the Vulkan swapchain | |
| // may end up selecting different values in the end. Use the | |
| // extent() method, after init(), to get the final ones. | |
| uint32_t window_width = 1024; | |
| uint32_t window_height = 1024; | |
| // |verbose| enables logs to be dumped during window creation. | |
| // |debug| enables Vulkan validation and adds more logs. | |
| bool verbose = false; | |
| bool debug = false; | |
| // |disable_vsync| is used to disable vsync synchronization in the | |
| // swapchain. Must match the value used to initialize the VulkanDevice!! | |
| bool disable_vsync = false; | |
| // |wanted_format| is the desired swachain image format, | |
| // VK_FORMAT_UNDEFINED leaves the choice to the swapchain | |
| // implementation, and is a sane default. Note that init() | |
| // will fail if the Vulkan swapchain cannot support it. | |
| VkFormat wanted_format = VK_FORMAT_UNDEFINED; | |
| // Set to true if this window requires shaders to write directly to | |
| // swapchain images. For example when using the Spinel library to | |
| // render directly into such images. | |
| bool require_swapchain_image_shader_storage = false; | |
| // Set to true if this window requires that buffers or images | |
| // be copied to swapchain images. For example when unsing the Mold | |
| // library to render into a VkBuffer, then copying it into the | |
| // swapchain's VkImage. | |
| bool require_swapchain_transfers = false; | |
| // If unset (the default), the drawFrame() method should only | |
| // call acquireSwapchainImage() and presentSwapchainImage(). | |
| bool enable_swapchain_queue = false; | |
| // The following fields are only used if |enable_swapchain_queue| | |
| // set, and are used to initialize the swapchain queue. | |
| // (see vk_swapchain_queue_config_t for details). | |
| VkRenderPass enable_framebuffers = VK_NULL_HANDLE; | |
| uint32_t sync_semaphores_count = 0u; | |
| }; | |
| VulkanWindow() | |
| { | |
| } | |
| ~VulkanWindow(); | |
| // Initialize instance. Return true on success. On failure, print error messages | |
| // to stderr and return false. | |
| bool | |
| init(VulkanDevice * device, const Config & config); | |
| struct Info | |
| { | |
| uint32_t image_count = 0; | |
| VkExtent2D extent = {}; | |
| VkSurfaceKHR surface = {}; | |
| VkSurfaceFormatKHR surface_format = {}; | |
| }; | |
| const VulkanDevice & | |
| device() const | |
| { | |
| return *device_; | |
| } | |
| vk_swapchain_t * | |
| swapchain() const | |
| { | |
| return swapchain_; | |
| } | |
| const Info & | |
| info() const | |
| { | |
| return info_; | |
| } | |
| // Call this in a loop to handle input UI events. | |
| // Returns true in case of failure, i.e. when it is time to quit. | |
| bool | |
| handleUserEvents(); | |
| // Wait until all GPU operations have completed on this device. | |
| // Should only be called on application exit, once it is sure that no | |
| // operations is blocked on synchronization on the GPU, or this will | |
| // freeze the process. | |
| void | |
| waitIdle(); | |
| // These functions should only be called if |enable_swapchain_queue| was false | |
| // during construction. | |
| bool | |
| acquireSwapchainImage(); | |
| void | |
| presentSwapchainImage(); | |
| // These functions should only be called if |enabled_swapchain_queue| was true | |
| // during construction. | |
| bool | |
| acquireSwapchainQueueImage(); | |
| void | |
| presentSwapchainQueueImage(); | |
| uint32_t | |
| image_index() const | |
| { | |
| return image_index_; | |
| } | |
| vk_swapchain_queue_t * | |
| swapchain_queue() const | |
| { | |
| return swapchain_queue_; | |
| } | |
| protected: | |
| VulkanDevice * device_ = nullptr; | |
| vk_surface_t * surface_ = nullptr; | |
| vk_swapchain_t * swapchain_ = nullptr; | |
| Info info_ = {}; | |
| vk_swapchain_queue_t * swapchain_queue_ = nullptr; | |
| const vk_swapchain_queue_image_t * swapchain_queue_image_ = nullptr; | |
| uint32_t image_index_ = 0; | |
| }; | |
| #endif // SRC_GRAPHICS_LIB_COMPUTE_EXAMPLES_COMMON_VULKAN_WINDOW_H_ |