Browse Source

Refacto: Move basic setup to VulkanContext class.

master
Draklaw 4 years ago
parent
commit
52a2bdbfe8
  1. 1
      CMakeLists.txt
  2. 1
      src/VkExpe.cpp
  3. 1019
      src/VulkanContext.cpp
  4. 215
      src/VulkanContext.h
  5. 846
      src/VulkanTutorial.cpp
  6. 78
      src/VulkanTutorial.h
  7. 7
      src/utils.cpp
  8. 6
      src/utils.h

1
CMakeLists.txt

@ -34,6 +34,7 @@ add_executable(vk_expe
src/utils.cpp src/utils.cpp
src/Logger.cpp src/Logger.cpp
src/VkExpe.cpp src/VkExpe.cpp
src/VulkanContext.cpp
src/VulkanTutorial.cpp src/VulkanTutorial.cpp
) )

1
src/VkExpe.cpp

@ -83,5 +83,6 @@ void VkExpe::run() {
} }
m_vulkan.draw_frame(); m_vulkan.draw_frame();
// m_running = false;
} }
} }

1019
src/VulkanContext.cpp

File diff suppressed because it is too large

215
src/VulkanContext.h

@ -0,0 +1,215 @@
#pragma once
#include "utils.h"
#include "Logger.h"
#include <SDL2/SDL.h>
#include <vulkan/vulkan.h>
#include <optional>
#include <initializer_list>
#include <vector>
#include <functional>
class VulkanContext;
class VulkanContextSettings {
public:
struct QueueInfo {
uint32_t index;
VkQueueFlagBits flags;
bool use_swapchain_images;
};
public:
VulkanContextSettings();
~VulkanContextSettings();
bool debug() const;
VulkanContextSettings& with_debug(bool enabled=true);
const std::optional<Uuid>& physical_device() const;
VulkanContextSettings& with_physical_device(Uuid uuid);
const std::vector<QueueInfo>& queues() const;
VulkanContextSettings& with_queue(uint32_t index, VkQueueFlagBits flags, bool use_swapchain_images=false);
SDL_Window* window() const;
VulkanContextSettings& with_window(SDL_Window* window);
private:
bool m_debug = false;
std::optional<Uuid> m_physical_device;
std::vector<QueueInfo> m_queues;
SDL_Window* m_window = nullptr;
};
constexpr uint32_t INVALID_QUEUE_FAMILY = UINT32_MAX;
class VulkanContext {
public:
static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX;
static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2;
using SwapchainCreationCallback = std::function<void(uint32_t)>;
using SwapchainDestructionCallback = std::function<void()>;
using ContextDestructionCallback = std::function<void()>;
public:
VulkanContext();
VulkanContext(const VulkanContext&) = delete;
~VulkanContext();
VulkanContext& operator=(const VulkanContext&) = delete;
VkInstance instance();
VkPhysicalDevice physical_device();
VkDevice device();
uint32_t queue_family(size_t queue_index) const;
VkQueue queue(size_t queue_index);
VkSurfaceKHR surface();
VkSwapchainKHR swapchain();
VkSurfaceFormatKHR surface_format() const;
VkPresentModeKHR present_mode() const;
VkExtent2D swapchain_extent() const;
size_t swapchain_image_count() const;
uint32_t current_image_index() const;
VkImage swapchain_image();
VkImage swapchain_image(size_t image_index);
VkImageView swapchain_image_view();
VkImageView swapchain_image_view(size_t image_index);
// VkFramebuffer framebuffer();
VkSemaphore ready_to_render();
VkFence render_done();
void initialize(const VulkanContextSettings& settings);
void shutdown();
void begin_frame();
void swap_buffers(uint32_t semaphore_count, VkSemaphore* wait_semaphores);
void invalidate_swapchain();
void register_swapchain_creation_callback(SwapchainCreationCallback callback);
void register_swapchain_destruction_callback(SwapchainDestructionCallback callback);
void register_context_destruction_callback(ContextDestructionCallback callback);
static std::vector<VkExtensionProperties> available_extensions();
static std::vector<VkLayerProperties> available_layers();
std::vector<const char*> sdl_vulkan_extensions() const;
std::vector<VkPhysicalDevice> physical_devices() const;
std::vector<VkQueueFamilyProperties> queue_families(VkPhysicalDevice physical_device) const;
std::vector<VkExtensionProperties> device_extensions(VkPhysicalDevice physical_device) const;
std::vector<VkSurfaceFormatKHR> surface_formats(VkPhysicalDevice physical_device) const;
std::vector<VkPresentModeKHR> present_modes(VkPhysicalDevice physical_device) const;
void set_object_name(VkObjectType type, uint64_t object, const char* name);
void set_object_name(VkObjectType type, uint64_t object, const std::string& name);
void destroy_instance(VkInstance& instance);
void destroy_debug_messenger(VkDebugUtilsMessengerEXT& debug_messenger);
void destroy_surface(VkSurfaceKHR& surface);
void destroy_device(VkDevice& device);
void destroy_swapchain(VkSwapchainKHR& swapchain);
void destroy_image(VkImage& image);
void destroy_image_view(VkImageView& image_view);
void destroy_framebuffer(VkFramebuffer& framebuffer);
void destroy_buffer(VkBuffer& buffer);
void destroy_command_pool(VkCommandPool& command_pool);
void destroy_render_pass(VkRenderPass& render_pass);
void destroy_pipeline_layout(VkPipelineLayout& pipeline_layout);
void destroy_pipeline(VkPipeline& pipeline);
void destroy_semaphore(VkSemaphore& semaphore);
void destroy_fence(VkFence& fence);
void free_memory(VkDeviceMemory& memory);
private:
struct ImageResources {
VkImage image = VK_NULL_HANDLE;
VkImageView view = VK_NULL_HANDLE;
VkFence render_done = VK_NULL_HANDLE;
};
struct FrameResources {
VkSemaphore ready_to_render = VK_NULL_HANDLE;
VkFence render_done = VK_NULL_HANDLE;
};
private:
void create_instance(const VulkanContextSettings& settings);
void create_surface(const VulkanContextSettings& settings);
void choose_physical_device(const VulkanContextSettings& settings);
bool select_physical_device(
VkPhysicalDevice physical_device,
const VulkanContextSettings& settings
);
void create_device(const VulkanContextSettings& settings);
void create_swapchain(const VulkanContextSettings& settings);
void create_swapchain();
void destroy_swapchain();
void recreate_swapchain();
void initialize_extension_functions();
static VKAPI_ATTR VkBool32 VKAPI_CALL log_debug_message(
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* data,
void* user_data
);
private:
SDL_Window* m_window = nullptr;
VkInstance m_instance = nullptr;
VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE;
VkPhysicalDevice m_physical_device = nullptr;
VkDevice m_device = nullptr;
std::vector<uint32_t> m_queue_families;
uint32_t m_presentation_queue_family = UINT32_MAX;
std::vector<VkQueue> m_queues;
VkQueue m_presentation_queue = nullptr;
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
VkSurfaceFormatKHR m_surface_format;
VkPresentModeKHR m_present_mode;
VkExtent2D m_swapchain_extent;
std::vector<uint32_t> m_swapchain_queue_families;
std::vector<ImageResources> m_image_resources;
std::vector<FrameResources> m_frame_resources;
bool m_invalid_swapchain = false;
std::vector<SwapchainCreationCallback> m_swapchain_creation_callbacks;
std::vector<SwapchainDestructionCallback> m_swapchain_destruction_callbacks;
std::vector<ContextDestructionCallback> m_context_destruction_callbacks;
uint32_t m_current_image_index = CURRENT_IMAGE_INDEX;
size_t m_frame_index = 0;
size_t m_frame_resources_index = 0;
friend class VulkanContextSettings;
};
extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT;
extern PFN_vkSetDebugUtilsObjectNameEXT vkeSetDebugUtilsObjectNameEXT;

