diff options
author | Danny Holman <dholman@gymli.org> | 2025-08-04 12:32:39 -0500 |
---|---|---|
committer | Danny Holman <dholman@gymli.org> | 2025-08-04 12:32:39 -0500 |
commit | 7a268ae92d44a9f27f4874e1e50413ee33b86dd3 (patch) | |
tree | 47574f2a1d6c6d469e19627aacbcae03ae615dee | |
parent | render: vulkan: add check for null pointer for debug (diff) | |
download | rune-engine-7a268ae92d44a9f27f4874e1e50413ee33b86dd3.tar.gz rune-engine-7a268ae92d44a9f27f4874e1e50413ee33b86dd3.tar.zst rune-engine-7a268ae92d44a9f27f4874e1e50413ee33b86dd3.zip |
root: restructuring
Restructure the root of the project such that the engine is siloed from
the rest of the toolchain. Add two new subdirectories that contain an
editor and an offline profiling data analyzer.
Signed-off-by: Danny Holman <dholman@gymli.org>
-rw-r--r-- | CMake/SubmoduleDefines.cmake | 60 | ||||
-rw-r--r-- | CMakeLists.txt | 97 | ||||
-rw-r--r-- | editor/CMakeLists.txt | 13 | ||||
-rw-r--r-- | engine/CMakeLists.txt | 48 | ||||
-rw-r--r-- | engine/core/abort.c (renamed from core/abort.c) | 0 | ||||
-rw-r--r-- | engine/core/alloc.c (renamed from core/alloc.c) | 27 | ||||
-rw-r--r-- | engine/core/callbacks.c (renamed from core/callbacks.c) | 0 | ||||
-rw-r--r-- | engine/core/init.c (renamed from core/init.c) | 13 | ||||
-rw-r--r-- | engine/core/logging.c (renamed from core/logging.c) | 0 | ||||
-rw-r--r-- | engine/core/mod.c (renamed from core/mod.c) | 0 | ||||
-rw-r--r-- | engine/core/thread.c (renamed from core/thread.c) | 0 | ||||
-rw-r--r-- | engine/render/directx/renderer.c (renamed from render/directx/renderer.c) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/context.c (renamed from render/vulkan/context.c) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/context.h (renamed from render/vulkan/context.h) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/device.c (renamed from render/vulkan/device.c) | 120 | ||||
-rw-r--r-- | engine/render/vulkan/device.h (renamed from render/vulkan/device.h) | 2 | ||||
-rw-r--r-- | engine/render/vulkan/fence.c (renamed from render/vulkan/fence.c) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/fence.h (renamed from render/vulkan/fence.h) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/framebuffer.c (renamed from render/vulkan/framebuffer.c) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/framebuffer.h (renamed from render/vulkan/framebuffer.h) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/image.c (renamed from render/vulkan/image.c) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/image.h (renamed from render/vulkan/image.h) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/renderer.c (renamed from render/vulkan/renderer.c) | 18 | ||||
-rw-r--r-- | engine/render/vulkan/renderpass.c (renamed from render/vulkan/renderpass.c) | 4 | ||||
-rw-r--r-- | engine/render/vulkan/renderpass.h (renamed from render/vulkan/renderpass.h) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/swapchain.c (renamed from render/vulkan/swapchain.c) | 8 | ||||
-rw-r--r-- | engine/render/vulkan/swapchain.h (renamed from render/vulkan/swapchain.h) | 0 | ||||
-rw-r--r-- | engine/render/vulkan/vk_types.h (renamed from render/vulkan/vk_types.h) | 25 | ||||
-rw-r--r-- | engine/render/vulkan/vkassert.h (renamed from render/vulkan/vkassert.h) | 0 | ||||
-rw-r--r-- | profiler/CMakeLists.txt | 9 |
30 files changed, 312 insertions, 132 deletions
diff --git a/CMake/SubmoduleDefines.cmake b/CMake/SubmoduleDefines.cmake new file mode 100644 index 0000000..edd006b --- /dev/null +++ b/CMake/SubmoduleDefines.cmake @@ -0,0 +1,60 @@ +list(APPEND SUBMODULE_INCLUDE_DIRS ${SUBMODULE_HEADER_DIR}) + +include(EnableCFLAG) +if (MSVC) + enable_c_compiler_flag_if_supported("/GS") +else () + enable_c_compiler_flag_if_supported("-fstack-protector-all") +endif () + +if (WIN32) + find_package(dlfcn-win32 REQUIRED) + find_package(DBGHELP REQUIRED) + list(APPEND SUBMODULE_LINK_LIBS dlfcn-win32::dl ${DBGHELP_LIBRARY}) +endif() + +if (DEFINED SUBMODULE_LIBRARY) + add_definitions(-DRAPI_EXPORT) + set(SUBMODULE_BINARY ${SUBMODULE_LIBRARY}) + add_library(${SUBMODULE_BINARY} SHARED ${SUBMODULE_FILES}) + set_target_properties(${SUBMODULE_BINARY} PROPERTIES VERSION ${PROJECT_VERSION}) + set_target_properties(${SUBMODULE_BINARY} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) + target_include_directories(${SUBMODULE_BINARY} PUBLIC ${SUBMODULE_INCLUDE_DIRS}) + target_link_libraries(${SUBMODULE_BINARY} PUBLIC ${SUBMODULE_LINK_LIBS}) +elseif (DEFINED SUBMODULE_EXECUTABLE) + set(SUBMODULE_BINARY ${SUBMODULE_EXECUTABLE}) + add_executable(${SUBMODULE_BINARY} ${SUBMODULE_FILES}) + set_target_properties(${SUBMODULE_BINARY} PROPERTIES VERSION ${PROJECT_VERSION}) + target_include_directories(${SUBMODULE_BINARY} PRIVATE ${SUBMODULE_INCLUDE_DIRS}) + target_link_libraries(${SUBMODULE_BINARY} PRIVATE ${SUBMODULE_LINK_LIBS}) +else () + message(FATAL_ERROR "Unknown submodule type defined by submodule ${CMAKE_CURRENT_SOURCE_DIR}") +endif () + +target_compile_definitions(${SUBMODULE_BINARY} PUBLIC RUNE_VER="${CMAKE_PROJECT_VERSION}") +target_compile_definitions(${SUBMODULE_BINARY} PUBLIC RUNE_VER_MAJOR="${CMAKE_PROJECT_VERSION_MAJOR}") +target_compile_definitions(${SUBMODULE_BINARY} PUBLIC RUNE_VER_MINOR="${CMAKE_PROJECT_VERSION_MINOR}") +target_compile_definitions(${SUBMODULE_BINARY} PUBLIC RUNE_VER_PATCH="${CMAKE_PROJECT_VERSION_PATCH}") + +option(ENABLE_PROFILING "Enable profiling") +if (ENABLE_PROFILING) + target_compile_definitions(${SUBMODULE_BINARY} PUBLIC RUNE_PROFILING) +endif () + +include(GNUInstallDirs) +install(TARGETS ${SUBMODULE_BINARY} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT ${SUBMODULE_BINARY}_Runtime + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT ${SUBMODULE_BINARY}_Runtime + NAMELINK_COMPONENT ${SUBMODULE_BINARY}_Development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT ${SUBMODULE_BINARY}_Development +) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + ${SUBMODULE_BINARY}Version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90770d1..0fa8785 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,110 +1,31 @@ cmake_minimum_required(VERSION 3.20) project(rune-engine VERSION 0.63.0 DESCRIPTION "High performance game engine designed for Quake-style shooters") -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) -list(APPEND SOURCE_FILES - core/abort.c - core/alloc.c - core/callbacks.c - core/init.c - core/logging.c - core/mod.c - core/network.c - core/thread.c -) - -list(APPEND SOURCE_FILES - render/directx/renderer.c - render/vulkan/context.c - render/vulkan/device.c - render/vulkan/fence.c - render/vulkan/framebuffer.c - render/vulkan/image.c - render/vulkan/renderer.c - render/vulkan/renderpass.c - render/vulkan/swapchain.c - ui/window.c - ui/input.c -) - find_package(Vulkan REQUIRED) find_package(glfw3 REQUIRED) find_package(OpenAL REQUIRED) find_package(cglm REQUIRED) +find_package(json-c REQUIRED) find_package(Threads REQUIRED) -set(HEADER_DIR include) - -list(APPEND INCLUDE_DIRS - ${HEADER_DIR} +set(ENGINE_HEADER_DIR ${CMAKE_SOURCE_DIR}/include) +list(APPEND SUBMODULE_INCLUDE_DIRS + ${ENGINE_HEADER_DIR} ${Vulkan_INCLUDE_DIRS} ${GLFW_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR} ) -list(APPEND LINK_LIBS - ${Vulkan_LIBRARIES} - ${GLFW_LIBRARIES} - ${OPENAL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} -) - -if (WIN32) - find_package(dlfcn-win32 REQUIRED) - find_package(DBGHELP REQUIRED) - set(GLFW_LIBRARIES glfw3dll) - set(DX12_LIBRARIES d3d12.lib dxgi.lib dxguid.lib) - set(DL_LIBRARIES dlfcn-win32::dl) - list(APPEND LINK_LIBS ${DX12_LIBRARIES} ${DL_LIBRARIES} ${DBGHELP_LIBRARY}) -else () - set(GLFW_LIBRARIES glfw) -endif () - -include(EnableCFLAG) -if (MSVC) - enable_c_compiler_flag_if_supported("/GS") -else () - enable_c_compiler_flag_if_supported("-fstack-protector-all") -endif () - -list(APPEND LINK_LIBS ${GLFW_LIBRARIES}) - -add_compile_definitions(RUNE_VER="${PROJECT_VERSION}") -add_compile_definitions(RUNE_VER_MAJOR="${PROJECT_VERSION_MAJOR}") -add_compile_definitions(RUNE_VER_MINOR="${PROJECT_VERSION_MINOR}") -add_compile_definitions(RUNE_VER_PATCH="${PROJECT_VERSION_PATCH}") -add_compile_definitions(RAPI_EXPORT) -add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES}) - -set_property(TARGET ${PROJECT_NAME} PROPERTY ENABLE_EXPORTS ON) -target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS}) -target_link_libraries(${PROJECT_NAME} ${LINK_LIBS}) -set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) -set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) - +add_subdirectory("engine") +add_subdirectory("editor") +add_subdirectory("profiler") add_subdirectory("doc") -include(GNUInstallDirs) -install(TARGETS ${PROJECT_NAME} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - COMPONENT ${PROJECT_NAME}_Runtime - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT ${PROJECT_NAME}_Runtime - NAMELINK_COMPONENT ${PROJECT_NAME}_Development - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT ${PROJECT_NAME}_Development -) -install(DIRECTORY ${HEADER_DIR}/rune DESTINATION include) - -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - ${PROJECT_NAME}Version.cmake - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion -) +install(DIRECTORY ${ENGINE_HEADER_DIR}/rune DESTINATION include) diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt new file mode 100644 index 0000000..d633eb4 --- /dev/null +++ b/editor/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SUBMODULE_EXECUTABLE rune-editor) + +list(APPEND SUBMODULE_FILES + src/editor.c +) + +list(APPEND SUBMODULE_LINK_LIBS + rune-engine +) + +set(SUBMODULE_HEADER_DIR ${CMAKE_SOURCE_DIR}/editor/include) + +include(${CMAKE_SOURCE_DIR}/CMake/SubmoduleDefines.cmake) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt new file mode 100644 index 0000000..0d1465f --- /dev/null +++ b/engine/CMakeLists.txt @@ -0,0 +1,48 @@ +set(SUBMODULE_LIBRARY rune-engine) + +list(APPEND SUBMODULE_FILES + core/abort.c + core/alloc.c + core/callbacks.c + core/config.c + core/console.c + core/init.c + core/logging.c + core/mesh.c + core/mod.c + core/object.c + core/profiling.c + core/thread.c +) + +list(APPEND SUBMODULE_FILES + render/directx/renderer.c + render/vulkan/context.c + render/vulkan/device.c + render/vulkan/fence.c + render/vulkan/framebuffer.c + render/vulkan/image.c + render/vulkan/renderer.c + render/vulkan/renderpass.c + render/vulkan/swapchain.c + ui/input.c + ui/panel.c + ui/window.c + sound/sound.c +) + +list(APPEND SUBMODULE_LINK_LIBS + ${Vulkan_LIBRARIES} + ${GLFW_LIBRARIES} + ${OPENAL_LIBRARY} + json-c::json-c + ${CMAKE_THREAD_LIBS_INIT} +) + +if (WIN32) + list(APPEND SUBMODULE_LINK_LIBS glfw3dll d3d12.lib dxgi.lib dxguid.lib) +else () + list(APPEND SUBMODULE_LINK_LIBS glfw) +endif () + +include(${CMAKE_SOURCE_DIR}/CMake/SubmoduleDefines.cmake) diff --git a/core/abort.c b/engine/core/abort.c index 5ee42f6..5ee42f6 100644 --- a/core/abort.c +++ b/engine/core/abort.c diff --git a/core/alloc.c b/engine/core/alloc.c index 0ed705c..b75f1d3 100644 --- a/core/alloc.c +++ b/engine/core/alloc.c @@ -21,6 +21,7 @@ #include <rune/core/alloc.h> #include <rune/core/logging.h> +#include <rune/core/profiling.h> #include <stdlib.h> #include <string.h> @@ -55,19 +56,22 @@ static mem_block_t* _find_block(void *ptr) { } static mem_block_t* _alloc_block(size_t sz) { + RUNE_PROFILE_SCOPE("Block allocation"); if (first_block.ptr == NULL) { - first_block.ptr == DEADBLOCK; + first_block.ptr = DEADBLOCK; first_block.sz = 0; } mem_block_t *ret = _find_free_block(sz); if (ret != NULL) { ret->free = 0; + RUNE_PROFILE_END(); return ret->ptr; } ret = malloc(sizeof(mem_block_t)); if (ret == NULL) { + RUNE_PROFILE_END(); log_output(LOG_ERROR, "Cannot allocate block of size %d", sz); return NULL; } @@ -76,15 +80,18 @@ static mem_block_t* _alloc_block(size_t sz) { ret->sz = sz; ret->free = 0; list_add(&ret->list, &first_block.list); + RUNE_PROFILE_END(); log_output(LOG_DEBUG, "Alloc'd block of size %d", sz); return ret; } static void _free_block(mem_block_t *block, int hard) { + RUNE_PROFILE_SCOPE("Block free"); if (hard == 1) { list_del(&block->list); - log_output(LOG_DEBUG, "Freed block of size %d", block->sz); + RUNE_PROFILE_END(); free(block); + log_output(LOG_DEBUG, "Freed block of size %d", block->sz); return; } block->free = 1; @@ -94,13 +101,16 @@ void* rune_alloc(size_t sz) { if (sz == 0) return NULL; + RUNE_PROFILE_SCOPE("Pool allocation"); mem_block_t *block = _find_free_block(sz); if (block != NULL) { block->free = 0; + RUNE_PROFILE_END(); return block->ptr; } block = _alloc_block(sz); + RUNE_PROFILE_END(); return block->ptr; } @@ -108,14 +118,17 @@ void* rune_calloc(size_t nmemb, size_t sz) { if (sz == 0) return NULL; + RUNE_PROFILE_SCOPE("Zero array pool allocation"); mem_block_t *block = _find_free_block(sz); if (block != NULL) { block->free = 0; + RUNE_PROFILE_END(); return block->ptr; } block = _alloc_block(sz); memset(block->ptr, 0, sz); + RUNE_PROFILE_END(); return block->ptr; } @@ -123,10 +136,12 @@ void* rune_realloc(void *ptr, size_t sz) { if (ptr == NULL || sz == 0) return rune_alloc(sz); + RUNE_PROFILE_SCOPE("Pool reallocation"); mem_block_t *old = _find_block(ptr); mem_block_t *new = _alloc_block(sz); memcpy(new->ptr, old->ptr, old->sz); old->free = 1; + RUNE_PROFILE_END(); return new->ptr; } @@ -134,13 +149,18 @@ void rune_free(void *ptr) { if (ptr == NULL) return; + RUNE_PROFILE_SCOPE("Pool free"); mem_block_t *block = _find_block(ptr); - if (block->free == 1) + if (block->free == 1) { + RUNE_PROFILE_END(); return; + } block->free = 1; + RUNE_PROFILE_END(); } void rune_free_all(void) { + RUNE_PROFILE_SCOPE("Pool free all"); list_head_t *temp = &first_block.list; mem_block_t *block; while (temp != NULL) { @@ -154,4 +174,5 @@ void rune_free_all(void) { if (block->ptr != NULL) _free_block(block, 1); } + RUNE_PROFILE_END(); } diff --git a/core/callbacks.c b/engine/core/callbacks.c index ea7f50e..ea7f50e 100644 --- a/core/callbacks.c +++ b/engine/core/callbacks.c diff --git a/core/init.c b/engine/core/init.c index 5df4d04..6fcd086 100644 --- a/core/init.c +++ b/engine/core/init.c @@ -21,17 +21,28 @@ #include <rune/core/init.h> #include <rune/core/abort.h> +#include <rune/core/alloc.h> +#include <rune/core/config.h> #include <rune/core/logging.h> #include <rune/core/thread.h> +#include <rune/core/mod.h> +#include <rune/core/object.h> int rune_init(int argc, char* argv[]) { log_output(LOG_INFO, "Started Rune Engine version %s", RUNE_VER); - _parse_args(argc, argv); + + rune_init_default_settings(); rune_init_thread_api(); + + rune_load_mods(); + rune_init_mods(); + return 0; } void rune_exit(void) { log_output(LOG_INFO, "Engine shutdown requested"); + rune_clear_objs(); + rune_close_mods(); rune_free_all(); } diff --git a/core/logging.c b/engine/core/logging.c index b7f77bd..b7f77bd 100644 --- a/core/logging.c +++ b/engine/core/logging.c diff --git a/core/mod.c b/engine/core/mod.c index 3d9e710..3d9e710 100644 --- a/core/mod.c +++ b/engine/core/mod.c diff --git a/core/thread.c b/engine/core/thread.c index 3c5db8c..3c5db8c 100644 --- a/core/thread.c +++ b/engine/core/thread.c diff --git a/render/directx/renderer.c b/engine/render/directx/renderer.c index 8820441..8820441 100644 --- a/render/directx/renderer.c +++ b/engine/render/directx/renderer.c diff --git a/render/vulkan/context.c b/engine/render/vulkan/context.c index 1282706..1282706 100644 --- a/render/vulkan/context.c +++ b/engine/render/vulkan/context.c diff --git a/render/vulkan/context.h b/engine/render/vulkan/context.h index 15817e8..15817e8 100644 --- a/render/vulkan/context.h +++ b/engine/render/vulkan/context.h diff --git a/render/vulkan/device.c b/engine/render/vulkan/device.c index 583fb54..11d9433 100644 --- a/render/vulkan/device.c +++ b/engine/render/vulkan/device.c @@ -78,7 +78,7 @@ int _query_comp_index(int num_props, VkQueueFamilyProperties *qfam_props) { int _query_pres_index(int num_props, VkQueueFamilyProperties *qfam_props, VkPhysicalDevice pdev, VkSurfaceKHR surface) { VkBool32 present_bit; for (int i = 0; i < num_props; i++) { - vkGetPhysicalDeviceSurfaceSupportKHR(pdev, 0, surface, &present_bit); + vkGetPhysicalDeviceSurfaceSupportKHR(pdev, i, surface, &present_bit); if (present_bit != VK_FALSE) pres_qfam = i; } @@ -124,15 +124,47 @@ VkPhysicalDevice _select_pdev(VkInstance instance, VkSurfaceKHR surface) { return NULL; } -void _create_queue(vkdev_t *dev, int qfam_index, int queue_index) { - vkGetDeviceQueue(dev->ldev, qfam_index, queue_index, &dev->queues[qfam_index].handle); - if (dev->queues[qfam_index].handle == NULL) { +void _create_queue(vkdev_t *dev, int qfam_type, int qfam_index, int queue_index) { + VkQueue *queue_arr; + int num_queues; + switch (qfam_type) { + case QFAM_TYPE_GRAPHICS: + dev->num_gfx_queues++; + num_queues = dev->num_gfx_queues; + dev->gfx_queues = rune_realloc(dev->gfx_queues, sizeof(VkQueue)*num_queues); + queue_arr = dev->gfx_queues; + break; + case QFAM_TYPE_TRANSFER: + dev->num_tsfr_queues++; + num_queues = dev->num_tsfr_queues; + dev->gfx_queues = rune_realloc(dev->tsfr_queues, sizeof(VkQueue)*num_queues); + queue_arr = dev->tsfr_queues; + break; + case QFAM_TYPE_COMPUTE: + dev->num_comp_queues++; + num_queues = dev->num_comp_queues; + dev->gfx_queues = rune_realloc(dev->comp_queues, sizeof(VkQueue)*num_queues); + queue_arr = dev->comp_queues; + break; + case QFAM_TYPE_PRESENT: + if (dev->pres_queue != NULL) + rune_free(dev->pres_queue); + dev->pres_queue = rune_alloc(sizeof(VkQueue)); + queue_arr = dev->pres_queue; + break; + default: + log_output(LOG_FATAL, "Requested unknown queue type"); + rune_abort(); + } + + vkGetDeviceQueue(dev->ldev, qfam_index, queue_index, &queue_arr[num_queues-1]); + if (queue_arr[num_queues-1] == NULL) { log_output(LOG_FATAL, "Error creating required Vulkan queue"); rune_abort(); } } -vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { +vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface, int num_gfx, int num_tsfr, int num_comp, int presentable) { VkPhysicalDevice pdev = _select_pdev(instance, surface); if (pdev == NULL) { log_output(LOG_FATAL, "No device meets minimum requirements for rendering"); @@ -141,22 +173,58 @@ vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { vkdev_t *dev = rune_calloc(0, sizeof(vkdev_t)); dev->pdev = pdev; + dev->gfx_qfam = gfx_qfam; + dev->tsfr_qfam = tsfr_qfam; + dev->comp_qfam = comp_qfam; + dev->pres_qfam = pres_qfam; - dev->queues[0].qfam = gfx_qfam; - dev->queues[1].qfam = tsfr_qfam; - dev->queues[2].qfam = comp_qfam; - dev->queues[3].qfam = 0; + if (num_gfx > 0 && gfx_qfam == -1) { + log_output(LOG_FATAL, "Requested graphics queues but none found on device"); + rune_abort(); + } + if (num_tsfr > 0 && tsfr_qfam == -1) { + log_output(LOG_FATAL, "Requested transfer queues but none found on device"); + rune_abort(); + } + if (num_comp > 0 && comp_qfam == -1) { + log_output(LOG_FATAL, "Requested compute queues but none found on device"); + rune_abort(); + } + if (presentable == 1 && pres_qfam == -1) { + log_output(LOG_FATAL, "Requested presentation queue but none found on device"); + rune_abort(); + } - float queue_priority = 1.0f; - VkDeviceQueueCreateInfo qcinfos[3]; - for (int i = 0; i < 3; i++) { + int num_total = num_gfx + num_tsfr + num_comp + presentable; + int index = 0; + static const float queue_priority = 1.0f; + VkDeviceQueueCreateInfo *qcinfos = rune_alloc(sizeof(VkDeviceQueueCreateInfo)*num_total); + for (int i = 0; i < index+num_gfx; i++) { qcinfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; qcinfos[i].pNext = NULL; qcinfos[i].flags = 0; - qcinfos[i].queueFamilyIndex = dev->queues[i].qfam; + qcinfos[i].queueFamilyIndex = gfx_qfam; qcinfos[i].queueCount = 1; qcinfos[i].pQueuePriorities = &queue_priority; } + //index += num_gfx; + //for (int i = index; i < index+num_tsfr; i++) { + // qcinfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + // qcinfos[i].pNext = NULL; + // qcinfos[i].flags = 0; + // qcinfos[i].queueFamilyIndex = tsfr_qfam; + // qcinfos[i].queueCount = 1; + // qcinfos[i].pQueuePriorities = &queue_priority; + //} + //index += num_tsfr; + //for (int i = index; i < index+num_comp; i++) { + // qcinfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + // qcinfos[i].pNext = NULL; + // qcinfos[i].flags = 0; + // qcinfos[i].queueFamilyIndex = comp_qfam; + // qcinfos[i].queueCount = 1; + // qcinfos[i].pQueuePriorities = &queue_priority; + //} struct vkdev_data pdata; _query_pdev_data(pdev, &pdata); @@ -165,7 +233,7 @@ vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { dcinfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; dcinfo.pNext = NULL; dcinfo.flags = 0; - dcinfo.queueCreateInfoCount = 3; + dcinfo.queueCreateInfoCount = num_total; dcinfo.pQueueCreateInfos = qcinfos; dcinfo.enabledLayerCount = 0; dcinfo.ppEnabledLayerNames = NULL; @@ -174,26 +242,34 @@ vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface) { dcinfo.ppEnabledExtensionNames = &ext_names; dcinfo.pEnabledFeatures = &pdata.pdev_feats; vkassert(vkCreateDevice(dev->pdev, &dcinfo, NULL, &dev->ldev)); + rune_free(qcinfos); - for (uint32_t i = 0; i < 3; i++) - _create_queue(dev, i, 0); - - // FIXME: This is a dirty hack and should be fixed - dev->queues[3].handle = dev->queues[0].handle; + for (int i = 0; i < num_gfx; i++) + _create_queue(dev, QFAM_TYPE_GRAPHICS, gfx_qfam, i); + for (int i = 0; i < num_tsfr; i++) + _create_queue(dev, QFAM_TYPE_TRANSFER, tsfr_qfam, i); + for (int i = 0; i < num_comp; i++) + _create_queue(dev, QFAM_TYPE_COMPUTE, comp_qfam, i); VkCommandPoolCreateInfo pcinfo; pcinfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; pcinfo.pNext = NULL; pcinfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - pcinfo.queueFamilyIndex = dev->queues[0].qfam; - vkassert(vkCreateCommandPool(dev->ldev, &pcinfo, NULL, &dev->cmd_pool)); + pcinfo.queueFamilyIndex = gfx_qfam; + vkassert(vkCreateCommandPool(dev->ldev, &pcinfo, NULL, &dev->gfx_cmd_pool)); + pcinfo.queueFamilyIndex = tsfr_qfam; + vkassert(vkCreateCommandPool(dev->ldev, &pcinfo, NULL, &dev->tsfr_cmd_pool)); + pcinfo.queueFamilyIndex = comp_qfam; + vkassert(vkCreateCommandPool(dev->ldev, &pcinfo, NULL, &dev->comp_cmd_pool)); log_output(LOG_DEBUG, "Initialized new logical device"); return dev; } void destroy_vkdev(vkdev_t *dev) { - vkDestroyCommandPool(dev->ldev, dev->cmd_pool, NULL); + vkDestroyCommandPool(dev->ldev, dev->gfx_cmd_pool, NULL); + vkDestroyCommandPool(dev->ldev, dev->tsfr_cmd_pool, NULL); + vkDestroyCommandPool(dev->ldev, dev->comp_cmd_pool, NULL); vkDestroyDevice(dev->ldev, NULL); rune_free(dev); } diff --git a/render/vulkan/device.h b/engine/render/vulkan/device.h index b375c5b..3dab471 100644 --- a/render/vulkan/device.h +++ b/engine/render/vulkan/device.h @@ -24,7 +24,7 @@ #include "vk_types.h" -vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface); +vkdev_t* create_vkdev(VkInstance instance, VkSurfaceKHR surface, int num_gfx, int num_tsfr, int num_comp, int presentable); void destroy_vkdev(vkdev_t *dev); void get_swapchain_data(vkdev_t *dev, VkSurfaceKHR *surface); diff --git a/render/vulkan/fence.c b/engine/render/vulkan/fence.c index cee022e..cee022e 100644 --- a/render/vulkan/fence.c +++ b/engine/render/vulkan/fence.c diff --git a/render/vulkan/fence.h b/engine/render/vulkan/fence.h index 49a04fe..49a04fe 100644 --- a/render/vulkan/fence.h +++ b/engine/render/vulkan/fence.h diff --git a/render/vulkan/framebuffer.c b/engine/render/vulkan/framebuffer.c index 697bbb9..697bbb9 100644 --- a/render/vulkan/framebuffer.c +++ b/engine/render/vulkan/framebuffer.c diff --git a/render/vulkan/framebuffer.h b/engine/render/vulkan/framebuffer.h index dbf914d..dbf914d 100644 --- a/render/vulkan/framebuffer.h +++ b/engine/render/vulkan/framebuffer.h diff --git a/render/vulkan/image.c b/engine/render/vulkan/image.c index 0334e94..0334e94 100644 --- a/render/vulkan/image.c +++ b/engine/render/vulkan/image.c diff --git a/render/vulkan/image.h b/engine/render/vulkan/image.h index 067025d..067025d 100644 --- a/render/vulkan/image.h +++ b/engine/render/vulkan/image.h diff --git a/render/vulkan/renderer.c b/engine/render/vulkan/renderer.c index 679abef..f02d84f 100644 --- a/render/vulkan/renderer.c +++ b/engine/render/vulkan/renderer.c @@ -123,7 +123,11 @@ int _init_vulkan(window_t *window) { } context->dev = create_vkdev(context->instance, - context->surface->handle); + context->surface->handle, + 1, + 1, + 1, + 1); if (context->dev == NULL) return -1; @@ -238,11 +242,13 @@ int _end_frame(float time) { *img_in_flight = context->fences_in_flight[context->swapchain->frame]; fence_unlock(*img_in_flight, context->dev); - cmdbuf_submit(cmdbuf, - &context->queue_semaphores[context->swapchain->frame], - &context->image_semaphores[context->swapchain->frame], - context->dev->queues[0].handle, - (*img_in_flight)->handle); + for (int i = 0; i < context->dev->num_gfx_queues; i++) { + cmdbuf_submit(cmdbuf, + &context->queue_semaphores[context->swapchain->frame], + &context->image_semaphores[context->swapchain->frame], + context->dev->gfx_queues[i], + (*img_in_flight)->handle); + } vkswapchain_present(context->swapchain, context->dev, diff --git a/render/vulkan/renderpass.c b/engine/render/vulkan/renderpass.c index 981039a..e1e8743 100644 --- a/render/vulkan/renderpass.c +++ b/engine/render/vulkan/renderpass.c @@ -29,7 +29,7 @@ vkcmdbuffer_t* create_vkcmdbuffer(vkdev_t *dev, int primary) { VkCommandBufferAllocateInfo ainfo; ainfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; ainfo.pNext = NULL; - ainfo.commandPool = dev->cmd_pool; + ainfo.commandPool = dev->gfx_cmd_pool; if (primary == 1) ainfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; else @@ -42,7 +42,7 @@ vkcmdbuffer_t* create_vkcmdbuffer(vkdev_t *dev, int primary) { } void destroy_vkcmdbuffer(vkcmdbuffer_t *cmdbuffer, vkdev_t *dev) { - vkFreeCommandBuffers(dev->ldev, dev->cmd_pool, 1, &cmdbuffer->handle); + vkFreeCommandBuffers(dev->ldev, dev->gfx_cmd_pool, 1, &cmdbuffer->handle); rune_free(cmdbuffer); } diff --git a/render/vulkan/renderpass.h b/engine/render/vulkan/renderpass.h index 1524438..1524438 100644 --- a/render/vulkan/renderpass.h +++ b/engine/render/vulkan/renderpass.h diff --git a/render/vulkan/swapchain.c b/engine/render/vulkan/swapchain.c index 055d36f..36899de 100644 --- a/render/vulkan/swapchain.c +++ b/engine/render/vulkan/swapchain.c @@ -47,6 +47,8 @@ vkswapchain_t* create_swapchain(vksurface_t *surface, vkdev_t *dev) { VkSwapchainCreateInfoKHR cinfo; cinfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + cinfo.pNext = NULL; + cinfo.flags = 0; cinfo.surface = surface->handle; cinfo.minImageCount = img_count; cinfo.imageFormat = swapchain->format_khr.format; @@ -59,8 +61,8 @@ vkswapchain_t* create_swapchain(vksurface_t *surface, vkdev_t *dev) { cinfo.presentMode = VK_PRESENT_MODE_MAILBOX_KHR; cinfo.clipped = VK_TRUE; cinfo.oldSwapchain = NULL; - if (dev->queues[0].qfam != dev->queues[3].qfam) { - uint32_t qfams[] = {dev->queues[0].qfam, dev->queues[3].qfam}; + if (dev->gfx_qfam != dev->pres_qfam) { + uint32_t qfams[] = {dev->gfx_qfam, dev->pres_qfam}; cinfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; cinfo.queueFamilyIndexCount = 2; cinfo.pQueueFamilyIndices = qfams; @@ -140,7 +142,7 @@ void vkswapchain_present(vkswapchain_t *swapchain, vkdev_t *dev, VkSemaphore *re pinfo.pImageIndices = img_index; pinfo.pResults = NULL; - VkResult res = vkQueuePresentKHR(dev->queues[3].handle, &pinfo); + VkResult res = vkQueuePresentKHR(dev->pres_queue, &pinfo); if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) STUBBED("Recreate swapchain"); else if (res != VK_SUCCESS) diff --git a/render/vulkan/swapchain.h b/engine/render/vulkan/swapchain.h index 7c2e2a5..7c2e2a5 100644 --- a/render/vulkan/swapchain.h +++ b/engine/render/vulkan/swapchain.h diff --git a/render/vulkan/vk_types.h b/engine/render/vulkan/vk_types.h index c7610c9..2011771 100644 --- a/render/vulkan/vk_types.h +++ b/engine/render/vulkan/vk_types.h @@ -27,10 +27,10 @@ #include <GLFW/glfw3.h> #include <cglm/cglm.h> -typedef struct vkqueue { - uint32_t qfam; - VkQueue handle; -} vkqueue_t; +#define QFAM_TYPE_GRAPHICS 1 +#define QFAM_TYPE_TRANSFER 2 +#define QFAM_TYPE_COMPUTE 3 +#define QFAM_TYPE_PRESENT 4 typedef struct vksurface { VkSurfaceKHR handle; @@ -93,8 +93,21 @@ typedef struct vkdev { VkPhysicalDevice pdev; VkDevice ldev; vkswapchain_data_t scdata; - vkqueue_t queues[4]; - VkCommandPool cmd_pool; + VkQueue *gfx_queues; + int num_gfx_queues; + int gfx_qfam; + VkQueue *tsfr_queues; + int num_tsfr_queues; + int tsfr_qfam; + VkQueue *comp_queues; + int num_comp_queues; + int comp_qfam; + VkQueue *pres_queue; + int pres_qfam; + VkCommandPool gfx_cmd_pool; + VkCommandPool tsfr_cmd_pool; + VkCommandPool comp_cmd_pool; + VkCommandPool pres_cmd_pool; VkFormat depth_format; } vkdev_t; diff --git a/render/vulkan/vkassert.h b/engine/render/vulkan/vkassert.h index ca0a89d..ca0a89d 100644 --- a/render/vulkan/vkassert.h +++ b/engine/render/vulkan/vkassert.h diff --git a/profiler/CMakeLists.txt b/profiler/CMakeLists.txt new file mode 100644 index 0000000..a80b982 --- /dev/null +++ b/profiler/CMakeLists.txt @@ -0,0 +1,9 @@ +set(SUBMODULE_EXECUTABLE rune-profiler) + +list(APPEND SUBMODULE_FILES + src/profiler.c +) + +set(SUBMODULE_HEADER_DIR ${CMAKE_SOURCE_DIR}/profiler/include) + +include(${CMAKE_SOURCE_DIR}/CMake/SubmoduleDefines.cmake) |