blob: 8fcd572f2472a1742e18ea93d9510bcf2822a920 [file] [log] [blame]
// 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_