846
src/VulkanTutorial.cpp

File diff suppressed because it is too large

78
src/VulkanTutorial.h

@ -1,21 +1,13 @@
#pragma once #pragma once
#include "VulkanContext.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <Eigen/Dense> #include <Eigen/Dense>
#include <vector> #include <vector>
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
#define VKEXPE_VALIDATION true
#else
#define VKEXPE_VALIDATION false
#endif
extern PFN_vkCreateDebugUtilsMessengerEXT vkeCreateDebugUtilsMessengerEXT;
extern PFN_vkDestroyDebugUtilsMessengerEXT vkeDestroyDebugUtilsMessengerEXT;
struct Vertex { struct Vertex {
Eigen::Vector2f position; Eigen::Vector2f position;
Eigen::Vector3f color; Eigen::Vector3f color;
@ -26,6 +18,11 @@ struct Vertex {
class VulkanTutorial { class VulkanTutorial {
public:
enum QueueIndex {
GRAPHIC_QUEUE,
};
public: public:
VulkanTutorial(); VulkanTutorial();
VulkanTutorial(const VulkanTutorial&) = delete; VulkanTutorial(const VulkanTutorial&) = delete;
@ -39,59 +36,27 @@ public:
void draw_frame(); void draw_frame();
void invalidate_swapchain(); void invalidate_swapchain();
static std::vector<VkExtensionProperties> available_extensions();
static std::vector<VkLayerProperties> available_layers();
static VKAPI_ATTR VkBool32 VKAPI_CALL print_debug_message(
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* data,
void* user_data
);
private: private:
void create_instance(); void create_swapchain_objects(uint32_t image_count);
void create_surface(); void destroy_swapchain_objects();
void find_physical_device();
void create_device();
void create_swapchain();
void create_render_pass(); void create_render_pass();
void create_graphic_pipeline(); void create_graphic_pipeline();
void create_framebuffers(); void create_framebuffers();
void create_command_pool(); void create_command_pool();
void create_vertex_buffer(); void create_vertex_buffer();
void create_command_buffers(); void create_command_buffers();
void create_sync_objects();
void cleanup_swap_chain();
void recreate_swap_chain();
VkShaderModule create_shader_module(const std::vector<char> bytecode); VkShaderModule create_shader_module(const std::vector<char> bytecode);
VkShaderModule create_shader_module_from_file(const char* path); VkShaderModule create_shader_module_from_file(const char* path);
int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties); int32_t find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties);
std::vector<VkPhysicalDevice> get_physical_devices() const;
std::vector<VkQueueFamilyProperties> get_queue_families(VkPhysicalDevice physical_device) const;
std::vector<VkExtensionProperties> get_device_extensions(VkPhysicalDevice physical_device) const;
std::vector<VkSurfaceFormatKHR> get_surface_formats(VkPhysicalDevice physical_device) const;
std::vector<VkPresentModeKHR> get_present_modes(VkPhysicalDevice physical_device) const;
void initialize_extension_functions();
private: private:
SDL_Window* m_window = nullptr; VulkanContext m_context;
VkInstance m_instance = nullptr;
VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE;
VkSurfaceKHR m_surface;
VkPhysicalDevice m_physical_device = nullptr;
VkDevice m_device = nullptr;
VkQueue m_graphic_queue = nullptr; VkQueue m_graphic_queue = nullptr;
VkQueue m_presentation_queue = nullptr; VkQueue m_presentation_queue = nullptr;
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
std::vector<VkImage> m_swapchain_images;
std::vector<VkImageView> m_swapchain_image_views;
VkRenderPass m_render_pass = VK_NULL_HANDLE; VkRenderPass m_render_pass = VK_NULL_HANDLE;
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE; VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
VkPipeline m_pipeline = VK_NULL_HANDLE; VkPipeline m_pipeline = VK_NULL_HANDLE;
@ -100,22 +65,5 @@ private:
VkBuffer m_vertex_buffer = VK_NULL_HANDLE; VkBuffer m_vertex_buffer = VK_NULL_HANDLE;
VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE; VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> m_command_buffers; std::vector<VkCommandBuffer> m_command_buffers;
std::vector<VkSemaphore> m_image_available_semaphores; std::vector<VkSemaphore> m_render_done;
std::vector<VkSemaphore> m_render_finished_semaphores;
std::vector<VkFence> m_in_flight_fence;
std::vector<VkFence> m_images_in_flight;
uint32_t m_graphic_queue_family = -1;
uint32_t m_presentation_queue_family = -1;
VkSurfaceFormatKHR m_swapchain_format;
VkPresentModeKHR m_present_mode;
VkExtent2D m_swapchain_extent;
size_t m_frame_index = 0;
bool m_invalid_swapchain = true;
VkDebugUtilsMessengerCreateInfoEXT m_debug_info;
bool m_enableValidation = VKEXPE_VALIDATION;
static constexpr size_t MAX_FRAMES_IN_FLIGHT = 2;
}; };

7
src/utils.cpp

@ -1,8 +1,15 @@
#include "utils.h" #include "utils.h"
#include <cstring>
#include <fstream> #include <fstream>
Uuid make_uuid(uint8_t const* bytes) {
Uuid uuid;
std::memcpy(uuid.data(), bytes, UUID_SIZE);
return uuid;
}
std::vector<char> read_binary_file(const char* path) { std::vector<char> read_binary_file(const char* path) {
std::ifstream istream(path, std::ios_base::ate | std::ios_base::binary); std::ifstream istream(path, std::ios_base::ate | std::ios_base::binary);
if(!istream.is_open()) if(!istream.is_open())

6
src/utils.h

@ -3,6 +3,12 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <array>
constexpr size_t UUID_SIZE = 16;
using Uuid = std::array<uint8_t, UUID_SIZE>;
Uuid make_uuid(uint8_t const* bytes);
template<typename T> template<typename T>

Loading…
Cancel
Save