[WIP] Refactor project
There are many problems with the way the current version is provided and maintained. This commit or series of commits will fix this.
This commit is contained in:
1 parent
f5ab5f3f27
commit
173a82b9d1
63 files changed
+2663
-2239
No files matched your search
+145
-164
@@ -23,22 +23,20 @@
|
||||
// #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
// #pragma GCC diagnostic ignored "-Wswitch"
|
||||
// #pragma GCC diagnostic ignored "-Wparentheses"
|
||||
#include "utilities/localization.h"
|
||||
#include "vk_mem_alloc.h"
|
||||
// #pragma GCC diagnostic pop
|
||||
|
||||
#include "locale_vulkan.h"
|
||||
#include "utilities/rse_errors_common.h"
|
||||
#include "utilities/errors_common.h"
|
||||
#include "utilities/logger.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
#include "vulkan_errors.h"
|
||||
#include "window.h"
|
||||
|
||||
#include "vulkan_commons.h"
|
||||
#include "rse_vulkan_commands.h"
|
||||
#include "vulkan_commands.h"
|
||||
#include "vulkan_buffers.h"
|
||||
#include "vulkan_descriptors.h"
|
||||
#include "vulkan_pipeline.h"
|
||||
#include "rse_vulkan_image.h"
|
||||
#include "vulkan_image.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -47,37 +45,7 @@
|
||||
#define APPLICATION_NAME "RedScarfEngine PoC"
|
||||
#define ENGINE_NAME "RedScarf Engine"
|
||||
|
||||
/* Define Validation Layers for debug build */
|
||||
#ifndef NDEBUG
|
||||
#define ENABLED_EXTENSIONS_COUT 4
|
||||
#define ENABLED_INSTANCE_LAYERS_COUNT 1
|
||||
const char* g_enabled_instance_layers_names[] = {"VK_LAYER_KHRONOS_validation"};
|
||||
#else
|
||||
#define ENABLED_EXTENSIONS_COUT 3
|
||||
#define ENABLED_INSTANCE_LAYERS_COUNT 0
|
||||
const char* g_enabled_instance_layers_names[] = {};
|
||||
#endif
|
||||
|
||||
const char* g_enabled_instance_extensions_names[ENABLED_EXTENSIONS_COUT] = {};
|
||||
|
||||
#define ENABLED_DEVICE_EXTENSIONS_COUT 1
|
||||
const char* g_enabled_device_extensions_names[] = {
|
||||
"VK_KHR_swapchain",
|
||||
};
|
||||
|
||||
|
||||
VkInstance g_vulkan_instance = VK_NULL_HANDLE;
|
||||
|
||||
VkDebugUtilsMessengerEXT g_debug_messenger = VK_NULL_HANDLE;
|
||||
VkQueue g_present_queue;
|
||||
|
||||
VkSemaphore g_image_available_semaphores[SWAP_BUFFER_COUNT] = {};
|
||||
VkSemaphore g_render_finished_semaphores[SWAP_BUFFER_COUNT] = {};
|
||||
VkFence g_in_flight_fences[SWAP_BUFFER_COUNT] = {};
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/**
|
||||
* @brief Calback for debug messenger
|
||||
*
|
||||
@@ -142,8 +110,10 @@ static VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugU
|
||||
/**
|
||||
* @brief Setup debugging system for Vulkan API
|
||||
*
|
||||
* @param context Graphics context
|
||||
*
|
||||
*/
|
||||
static rse_err_t setup_debug_messenger()
|
||||
static rse_err_t setup_debug_messenger(VkInstance instance, VkDebugUtilsMessengerEXT* messenger)
|
||||
{
|
||||
VkDebugUtilsMessengerCreateInfoEXT create_info = {0};
|
||||
|
||||
@@ -159,8 +129,8 @@ static rse_err_t setup_debug_messenger()
|
||||
create_info.pUserData = NULL; // Optional
|
||||
create_info.flags = 0U;
|
||||
|
||||
if (CreateDebugUtilsMessengerEXT(g_vulkan_instance, &create_info, NULL, &g_debug_messenger) != VK_SUCCESS) {
|
||||
LOGF(vulkan_messages[VULKAN_DEBUG_MESSENGER_SETUP_FAILED]);
|
||||
if (CreateDebugUtilsMessengerEXT(instance, &create_info, NULL, messenger) != VK_SUCCESS) {
|
||||
LOGF(_("Failed to setup debug messenger\n"));
|
||||
return VULKAN_ERROR_DEBUG_MESSENGER_CREATION_FAILED;
|
||||
}
|
||||
|
||||
@@ -186,46 +156,18 @@ static void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMesse
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/**
|
||||
* @brief Enable instance extensions, based on system and requirements
|
||||
*
|
||||
*/
|
||||
static void set_enabled_extension()
|
||||
{
|
||||
g_enabled_instance_extensions_names[0] = "VK_KHR_surface";
|
||||
g_enabled_instance_extensions_names[1] = "VK_KHR_device_group_creation";
|
||||
|
||||
#ifdef __linux__
|
||||
if (getenv("WAYLAND_DISPLAY") != NULL) {
|
||||
g_enabled_instance_extensions_names[2] = "VK_KHR_wayland_surface";
|
||||
} else {
|
||||
g_enabled_instance_extensions_names[2] = "VK_KHR_xcb_surface";
|
||||
}
|
||||
#elif defined(_WIN32) || defined(WIN32)
|
||||
g_enabled_instance_extensions_names[2] = "VK_KHR_win32_surface";
|
||||
#endif
|
||||
|
||||
/* Add custom extensions here and make VK_EXT_debug_utils last */
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
#ifndef NDEBUG
|
||||
g_enabled_instance_extensions_names[3] = "VK_EXT_debug_utils";
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create the Vulkan Instance object
|
||||
*
|
||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
||||
* VULKAN_ERROR_INSTANCE_INIT_FAILED
|
||||
*/
|
||||
static rse_err_t create_instance()
|
||||
static rse_err_t create_instance(VkInstance* instance)
|
||||
{
|
||||
size_t i = 0U;
|
||||
size_t j = 0U;
|
||||
uint8_t supported = 0U;
|
||||
VkResult result = VK_SUCCESS;
|
||||
uint32_t extensionCount = 0U;
|
||||
uint32_t layersCount = 0U;
|
||||
VkApplicationInfo application_info = {0};
|
||||
@@ -233,6 +175,35 @@ static rse_err_t create_instance()
|
||||
VkLayerProperties* layer_properties;
|
||||
VkExtensionProperties* extensions_properties;
|
||||
|
||||
const char* enabled_instance_extensions_names[] = {
|
||||
"VK_KHR_surface",
|
||||
"VK_KHR_device_group_creation",
|
||||
#ifdef __linux__
|
||||
#ifdef WAYLAND
|
||||
"VK_KHR_wayland_surface",
|
||||
#else
|
||||
"VK_KHR_xcb_surface",
|
||||
#endif /* WAYLAND */
|
||||
#elif defined(_WIN32) || defined(WIN32)
|
||||
"VK_KHR_win32_surface",
|
||||
#endif /* _WIN32 || WIN32 */
|
||||
#ifndef NDEBUG
|
||||
"VK_EXT_debug_utils",
|
||||
#endif /* NDEBUG */
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
uint32_t enabled_instance_extensions_count = 4;
|
||||
uint32_t enabled_instance_layers_count = 1;
|
||||
const char* enabled_instance_layers_names[] = {
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
};
|
||||
#else
|
||||
uint32_t enabled_instance_extensions_count = 3;
|
||||
uint32_t enabled_instance_layers_count = 0;
|
||||
const char* enabled_instance_layers_names[] = {};
|
||||
#endif /* NDEBUG */
|
||||
|
||||
vkEnumerateInstanceLayerProperties(&layersCount, NULL);
|
||||
rse_malloc(layer_properties, sizeof(VkLayerProperties) * layersCount);
|
||||
vkEnumerateInstanceLayerProperties(&layersCount, layer_properties);
|
||||
@@ -254,35 +225,38 @@ static rse_err_t create_instance()
|
||||
#endif
|
||||
|
||||
/* Check if selected layers are supported*/
|
||||
for (i = 0; i < ENABLED_INSTANCE_LAYERS_COUNT; ++i) {
|
||||
for (i = 0; i < enabled_instance_layers_count; ++i) {
|
||||
for(j = 0; i < layersCount; ++j) {
|
||||
if(strcmp(layer_properties[j].layerName, g_enabled_instance_layers_names[i]) == 0) {
|
||||
if(strcmp(layer_properties[j].layerName, enabled_instance_layers_names[i]) == 0) {
|
||||
supported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(supported == 0) {
|
||||
LOGF(vulkan_messages[VULKAN_LAYER_NOT_SUPPORTED], layer_properties[j].layerName);
|
||||
LOGF(_("Selected layer is not supported: %s\n"), layer_properties[j].layerName);
|
||||
return VULKAN_ERROR_LAYER_NOT_SUPPORTED;
|
||||
}
|
||||
supported = 0;
|
||||
}
|
||||
|
||||
/* Check if selected extensions are supported*/
|
||||
for (i = 0; i < ENABLED_EXTENSIONS_COUT; ++i) {
|
||||
for (i = 0; i < enabled_instance_extensions_count; ++i) {
|
||||
for(j = 0; j < extensionCount; ++j) {
|
||||
if(strcmp(extensions_properties[j].extensionName, g_enabled_instance_extensions_names[i]) == 0) {
|
||||
if(strcmp(extensions_properties[j].extensionName, enabled_instance_extensions_names[i]) == 0) {
|
||||
supported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(supported == 0) {
|
||||
LOGF(vulkan_messages[VULKAN_EXTENSION_NOT_SUPPORTED], extensions_properties[j].extensionName);
|
||||
LOGF(_("Selected extension is not supported: %s\n"), extensions_properties[j].extensionName);
|
||||
return VULKAN_ERROR_EXTENSION_NOT_SUPPORTED;
|
||||
}
|
||||
supported = 0;
|
||||
}
|
||||
|
||||
rse_free(layer_properties);
|
||||
rse_free(extensions_properties);
|
||||
|
||||
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
application_info.pNext = NULL;
|
||||
application_info.pApplicationName = APPLICATION_NAME;
|
||||
@@ -295,18 +269,18 @@ static rse_err_t create_instance()
|
||||
create_info.pNext = NULL;
|
||||
create_info.flags = 0U;
|
||||
create_info.pApplicationInfo = &application_info;
|
||||
create_info.enabledLayerCount = ENABLED_INSTANCE_LAYERS_COUNT;
|
||||
create_info.enabledLayerCount = enabled_instance_layers_count;
|
||||
#ifndef NDEBUG
|
||||
create_info.ppEnabledLayerNames = g_enabled_instance_layers_names;
|
||||
create_info.ppEnabledLayerNames = enabled_instance_layers_names;
|
||||
#else
|
||||
create_info.ppEnabledLayerNames = NULL;
|
||||
#endif
|
||||
create_info.enabledExtensionCount = ENABLED_EXTENSIONS_COUT;
|
||||
create_info.ppEnabledExtensionNames = g_enabled_instance_extensions_names;
|
||||
create_info.enabledExtensionCount = enabled_instance_extensions_count;
|
||||
create_info.ppEnabledExtensionNames = enabled_instance_extensions_names;
|
||||
|
||||
VkResult result = vkCreateInstance(&create_info, NULL, &g_vulkan_instance);
|
||||
result = vkCreateInstance(&create_info, NULL, instance);
|
||||
if (VK_SUCCESS != result) {
|
||||
LOGF(vulkan_messages[VULKAN_INTANCE_INIT_FAILED]);
|
||||
LOGF(_("Vulkan instance initialization failed\n"));
|
||||
return VULKAN_ERROR_INSTANCE_INIT_FAILED;
|
||||
}
|
||||
|
||||
@@ -318,10 +292,10 @@ static rse_err_t create_instance()
|
||||
*
|
||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
||||
*/
|
||||
static rse_err_t create_surface()
|
||||
static rse_err_t create_surface(VkInstance instance, GLFWwindow* window_handle, VkSurfaceKHR* surface)
|
||||
{
|
||||
if (VK_SUCCESS != glfwCreateWindowSurface(g_vulkan_instance, get_window_handle(), NULL, &g_vulkan_state.surface)) {
|
||||
LOGF(vulkan_messages[VULKAN_SURFACE_CREATION_FAILED]);
|
||||
if (VK_SUCCESS != glfwCreateWindowSurface(instance, window_handle, NULL, surface)) {
|
||||
LOGF(_("Failed to create window surface\n"));
|
||||
return VULKAN_ERROR_SURFACE_CREATION_FAILED;
|
||||
}
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
@@ -334,7 +308,7 @@ static rse_err_t create_surface()
|
||||
* VULKAN_ERROR_NO_PHYSICAL_DEVICE_FOUND
|
||||
* VULKAN_ERROR_NO_SUITABLE_PHYSICAL_DEVICE_FOUND
|
||||
*/
|
||||
static rse_err_t pick_physical_device()
|
||||
static rse_err_t pick_physical_device(VkInstance instance, VkPhysicalDevice* physical_device)
|
||||
{
|
||||
uint32_t physical_device_count = 0U;
|
||||
VkPhysicalDevice* physical_devices = NULL;
|
||||
@@ -342,16 +316,16 @@ static rse_err_t pick_physical_device()
|
||||
VkPhysicalDeviceFeatures device_features = {0};
|
||||
|
||||
/* Get number of existing physical devices */
|
||||
vkEnumeratePhysicalDevices(g_vulkan_instance, &physical_device_count, NULL);
|
||||
vkEnumeratePhysicalDevices(instance, &physical_device_count, NULL);
|
||||
|
||||
if (0 == physical_device_count) {
|
||||
LOGF(vulkan_messages[VULKAN_NO_PHYSICAL_DEVICES]);
|
||||
LOGF(_("No physical graphical physical devices found in system\n"));
|
||||
return VULKAN_ERROR_NO_PHYSICAL_DEVICE_FOUND;
|
||||
}
|
||||
|
||||
rse_malloc(physical_devices, sizeof(VkPhysicalDevice) * physical_device_count);
|
||||
|
||||
vkEnumeratePhysicalDevices(g_vulkan_instance, &physical_device_count, physical_devices);
|
||||
vkEnumeratePhysicalDevices(instance, &physical_device_count, physical_devices);
|
||||
|
||||
/* Check for suitability */
|
||||
for (size_t physicalDeviceIdx = 0U; physicalDeviceIdx < physical_device_count; ++physicalDeviceIdx) {
|
||||
@@ -363,14 +337,14 @@ static rse_err_t pick_physical_device()
|
||||
device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
|
||||
/* Application MUST have geometry shader */
|
||||
if (device_features.geometryShader) {
|
||||
g_vulkan_state.physical_device = physical_devices[physicalDeviceIdx];
|
||||
*physical_device = physical_devices[physicalDeviceIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (VK_NULL_HANDLE == g_vulkan_state.physical_device) {
|
||||
if (VK_NULL_HANDLE == physical_device) {
|
||||
/* No suitable device found */
|
||||
LOGF(vulkan_messages[VULKAN_NO_SUITABLE_PHYSICAL_DEVICES]);
|
||||
LOGF(_("No suitable physical device found\n"));
|
||||
return VULKAN_ERROR_NO_SUITABLE_PHYSICAL_DEVICE_FOUND;
|
||||
}
|
||||
|
||||
@@ -384,7 +358,7 @@ static rse_err_t pick_physical_device()
|
||||
* VULKAN_ERROR_QUEUE_NOT_SUPPORTED
|
||||
* VULKAN_ERROR_DEVICE_CREATION_FAILED
|
||||
*/
|
||||
static rse_err_t create_device()
|
||||
static rse_err_t create_device(struct graphics_context_t* context)
|
||||
{
|
||||
size_t device_queues_count = 0;
|
||||
uint32_t queue_families_property_count = 0U;
|
||||
@@ -398,6 +372,11 @@ static rse_err_t create_device()
|
||||
VkPhysicalDeviceFeatures2 physical_features2 = {0};
|
||||
VkPhysicalDeviceDescriptorIndexingFeatures indexing_features = {0};
|
||||
VkBool32 bindless_supported = VK_FALSE;
|
||||
uint32_t enabled_device_extensions_count = 2;
|
||||
const char* enabled_device_extensions_names[] = {
|
||||
"VK_KHR_swapchain",
|
||||
"VK_EXT_descriptor_indexing",
|
||||
};
|
||||
|
||||
/* Enable descriptori indexing for bindless textures */
|
||||
indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
|
||||
@@ -405,18 +384,18 @@ static rse_err_t create_device()
|
||||
physical_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
physical_features2.pNext = &indexing_features;
|
||||
|
||||
vkGetPhysicalDeviceFeatures2(g_vulkan_state.physical_device, &physical_features2);
|
||||
vkGetPhysicalDeviceFeatures2(context->physical_device, &physical_features2);
|
||||
|
||||
bindless_supported = indexing_features.descriptorBindingPartiallyBound && indexing_features.runtimeDescriptorArray;
|
||||
if (bindless_supported == VK_FALSE) {
|
||||
LOGF(vulkan_messages[VULKAN_BINDLESS_DESIGN_NOT_SUPPORTED]);
|
||||
LOGF(_("Required features for bindless design not supported\n"));
|
||||
return VULKAN_ERROR_MISSING_FEATURES_FOR_BINDLESS_DESIGN;
|
||||
}
|
||||
|
||||
/* Get information about supported queue families */
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(g_vulkan_state.physical_device, &queue_families_property_count, NULL);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(context->physical_device, &queue_families_property_count, NULL);
|
||||
rse_malloc(queue_family_properties, sizeof(VkQueueFamilyProperties) * queue_families_property_count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(g_vulkan_state.physical_device, &queue_families_property_count,
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(context->physical_device, &queue_families_property_count,
|
||||
queue_family_properties);
|
||||
|
||||
/* Get queue families that support graphics operations AND have most
|
||||
@@ -436,7 +415,7 @@ static rse_err_t create_device()
|
||||
|
||||
/* Check for family with surface support */
|
||||
VkBool32 presentSupport = VK_FALSE;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(g_vulkan_state.physical_device, familyIdx, g_vulkan_state.surface, &presentSupport);
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(context->physical_device, familyIdx, context->surface, &presentSupport);
|
||||
if (presentSupport) {
|
||||
presentation_familiy_idx = familyIdx;
|
||||
/* If this is the same queue family as in graphics family, don't increase queue count */
|
||||
@@ -453,11 +432,11 @@ static rse_err_t create_device()
|
||||
|
||||
/* This is not magic number ;P. We want to support exact number of required queues flags */
|
||||
if (0 > graphics_family_idx) {
|
||||
LOGF(vulkan_messages[VULKAN_QUEUE_NOT_SUPPORTED]);
|
||||
LOGF(_("Selected physical device does not support required queue capabilities\n"));
|
||||
return VULKAN_ERROR_QUEUE_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
g_vulkan_state.queue_family_indices[0] = graphics_family_idx;
|
||||
context->queue_family_indices[0] = graphics_family_idx;
|
||||
|
||||
rse_malloc(graphics_familiy_queue_priorities, sizeof(float) * queue_family_properties[graphics_family_idx].queueCount);
|
||||
|
||||
@@ -492,17 +471,21 @@ static rse_err_t create_device()
|
||||
device_create_info.pQueueCreateInfos = device_queue_createinfos;
|
||||
device_create_info.enabledLayerCount = 0;
|
||||
device_create_info.ppEnabledLayerNames = NULL;
|
||||
device_create_info.enabledExtensionCount = ENABLED_DEVICE_EXTENSIONS_COUT;
|
||||
device_create_info.ppEnabledExtensionNames = g_enabled_device_extensions_names;
|
||||
device_create_info.enabledExtensionCount = enabled_device_extensions_count;
|
||||
device_create_info.ppEnabledExtensionNames = enabled_device_extensions_names;
|
||||
device_create_info.pEnabledFeatures = NULL;
|
||||
|
||||
if (VK_SUCCESS != vkCreateDevice(g_vulkan_state.physical_device, &device_create_info, NULL, &g_vulkan_state.device)) {
|
||||
LOGF(vulkan_messages[VULKAN_FAILED_TO_CREATE_DEVICE]);
|
||||
if (VK_SUCCESS != vkCreateDevice(context->physical_device, &device_create_info, NULL, &context->device)) {
|
||||
LOGF(_("Failed to create logical device\n"));
|
||||
return VULKAN_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
vkGetDeviceQueue(g_vulkan_state.device, graphics_family_idx, 0, &g_vulkan_state.graphics_queue);
|
||||
vkGetDeviceQueue(g_vulkan_state.device, presentation_familiy_idx, 0, &g_present_queue);
|
||||
vkGetDeviceQueue(context->device, graphics_family_idx, 0, &context->graphics_queue);
|
||||
vkGetDeviceQueue(context->device, presentation_familiy_idx, 0, &context->present_queue);
|
||||
|
||||
rse_free(presentation_familiy_queue_priorities);
|
||||
rse_free(graphics_familiy_queue_priorities);
|
||||
rse_free(queue_family_properties);
|
||||
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
@@ -513,7 +496,7 @@ static rse_err_t create_device()
|
||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
||||
* VULKAN_ERROR_ALLOCATOR_CREATION_FAILED
|
||||
*/
|
||||
static rse_err_t create_memory_allocator()
|
||||
static rse_err_t create_memory_allocator(struct graphics_context_t* context)
|
||||
{
|
||||
VmaVulkanFunctions vulkan_functions = {0};
|
||||
vulkan_functions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
|
||||
@@ -521,13 +504,13 @@ static rse_err_t create_memory_allocator()
|
||||
|
||||
VmaAllocatorCreateInfo allocator_create_info = {0};
|
||||
allocator_create_info.vulkanApiVersion = VK_API_VERSION_1_3;
|
||||
allocator_create_info.physicalDevice = g_vulkan_state.physical_device;
|
||||
allocator_create_info.device = g_vulkan_state.device;
|
||||
allocator_create_info.instance = g_vulkan_instance;
|
||||
allocator_create_info.physicalDevice = context->physical_device;
|
||||
allocator_create_info.device = context->device;
|
||||
allocator_create_info.instance = context->instance;
|
||||
allocator_create_info.pVulkanFunctions = &vulkan_functions;
|
||||
|
||||
if (VK_SUCCESS != vmaCreateAllocator(&allocator_create_info, &g_vulkan_state.allocator)) {
|
||||
LOGF(vulkan_messages[VULKAN_ALLOCATOR_CREATION_FAILED]);
|
||||
if (VK_SUCCESS != vmaCreateAllocator(&allocator_create_info, &context->allocator)) {
|
||||
LOGF(_("Failed to create Vulkan Memory Allocator\n"));
|
||||
return VULKAN_ERROR_ALLOCATOR_CREATION_FAILED;
|
||||
}
|
||||
|
||||
@@ -541,7 +524,7 @@ static rse_err_t create_memory_allocator()
|
||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
||||
* VULKAN_ERROR_SYNCOBJCTS_CREATION_FAILED
|
||||
*/
|
||||
static rse_err_t create_sync_objects()
|
||||
static rse_err_t create_sync_objects(struct graphics_context_t* context)
|
||||
{
|
||||
VkSemaphoreCreateInfo semaphore_info = {};
|
||||
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
@@ -551,10 +534,10 @@ static rse_err_t create_sync_objects()
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
for (size_t i = 0; i < SWAP_BUFFER_COUNT; ++i) {
|
||||
if (VK_SUCCESS != vkCreateSemaphore(g_vulkan_state.device, &semaphore_info, NULL, &g_image_available_semaphores[i]) ||
|
||||
VK_SUCCESS != vkCreateSemaphore(g_vulkan_state.device, &semaphore_info, NULL, &g_render_finished_semaphores[i]) ||
|
||||
VK_SUCCESS != vkCreateFence(g_vulkan_state.device, &fenceInfo, NULL, &g_in_flight_fences[i])) {
|
||||
LOGF(vulkan_messages[VULKAN_SYNCOBJCTS_CREATION_FAILED]);
|
||||
if (VK_SUCCESS != vkCreateSemaphore(context->device, &semaphore_info, NULL, &context->image_available_semaphores[i]) ||
|
||||
VK_SUCCESS != vkCreateSemaphore(context->device, &semaphore_info, NULL, &context->render_finished_semaphores[i]) ||
|
||||
VK_SUCCESS != vkCreateFence(context->device, &fenceInfo, NULL, &context->in_flight_fences[i])) {
|
||||
LOGF(_("Failed to create sync objects.\n"));
|
||||
return VULKAN_ERROR_SYNCOBJCTS_CREATION_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -563,40 +546,38 @@ static rse_err_t create_sync_objects()
|
||||
}
|
||||
|
||||
|
||||
rse_err_t preinit_vulkan()
|
||||
rse_err_t init_vulkan(struct graphics_context_t* context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
|
||||
set_enabled_extension();
|
||||
STATUS_CHECK(create_instance());
|
||||
STATUS_CHECK(create_instance(&context->instance));
|
||||
#ifndef NDEBUG
|
||||
STATUS_CHECK(setup_debug_messenger());
|
||||
STATUS_CHECK(setup_debug_messenger(context->instance, &context->debug_messenger));
|
||||
#endif
|
||||
STATUS_CHECK(create_surface());
|
||||
STATUS_CHECK(pick_physical_device());
|
||||
STATUS_CHECK(create_device());
|
||||
STATUS_CHECK(create_memory_allocator());
|
||||
STATUS_CHECK(init_commands());
|
||||
STATUS_CHECK(create_buffers());
|
||||
STATUS_CHECK(init_vulkan_images());
|
||||
STATUS_CHECK(create_surface(context->instance, context->window_handle, &context->surface));
|
||||
STATUS_CHECK(pick_physical_device(context->instance, &context->physical_device));
|
||||
STATUS_CHECK(create_device(context));
|
||||
STATUS_CHECK(create_memory_allocator(context));
|
||||
STATUS_CHECK(init_commands(context));
|
||||
STATUS_CHECK(create_buffers(context));
|
||||
STATUS_CHECK(init_vulkan_images(context));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rse_err_t init_vulkan()
|
||||
rse_err_t run_vulkan(struct graphics_context_t* context)
|
||||
{
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
|
||||
STATUS_CHECK(create_pipeline());
|
||||
STATUS_CHECK(create_descriptors());
|
||||
STATUS_CHECK(create_sync_objects());
|
||||
STATUS_CHECK(create_descriptors(context));
|
||||
STATUS_CHECK(create_sync_objects(context));
|
||||
|
||||
rse_init_time();
|
||||
init_time();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rse_err_t draw_frame()
|
||||
rse_err_t draw_frame(struct graphics_context_t* context)
|
||||
{
|
||||
uint32_t image_index = 0U;
|
||||
VkResult result = VK_FALSE;
|
||||
@@ -607,46 +588,46 @@ rse_err_t draw_frame()
|
||||
VkPresentInfoKHR present_info = {0};
|
||||
VkSwapchainKHR swap_chains[1];
|
||||
|
||||
vkWaitForFences(g_vulkan_state.device, 1, &g_in_flight_fences[g_vulkan_state.current_frame], VK_TRUE, UINT64_MAX);
|
||||
vkWaitForFences(context->device, 1, &context->in_flight_fences[context->current_frame], VK_TRUE, UINT64_MAX);
|
||||
|
||||
rse_update_time();
|
||||
update_time();
|
||||
|
||||
result = vkAcquireNextImageKHR(g_vulkan_state.device, g_vulkan_state.swapchain, UINT64_MAX, g_image_available_semaphores[g_vulkan_state.current_frame],
|
||||
result = vkAcquireNextImageKHR(context->device, context->swapchain, UINT64_MAX, context->image_available_semaphores[context->current_frame],
|
||||
VK_NULL_HANDLE, &image_index);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
recreate_swapchain();
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
} else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
|
||||
LOGF(vulkan_messages[VULKAN_ACQUIRE_SWAPCHAIN_FAILED]);
|
||||
LOGF(_("Failed to acquire swapchain image\n"));
|
||||
return VULKAN_ERROR_ACQUIRE_SWAPCHAIN_FAILED;
|
||||
}
|
||||
|
||||
update_uniform_buffers();
|
||||
update_uniform_buffers(context);
|
||||
|
||||
/* Only reset the fence if we are submitting work */
|
||||
vkResetFences(g_vulkan_state.device, 1, &g_in_flight_fences[g_vulkan_state.current_frame]);
|
||||
reset_command_buffer();
|
||||
vkResetFences(context->device, 1, &context->in_flight_fences[context->current_frame]);
|
||||
reset_command_buffer(context);
|
||||
|
||||
record_command_buffer(image_index);
|
||||
record_command_buffer(context, image_index);
|
||||
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
wait_semaphores[0] = g_image_available_semaphores[g_vulkan_state.current_frame];
|
||||
wait_semaphores[0] = context->image_available_semaphores[context->current_frame];
|
||||
wait_stages[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = wait_semaphores;
|
||||
submit_info.pWaitDstStageMask = wait_stages;
|
||||
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &g_vulkan_state.command_buffers[g_vulkan_state.current_frame];
|
||||
submit_info.pCommandBuffers = &context->command_buffers[context->current_frame];
|
||||
|
||||
signal_semaphores[0] = g_render_finished_semaphores[g_vulkan_state.current_frame];
|
||||
signal_semaphores[0] = context->render_finished_semaphores[context->current_frame];
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = signal_semaphores;
|
||||
|
||||
if (vkQueueSubmit(g_vulkan_state.graphics_queue, 1, &submit_info, g_in_flight_fences[g_vulkan_state.current_frame]) != VK_SUCCESS) {
|
||||
LOGF(vulkan_messages[VULAKN_DRAW_FAILED]);
|
||||
if (vkQueueSubmit(context->graphics_queue, 1, &submit_info, context->in_flight_fences[context->current_frame]) != VK_SUCCESS) {
|
||||
LOGF(_("Failed to submit draw command buffer!\n"));
|
||||
return VULKAN_ERROR_DRAW_FAILED;
|
||||
}
|
||||
|
||||
@@ -655,49 +636,49 @@ rse_err_t draw_frame()
|
||||
present_info.waitSemaphoreCount = 1;
|
||||
present_info.pWaitSemaphores = signal_semaphores;
|
||||
|
||||
swap_chains[0] = g_vulkan_state.swapchain;
|
||||
swap_chains[0] = context->swapchain;
|
||||
present_info.swapchainCount = 1;
|
||||
present_info.pSwapchains = swap_chains;
|
||||
|
||||
present_info.pImageIndices = &image_index;
|
||||
|
||||
result = vkQueuePresentKHR(g_present_queue, &present_info);
|
||||
result = vkQueuePresentKHR(context->present_queue, &present_info);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || is_framebuffer_resized()) {
|
||||
reset_framebuffer_resized();
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || context->is_framebuffer_resized) {
|
||||
context->is_framebuffer_resized = false;
|
||||
recreate_swapchain();
|
||||
} else if (result != VK_SUCCESS) {
|
||||
LOGF(vulkan_messages[VULAKN_DRAW_FAILED]);
|
||||
LOGF(_("Failed to submit draw command buffer!\n"));
|
||||
return VULKAN_ERROR_DRAW_FAILED;
|
||||
}
|
||||
|
||||
g_vulkan_state.current_frame = (g_vulkan_state.current_frame + 1) % SWAP_BUFFER_COUNT;
|
||||
context->current_frame = (context->current_frame + 1) % SWAP_BUFFER_COUNT;
|
||||
|
||||
return RSE_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void deinit_vulkan()
|
||||
void deinit_vulkan(struct graphics_context_t* context)
|
||||
{
|
||||
cleanup_swapchain();
|
||||
destroy_descriptors();
|
||||
destroy_buffers();
|
||||
destroy_buffers(context);
|
||||
for (size_t i = 0; i < SWAP_BUFFER_COUNT; ++i) {
|
||||
vkDestroySemaphore(g_vulkan_state.device, g_image_available_semaphores[i], NULL);
|
||||
vkDestroySemaphore(g_vulkan_state.device, g_render_finished_semaphores[i], NULL);
|
||||
vkDestroyFence(g_vulkan_state.device, g_in_flight_fences[i], NULL);
|
||||
vkDestroySemaphore(context->device, context->image_available_semaphores[i], NULL);
|
||||
vkDestroySemaphore(context->device, context->render_finished_semaphores[i], NULL);
|
||||
vkDestroyFence(context->device, context->in_flight_fences[i], NULL);
|
||||
}
|
||||
|
||||
rse_destroy_textures();
|
||||
destroy_textures();
|
||||
|
||||
destroy_commands();
|
||||
destroy_commands(context);
|
||||
|
||||
destroy_pipeline();
|
||||
|
||||
vmaDestroyAllocator(g_vulkan_state.allocator);
|
||||
vkDestroyDevice(g_vulkan_state.device, NULL);
|
||||
vmaDestroyAllocator(context->allocator);
|
||||
vkDestroyDevice(context->device, NULL);
|
||||
#ifndef NDEBUG
|
||||
DestroyDebugUtilsMessengerEXT(g_vulkan_instance, g_debug_messenger, NULL);
|
||||
DestroyDebugUtilsMessengerEXT(context->instance, context->debug_messenger, NULL);
|
||||
#endif
|
||||
vkDestroySurfaceKHR(g_vulkan_instance, g_vulkan_state.surface, NULL);
|
||||
vkDestroyInstance(g_vulkan_instance, NULL);
|
||||
vkDestroySurfaceKHR(context->instance, context->surface, NULL);
|
||||
vkDestroyInstance(context->instance, NULL);
|
||||
}
|
||||
Reference in new issue
Block a user