Compare commits

..
1 Commits
Author SHA1 Message Date
everyonecancode bbccf7f0ba Add wrap dependency for vulkan headers
Don't expect the vulkan headers to be present on the development system. Instead, download the using meson wrap.

Signed-off-by: Piotr Krygier <piotrkrygier@everyonecancode.xyz>
2026-06-12 14:11:42 +02:00
11 changed files with 82 additions and 165 deletions

No files matched your search

+6 -6
View File
@@ -15,9 +15,11 @@ rse_graphics_sources = [
'src/window.c',
]
vulkan_headers_dep = dependency('VulkanHeaders')
vulkan_dep = dependency('Vulkan')
sdl3_dep = dependency('sdl3', version: '>=3.4.0', default_options : ['warning_level=0', 'werror=false'])
sdl3_dep = dependency('sdl3', version: '>=3.4.0')
freetype_dep = dependency('freetype2', version: '>=22.1.16')
glm_dep = dependency('cglm', version: '>=0.9.6', method: 'cmake')
@@ -30,12 +32,9 @@ stb = dependency('stb',
rse_graphics_lib = shared_library(
'rse_graphics',
rse_graphics_sources,
override_options: [
'warning_level=3',
'werror=true'
],
include_directories: ['../'],
dependencies: [
vulkan_headers_dep,
vulkan_dep,
vma_dep,
sdl3_dep,
@@ -50,9 +49,10 @@ rse_graphics_lib = shared_library(
rse_graphics_lib_dep = declare_dependency(
link_with: rse_graphics_lib,
dependencies: [
vulkan_headers_dep,
vulkan_dep,
vma_dep,
glm_dep
],
include_directories: include_directories('.')
)
)
+1 -2
View File
@@ -229,7 +229,7 @@ struct vulkan_handles
VkRenderPass render_pass;
VkSemaphore image_available_semaphores[SWAP_BUFFER_COUNT];
VkSemaphore render_finished_semaphores[SWAP_BUFFER_COUNT];
VkSemaphore timeline_semaphore;
VkFence in_flight_fences[SWAP_BUFFER_COUNT];
#ifndef NDEBUG
VkDebugUtilsMessengerEXT debug_messenger;
#endif // !NDEBUG
@@ -280,7 +280,6 @@ struct graphics_context_t
uint32_t queue_family_indices[QUEUE_FAMILY_INDEX_LAST_INDEX];
uint32_t current_frame;
uint32_t swapchain_images_count;
uint64_t frame_finished_idx;
SDL_Window* window_handle;
struct mvp_data_t mvp_data;
struct renderer_data_t renderer_data;
-11
View File
@@ -1,17 +1,8 @@
#include "rse_graphics.h"
#ifdef __unix__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wsign-compare"
#endif
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_log.h>
#include <SDL3/SDL_render.h>
#ifdef __unix__
#pragma GCC diagnostic pop
#endif
#include <cglm/util.h>
#include <stdint.h>
#include <stdlib.h>
@@ -119,8 +110,6 @@ rse_err_t rse_graphics_init(struct graphics_context_t* context)
{
rse_err_t status = RSE_ERROR_NO_ERROR;
SDL_Init(SDL_INIT_VIDEO);
STATUS_CHECK(window_init(&context->window_handle, &context->is_framebuffer_resized));
STATUS_CHECK(vulkan_init(context));
+44 -103
View File
@@ -16,7 +16,6 @@
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_vulkan.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <vk_mem_alloc.h>
@@ -212,23 +211,21 @@ static rse_err_t create_instance(VkInstance* instance)
/* Check if selected layers are supported*/
for (i = 0; i < enabled_instance_layers_count; ++i) {
for (j = 0; i < layersCount; ++j) {
for (j = 0; j < layersCount; ++j) {
if (strcmp(layer_properties[j].layerName, enabled_instance_layers_names[i]) == 0) {
supported = 1;
break;
}
}
if (supported == 0) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Selected layer is not supported: %s", layer_properties[j].layerName);
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Selected layer is not supported: %s", enabled_instance_layers_names[i]);
return RSE_ERROR_INTERNAL_ERROR;
}
supported = 0;
}
/* Check if selected extensions are supported*/
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "Enabled extensions names:");
for (i = 0; i < enabled_instance_extensions_count; ++i) {
SDL_LogDebug(SDL_LOG_CATEGORY_GPU, "\t-%s", enabled_instance_extensions_names[i]);
for (j = 0; j < extensionCount; ++j) {
if (strcmp(extensions_properties[j].extensionName, enabled_instance_extensions_names[i]) == 0) {
supported = 1;
@@ -358,50 +355,28 @@ static rse_err_t create_device(struct graphics_context_t* context)
uint32_t presentation_familiy_idx = 0;
uint32_t queue_families_property_count = 0U;
uint32_t enabled_device_extensions_count = 2;
VkBool32 device_feature_supported = VK_FALSE;
VkBool32 bindless_supported = VK_FALSE;
VkDeviceCreateInfo device_create_info = {0};
VkQueueFamilyProperties* queue_family_properties = NULL;
VkDeviceQueueCreateInfo device_queue_createinfos[2] = {0};
VkPhysicalDeviceFeatures2 physical_features2 = {0};
VkPhysicalDeviceSynchronization2Features synchronization2_features = {0};
VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore_features = {0};
VkPhysicalDeviceDescriptorIndexingFeatures indexing_features = {0};
const char* enabled_device_extensions_names[] = {
"VK_KHR_swapchain",
"VK_EXT_descriptor_indexing",
};
/* Enable synchronization2 features */
synchronization2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;
/* Enable timeline semaphores feature*/
timeline_semaphore_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES;
timeline_semaphore_features.pNext = &synchronization2_features;
/* Enable descriptor indexing for bindless textures */
/* Enable descriptori indexing for bindless textures */
indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
indexing_features.pNext = &timeline_semaphore_features;
physical_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
physical_features2.pNext = &indexing_features;
vkGetPhysicalDeviceFeatures2(context->vulkan_handles.physical_device, &physical_features2);
device_feature_supported = indexing_features.descriptorBindingPartiallyBound && indexing_features.runtimeDescriptorArray;
if (device_feature_supported == VK_FALSE) {
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Required features for bindless design is not supported");
return RSE_ERROR_INTERNAL_ERROR;
}
device_feature_supported = synchronization2_features.synchronization2;
if (device_feature_supported == VK_FALSE) {
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Required features for Synchronization2 is not supported");
return RSE_ERROR_INTERNAL_ERROR;
}
device_feature_supported = timeline_semaphore_features.timelineSemaphore;
if (device_feature_supported == VK_FALSE) {
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Required features for timeline semaphore is not supported");
bindless_supported = indexing_features.descriptorBindingPartiallyBound && indexing_features.runtimeDescriptorArray;
if (bindless_supported == VK_FALSE) {
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Required features for bindless design not supported");
return RSE_ERROR_INTERNAL_ERROR;
}
@@ -555,14 +530,11 @@ static rse_err_t create_memory_allocator(struct graphics_context_t* context)
static rse_err_t create_sync_objects(struct graphics_context_t* context)
{
VkSemaphoreCreateInfo semaphore_info = {0};
VkSemaphoreTypeCreateInfo semaphore_type = {0};
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphore_type.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
semaphore_type.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
semaphore_type.initialValue = 0;
semaphore_type.pNext = NULL;
VkFenceCreateInfo fenceInfo = {0};
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < SWAP_BUFFER_COUNT; ++i) {
if (VK_SUCCESS != vkCreateSemaphore(context->vulkan_handles.device,
@@ -572,28 +544,16 @@ static rse_err_t create_sync_objects(struct graphics_context_t* context)
VK_SUCCESS != vkCreateSemaphore(context->vulkan_handles.device,
&semaphore_info,
NULL,
&context->vulkan_handles.render_finished_semaphores[i])) {
&context->vulkan_handles.render_finished_semaphores[i]) ||
VK_SUCCESS != vkCreateFence(context->vulkan_handles.device,
&fenceInfo,
NULL,
&context->vulkan_handles.in_flight_fences[i])) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to create sync objects.");
return RSE_ERROR_INTERNAL_ERROR;
}
}
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphore_type.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
semaphore_type.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
semaphore_type.initialValue = 0;
semaphore_type.pNext = NULL;
semaphore_info.pNext = &semaphore_type;
if (VK_SUCCESS != vkCreateSemaphore(context->vulkan_handles.device,
&semaphore_info,
NULL,
&context->vulkan_handles.timeline_semaphore)) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to create timeline semaphore.");
return RSE_ERROR_INTERNAL_ERROR;
}
return RSE_ERROR_NO_ERROR;
}
@@ -631,23 +591,18 @@ rse_err_t vulkan_draw_frame(struct graphics_context_t* context)
rse_err_t status = RSE_ERROR_NO_ERROR;
uint32_t image_index = 0U;
VkResult result = VK_FALSE;
VkSubmitInfo2 submit_info = {0};
VkSubmitInfo submit_info = {0};
VkSemaphore wait_semaphores[1];
VkPipelineStageFlags wait_stages[1];
VkSemaphore signal_semaphores[1];
VkPresentInfoKHR present_info = {0};
VkSwapchainKHR swap_chains[1];
VkSemaphoreWaitInfo timeline_wait_info = {0};
VkSemaphoreSubmitInfo timeline_signal_info = {0};
VkSemaphoreSubmitInfo binary_signal_info = {0};
VkSemaphoreSubmitInfo binary_wait_info = {0};
VkSemaphoreSubmitInfo signal_infos[2] = {0};
VkCommandBufferSubmitInfo cmd_buffer_submit_info = {0};
timeline_wait_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
timeline_wait_info.pNext = NULL;
timeline_wait_info.pSemaphores = &context->vulkan_handles.timeline_semaphore;
timeline_wait_info.semaphoreCount = 1;
timeline_wait_info.pValues = &context->frame_finished_idx;
vkWaitSemaphores(context->vulkan_handles.device, &timeline_wait_info, UINT64_MAX);
vkWaitForFences(context->vulkan_handles.device,
1,
&context->vulkan_handles.in_flight_fences[context->current_frame],
VK_TRUE,
UINT64_MAX);
STATUS_CHECK(buffers_update(context));
@@ -666,47 +621,33 @@ rse_err_t vulkan_draw_frame(struct graphics_context_t* context)
return RSE_ERROR_INTERNAL_ERROR;
}
// update_uniform_buffers(context);
/* Only reset the fence if we are submitting work */
vkResetFences(context->vulkan_handles.device, 1, &context->vulkan_handles.in_flight_fences[context->current_frame]);
reset_command_buffer(context);
record_command_buffer(context, image_index);
context->frame_finished_idx++;
binary_signal_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
binary_signal_info.pNext = NULL;
binary_signal_info.semaphore = context->vulkan_handles.render_finished_semaphores[context->current_frame];
binary_signal_info.value = 0;
binary_signal_info.stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
timeline_signal_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
timeline_signal_info.pNext = NULL;
timeline_signal_info.semaphore = context->vulkan_handles.timeline_semaphore;
timeline_signal_info.value = context->frame_finished_idx;
timeline_signal_info.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
wait_semaphores[0] = context->vulkan_handles.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;
signal_infos[0] = binary_signal_info;
signal_infos[1] = timeline_signal_info;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &context->vulkan_handles.command_buffers[context->current_frame];
binary_wait_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
binary_wait_info.pNext = NULL;
binary_wait_info.semaphore = context->vulkan_handles.image_available_semaphores[context->current_frame];
binary_wait_info.value = 0;
binary_wait_info.stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
signal_semaphores[0] = context->vulkan_handles.render_finished_semaphores[image_index];
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = signal_semaphores;
cmd_buffer_submit_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
cmd_buffer_submit_info.pNext = NULL;
cmd_buffer_submit_info.commandBuffer = context->vulkan_handles.command_buffers[context->current_frame];
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
submit_info.pNext = NULL;
submit_info.commandBufferInfoCount = 1;
submit_info.pCommandBufferInfos = &cmd_buffer_submit_info;
submit_info.signalSemaphoreInfoCount = 2;
submit_info.pSignalSemaphoreInfos = signal_infos;
submit_info.waitSemaphoreInfoCount = 1;
submit_info.pWaitSemaphoreInfos = &binary_wait_info;
if (vkQueueSubmit2(context->vulkan_handles.graphics_queue, 1, &submit_info, NULL)) {
if (vkQueueSubmit(context->vulkan_handles.graphics_queue,
1,
&submit_info,
context->vulkan_handles.in_flight_fences[context->current_frame]) != VK_SUCCESS) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to submit draw command buffer!");
return RSE_ERROR_INTERNAL_ERROR;
}
@@ -744,8 +685,8 @@ void vulkan_deinit(struct graphics_context_t* context)
for (size_t i = 0; i < SWAP_BUFFER_COUNT; ++i) {
vkDestroySemaphore(context->vulkan_handles.device, context->vulkan_handles.image_available_semaphores[i], NULL);
vkDestroySemaphore(context->vulkan_handles.device, context->vulkan_handles.render_finished_semaphores[i], NULL);
vkDestroyFence(context->vulkan_handles.device, context->vulkan_handles.in_flight_fences[i], NULL);
}
vkDestroySemaphore(context->vulkan_handles.device, context->vulkan_handles.timeline_semaphore, NULL);
destroy_textures(context);
+5 -2
View File
@@ -1,9 +1,12 @@
project('RedScarfEngine',
['c', 'cpp'],
version: '0.0.1',
)
default_options: [
'warning_level=3',
'werror=true'
])
# add_project_arguments('-DWAYLAND=1', language : 'c')
add_project_arguments('-DWAYLAND=1', language : 'c')
subdir('utilities')
subdir('graphics')
@@ -0,0 +1,15 @@
project(
'vulkan-headers',
'c',
license: 'Apache-2.0',
version: '1.4.353',
meson_version: '>=0.56.0',
)
vulkan_api_xml = files('registry/vk.xml')
vulkan_headers_dep = declare_dependency(
include_directories: include_directories('include'),
)
meson.override_dependency('VulkanHeaders', vulkan_headers_dep)
-14
View File
@@ -1,14 +0,0 @@
[wrap-file]
directory = SDL3-3.4.12
source_url = https://github.com/libsdl-org/SDL/releases/download/release-3.4.12/SDL3-3.4.12.tar.gz
source_filename = SDL3-3.4.12.tar.gz
source_hash = f07b958a9ac5020fb7a44cadb957f658b2149c3c8abb4f63145fac9303249db7
source_fallback_url = https://wrapdb.mesonbuild.com/v2/sdl3_3.4.12-1/get_source/SDL3-3.4.12.tar.gz
patch_filename = sdl3_3.4.12-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/sdl3_3.4.12-1/get_patch
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl3_3.4.12-1/sdl3_3.4.12-1_patch.zip
patch_hash = 67e859d280c9cc2de422efebc4f1edf954984b59e79eddf6c92ab61d89cd874d
wrapdb_version = 3.4.12-1
[provide]
dependency_names = sdl3
+5 -10
View File
@@ -1,14 +1,9 @@
[wrap-file]
directory = Vulkan-Headers-1.4.346
source_url = https://github.com/KhronosGroup/Vulkan-Headers/archive/v1.4.346.tar.gz
source_filename = vulkan-headers-1.4.346.tar.gz
source_hash = 5bb77f5d7b460e255a9e51affc00d64354986b55cf577d8eab28529cad01fc80
source_fallback_url = https://wrapdb.mesonbuild.com/v2/vulkan-headers_1.4.346-1/get_source/vulkan-headers-1.4.346.tar.gz
patch_filename = vulkan-headers_1.4.346-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/vulkan-headers_1.4.346-1/get_patch
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/vulkan-headers_1.4.346-1/vulkan-headers_1.4.346-1_patch.zip
patch_hash = b85cbf6793193b28c5bd80858308b214816e66041b10ec00f0115b19f3a7a60e
wrapdb_version = 1.4.346-1
directory = Vulkan-Headers-1.4.353
source_url = https://github.com/KhronosGroup/Vulkan-Headers/archive/v1.4.353.tar.gz
source_filename = vulkan-headers-1.4.353.tar.gz
source_hash = aead572dd86def896eddac84cb31acb4ede28e3ac1ab97439d6ddd1b5a14d38e
patch_directory = vulkan_headers/
[provide]
dependency_names = VulkanHeaders
-9
View File
@@ -1,9 +0,0 @@
[wrap-file]
directory = Vulkan-ValidationLayers-1.2.158
source_url = https://github.com/KhronosGroup/Vulkan-ValidationLayers/archive/v1.2.158.tar.gz
source_filename = vulkan-validationlayers-1.2.158.tar.gz
source_hash = 9d7a6eba2db88b8af6457acce0b638324ca03cde2e9589ae96749114091c6e9e
patch_url = https://wrapdb.mesonbuild.com/v2/vulkan-validationlayers_1.2.158-2/get_patch
patch_filename = vulkan-validationlayers-1.2.158-2-wrap.zip
patch_hash = d38dae45ca6a7124ee8df045a8d5288390ab836b4d28c53234f90baee5c649fc
+1 -1
View File
@@ -132,7 +132,7 @@ rse_err_t file_read_bytes(const char* file_name, size_t* bytes_count, unsigned c
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Failed to open file for read: %s", real_path);
ret = RSE_ERROR_INTERNAL_ERROR;
goto file_close;
return ret;
}
fseek(file, 0, SEEK_END);
+5 -7
View File
@@ -5,14 +5,11 @@
#include "errors_common.h"
#define NS_TO_S(time) (time/1000000000)
float g_time = 0.0f;
float g_dt = 0.0f;
double g_last_time = 0.0;
rse_err_t time_init(void)
{
g_last_time = NS_TO_S((double)SDL_GetTicksNS());
g_time = g_last_time;
return RSE_ERROR_NO_ERROR;
}
@@ -24,12 +21,13 @@ double time_get_sec_from_start(void)
void time_update(void)
{
g_last_time = g_time;
g_time = NS_TO_S((double)SDL_GetTicksNS());
g_dt = g_time - g_last_time;
g_last_time = NS_TO_S((double)SDL_GetTicksNS());
}
double time_get_dt(void)
{
return g_dt;
float time = NS_TO_S((double)SDL_GetTicksNS());
float dt = time - g_last_time;
return dt;
}