Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d2a2ddde3 | ||
|
|
454aaba349 | ||
|
|
5f759a9dbd | ||
|
|
5ad0ac7fed | ||
|
|
1b5cc7a79c | ||
|
|
393b59ad5d | ||
|
|
9cb692344f | ||
|
|
bd05c03a12 | ||
|
|
45be08019e | ||
|
|
e80faf80b2 |
No files matched your search
@@ -1,2 +1,13 @@
|
|||||||
CompileFlags:
|
CompileFlags:
|
||||||
Add: -ferror-limit=1000
|
Add: [
|
||||||
|
"-ferror-limit=0",
|
||||||
|
"-Wall",
|
||||||
|
"-Wpedantic",
|
||||||
|
"-Werror",
|
||||||
|
"-Wno-gnu-statement-expression",
|
||||||
|
"-I./",
|
||||||
|
"-I./graphics",
|
||||||
|
"-I./utilites",
|
||||||
|
"-I./third_party/include",
|
||||||
|
]
|
||||||
|
|
||||||
+10
-3
@@ -38,9 +38,16 @@ bin/*
|
|||||||
# VSCode configurations
|
# VSCode configurations
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
# Third party libraires
|
|
||||||
third_party/
|
|
||||||
|
|
||||||
# Cache folder
|
# Cache folder
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
|
# Cmake cache files
|
||||||
|
CMakeCache.txt
|
||||||
|
|
||||||
|
# Since we are using conan, we can remove CMakeFiles folder
|
||||||
|
CMakeFiles/
|
||||||
|
|
||||||
|
# Clang specific files
|
||||||
|
.clangd
|
||||||
|
.clangd/
|
||||||
|
|
||||||
+2
-3
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.31)
|
||||||
project("RedScarfEngine"
|
project("RedScarfEngine"
|
||||||
VERSION 0.0.1
|
VERSION 0.0.1
|
||||||
DESCRIPTION "Vulkan based 3D engine"
|
DESCRIPTION "Vulkan based 3D engine"
|
||||||
@@ -6,8 +6,7 @@ project("RedScarfEngine"
|
|||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
|
||||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
|
||||||
|
|
||||||
add_subdirectory(red_scarf_engine)
|
add_subdirectory(red_scarf_engine)
|
||||||
add_subdirectory(utilities)
|
add_subdirectory(utilities)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"vendor": {
|
||||||
|
"conan": {}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"build/CMakePresets.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[requires]
|
||||||
|
vulkan-headers/1.4.309.0
|
||||||
|
vulkan-loader/1.4.309.0
|
||||||
|
libgettext/0.22
|
||||||
|
freetype/2.13.3
|
||||||
|
stb/cci.20240531
|
||||||
|
sdl/3.2.14
|
||||||
|
|
||||||
|
[generators]
|
||||||
|
CMakeDeps
|
||||||
|
CMakeToolchain
|
||||||
|
|
||||||
|
[options]
|
||||||
|
sdl/*:wayland=False
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[GLFW]
|
|
||||||
git_url = https://github.com/glfw/glfw.git
|
|
||||||
tag = 3.3.8
|
|
||||||
custom_commands = cd GLFW && mkdir build && cd build && cmake .. -D BUILD_SHARED_LIBS=ON && make
|
|
||||||
|
|
||||||
[Vulkan-SDK]
|
|
||||||
dl_url = https://sdk.lunarg.com/sdk/download/1.3.250.1/linux/vulkansdk-linux-x86_64-1.3.250.1.tar.gz
|
|
||||||
custom_commands = tar -xf Vulkan-SDK && mv 1.3.250.1 vulkan && rm Vulkan-SDK && cd vulkan && ./vulkansdk -j 4 glslang vulkan-headers loader layers tools shaderc vulkan-extensionlayer
|
|
||||||
|
|
||||||
[vma]
|
|
||||||
git_url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
|
||||||
tag = v3.0.1
|
|
||||||
|
|
||||||
[Criterion]
|
|
||||||
git_url = https://github.com/Snaipe/Criterion.git
|
|
||||||
tag = v2.4.2
|
|
||||||
custom_commands = cd Criterion && meson build && cd build && ninja
|
|
||||||
|
|
||||||
[stb]
|
|
||||||
git_url = https://github.com/nothings/stb.git
|
|
||||||
tag = master
|
|
||||||
|
|
||||||
[FreeType]
|
|
||||||
dl_url = https://download.savannah.gnu.org/releases/freetype/freetype-2.10.0.tar.gz
|
|
||||||
custom_commands = tar -xf FreeType && mv freetype-2.10.0 freetype && rm FreeType && cd freetype && cmake -E make_directory build && cmake -E chdir build cmake -D BUILD_SHARED_LIBS:BOOL=true .. && cmake --build build
|
|
||||||
|
|
||||||
[CMock]
|
|
||||||
git_url = https://github.com/throwtheswitch/cmock.git
|
|
||||||
custom_commands = cd cmock && bundle install
|
|
||||||
+17
-47
@@ -1,54 +1,21 @@
|
|||||||
find_package(Vulkan REQUIRED)
|
find_package(VulkanHeaders REQUIRED)
|
||||||
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
|
find_package(VulkanLoader REQUIRED)
|
||||||
find_package(glfw3 REQUIRED)
|
# find_package(vulkan-validationlayers)
|
||||||
find_package(FreeType REQUIRED)
|
find_package(freetype REQUIRED)
|
||||||
|
find_package(stb REQUIRED)
|
||||||
|
find_package(SDL3 REQUIRED)
|
||||||
|
|
||||||
find_package(Vulkan COMPONENTS glslc)
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -g")
|
||||||
find_program(glslc_executable NAMES glslc HINTS ${Vulkan_GLSLC_EXECUTABLE}/..)
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
|
add_library(graphics SHARED)
|
||||||
|
|
||||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders)
|
|
||||||
|
|
||||||
cmake_policy(SET CMP0116 NEW)
|
|
||||||
function(compile_shader)
|
|
||||||
cmake_parse_arguments(PARSE_ARGV 1 arg "" "ENV;FORMAT" "SOURCES")
|
|
||||||
foreach(source ${arg_SOURCES})
|
|
||||||
message(${source}.${arg_FORMAT})
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${source}.${arg_FORMAT}
|
|
||||||
DEPENDS ${source}
|
|
||||||
COMMAND
|
|
||||||
${glslc_executable}
|
|
||||||
-o ${source}.${arg_FORMAT}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${source}
|
|
||||||
)
|
|
||||||
endforeach()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
compile_shader(graphics
|
|
||||||
ENV opengl
|
|
||||||
FORMAT num
|
|
||||||
SOURCES
|
|
||||||
shaders/shader.vert
|
|
||||||
shaders/solid_objects.frag
|
|
||||||
shaders/on_screen_text.frag
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(graphics SHARED
|
|
||||||
shaders/shader.vert.num
|
|
||||||
shaders/solid_objects.frag.num
|
|
||||||
shaders/on_screen_text.frag.num
|
|
||||||
)
|
|
||||||
target_include_directories(graphics PRIVATE
|
target_include_directories(graphics PRIVATE
|
||||||
${PROJECT_SOURCE_DIR}
|
${PROJECT_SOURCE_DIR}
|
||||||
|
${PROJECT_SOURCE_DIR}/third_party/include/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${CMAKE_SOURCE_DIR}
|
${CMAKE_SOURCE_DIR}
|
||||||
${Vulkan_INCLUDE_DIR}
|
|
||||||
${vma_INCLUDE_DIR}
|
|
||||||
${glfw3_INCLUDE_DIR}
|
|
||||||
${stb_INCLUDE_DIR}
|
${stb_INCLUDE_DIR}
|
||||||
${FreeType_INCLUDE_DIR}
|
${freetype_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(graphics PRIVATE
|
target_sources(graphics PRIVATE
|
||||||
@@ -56,10 +23,10 @@ src/vma_port.cpp
|
|||||||
src/window.c
|
src/window.c
|
||||||
src/vulkan_base.c
|
src/vulkan_base.c
|
||||||
src/vulkan_commands.c
|
src/vulkan_commands.c
|
||||||
src/vulkan_buffers.c
|
|
||||||
src/rse_graphics.c
|
src/rse_graphics.c
|
||||||
src/math.c
|
src/math.c
|
||||||
src/mesh_controller.c
|
src/mesh_controller.c
|
||||||
|
src/vulkan_buffers.c
|
||||||
src/vulkan_commons.c
|
src/vulkan_commons.c
|
||||||
src/vulkan_image.c
|
src/vulkan_image.c
|
||||||
src/vulkan_render_pass.c
|
src/vulkan_render_pass.c
|
||||||
@@ -71,7 +38,10 @@ src/descriptor_builder.c
|
|||||||
|
|
||||||
target_link_libraries(graphics PUBLIC
|
target_link_libraries(graphics PUBLIC
|
||||||
utilities
|
utilities
|
||||||
${Vulkan_LIBRARIES}
|
vulkan-headers::vulkan-headers
|
||||||
glfw
|
Vulkan::Loader
|
||||||
${freetype}
|
# vulkan-validationlayers::vulkan-validationlayers
|
||||||
|
Freetype::Freetype
|
||||||
|
stb::stb
|
||||||
|
sdl::sdl
|
||||||
)
|
)
|
||||||
@@ -19,7 +19,7 @@ rse_err_t rse_graphics_init(struct rse_graphics_context_t** context);
|
|||||||
*
|
*
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success
|
||||||
*/
|
*/
|
||||||
rse_err_t rse_graphics_run(struct rse_graphics_context_t* context);
|
int rse_graphics_run(void* arg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#version 450
|
#version 450
|
||||||
#extension GL_EXT_nonuniform_qualifier : enable
|
#extension GL_EXT_nonuniform_qualifier : enable
|
||||||
|
|
||||||
layout(set = 1, binding = 1) uniform sampler2D texSampler[];
|
layout(set = 0, binding = 1) uniform sampler2D texSampler[];
|
||||||
|
|
||||||
layout(location = 0) in vec3 fragColor;
|
layout(location = 0) in vec3 fragColor;
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
|
|
||||||
#include "descriptor_builder.h"
|
#include "descriptor_builder.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "src/graphics_context.h"
|
#include "src/graphics_context.h"
|
||||||
|
#include "src/vulkan_commons.h"
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
#include "utilities/linked_list.h"
|
#include "utilities/linked_list.h"
|
||||||
@@ -30,7 +32,7 @@ struct descriptor_t
|
|||||||
VkDescriptorType type;
|
VkDescriptorType type;
|
||||||
uint32_t descriptor_count;
|
uint32_t descriptor_count;
|
||||||
VkShaderStageFlags shader_stages;
|
VkShaderStageFlags shader_stages;
|
||||||
VkSampler immutable_sampler;
|
VkSampler* immutable_sampler;
|
||||||
};
|
};
|
||||||
|
|
||||||
RSE_LINKED_LIST_DEFINE(descriptor_set_list_t, struct descriptor_t);
|
RSE_LINKED_LIST_DEFINE(descriptor_set_list_t, struct descriptor_t);
|
||||||
@@ -40,6 +42,7 @@ struct descriptor_set_handle_t
|
|||||||
VkDescriptorSet descriptor_sets;
|
VkDescriptorSet descriptor_sets;
|
||||||
VkDescriptorPool descriptor_pool;
|
VkDescriptorPool descriptor_pool;
|
||||||
VkDescriptorSetLayout descriptor_sets_layout;
|
VkDescriptorSetLayout descriptor_sets_layout;
|
||||||
|
struct descriptor_set_list_t* descriptor_set_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: When new descriptors are introduced to Vulkan, this enum has to be
|
/* FIXME: When new descriptors are introduced to Vulkan, this enum has to be
|
||||||
@@ -66,8 +69,38 @@ enum descriptor_type_id_t
|
|||||||
DESCRIPTOR_TYPE_ID_MAX_ENUM,
|
DESCRIPTOR_TYPE_ID_MAX_ENUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
rse_err_t descriptor_add_set(struct descriptor_set_list_t* descriptor_set_list, uint32_t binding, VkDescriptorType type,
|
rse_err_t descriptor_initialize_handle(struct descriptor_set_handle_t **descriptor_set_handle)
|
||||||
uint32_t descriptor_count, VkShaderStageFlags shader_stages, VkSampler sampler)
|
{
|
||||||
|
if (NULL != *descriptor_set_handle) {
|
||||||
|
LOGE(_("Desciptor already initialized\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_malloc(*descriptor_set_handle, sizeof(struct descriptor_set_handle_t));
|
||||||
|
(*descriptor_set_handle)->descriptor_set_list = NULL;
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_err_t descriptor_free_handle(struct descriptor_set_handle_t **descriptor_set_handle)
|
||||||
|
{
|
||||||
|
if (NULL == *descriptor_set_handle) {
|
||||||
|
LOGE(_("Provided NULL handle\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
RSE_LINKED_LIST_CLEAR((*descriptor_set_handle)->descriptor_set_list);
|
||||||
|
rse_free(*descriptor_set_handle);
|
||||||
|
|
||||||
|
*descriptor_set_handle = NULL;
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_err_t descriptor_add_set(struct descriptor_set_handle_t* descriptor_set_handle, uint32_t binding, VkDescriptorType type,
|
||||||
|
uint32_t descriptor_count, VkShaderStageFlags shader_stages, VkSampler* sampler)
|
||||||
{
|
{
|
||||||
struct descriptor_t descriptor_sets = {.binding = binding,
|
struct descriptor_t descriptor_sets = {.binding = binding,
|
||||||
.type = type,
|
.type = type,
|
||||||
@@ -75,13 +108,12 @@ rse_err_t descriptor_add_set(struct descriptor_set_list_t* descriptor_set_list,
|
|||||||
.shader_stages = shader_stages,
|
.shader_stages = shader_stages,
|
||||||
.immutable_sampler = sampler};
|
.immutable_sampler = sampler};
|
||||||
|
|
||||||
RSE_LINKED_LIST_PUSH_BACK(descriptor_set_list, descriptor_sets);
|
RSE_LINKED_LIST_PUSH_BACK(descriptor_set_handle->descriptor_set_list, descriptor_sets);
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t descriptors_build(struct graphics_context_t* context, struct descriptor_set_list_t* descriptors,
|
rse_err_t descriptors_build(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle)
|
||||||
struct descriptor_set_handle_t* descriptor_set_handle)
|
|
||||||
{
|
{
|
||||||
size_t iterator = 0U;
|
size_t iterator = 0U;
|
||||||
size_t pool_size_count = 0U;
|
size_t pool_size_count = 0U;
|
||||||
@@ -104,8 +136,20 @@ rse_err_t descriptors_build(struct graphics_context_t* context, struct descripto
|
|||||||
return RSE_ERROR_NULL_POINTER;
|
return RSE_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL == descriptor_set_handle) {
|
||||||
|
LOGF(_("Descriptor set handle is null.\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RSE_LINKED_LIST_IS_EMPTY(descriptor_set_handle->descriptor_set_list)) {
|
||||||
|
LOGF(_("Provided empty descriptors list\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
iterator = 0U;
|
iterator = 0U;
|
||||||
RSE_LINKED_LIST_FOREACH(descriptors, descriptor)
|
RSE_LINKED_LIST_FOREACH(descriptor_set_handle->descriptor_set_list, descriptor)
|
||||||
{
|
{
|
||||||
switch (descriptor->data.type) {
|
switch (descriptor->data.type) {
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||||
@@ -195,6 +239,7 @@ rse_err_t descriptors_build(struct graphics_context_t* context, struct descripto
|
|||||||
layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
layout_create_info.bindingCount = iterator;
|
layout_create_info.bindingCount = iterator;
|
||||||
layout_create_info.pBindings = layout_bindings;
|
layout_create_info.pBindings = layout_bindings;
|
||||||
|
|
||||||
if (VK_SUCCESS != vkCreateDescriptorSetLayout(context->device, &layout_create_info, NULL, &set_layout)) {
|
if (VK_SUCCESS != vkCreateDescriptorSetLayout(context->device, &layout_create_info, NULL, &set_layout)) {
|
||||||
LOGF(_("Failed to create descriptor sets layout\n"));
|
LOGF(_("Failed to create descriptor sets layout\n"));
|
||||||
return VULKAN_ERROR_DESCRIPTOR_SET_LAYOUT_CREATION_FAILED;
|
return VULKAN_ERROR_DESCRIPTOR_SET_LAYOUT_CREATION_FAILED;
|
||||||
@@ -204,7 +249,7 @@ rse_err_t descriptors_build(struct graphics_context_t* context, struct descripto
|
|||||||
* What I'm doing here is calculating minimum viable number of pool max sets. This is a bit tricky, as
|
* What I'm doing here is calculating minimum viable number of pool max sets. This is a bit tricky, as
|
||||||
* (unintuitively) we have to select the MINIMUM number of sets, not maximum. This makes sense, but is difficult to
|
* (unintuitively) we have to select the MINIMUM number of sets, not maximum. This makes sense, but is difficult to
|
||||||
* wrap headr around */
|
* wrap headr around */
|
||||||
RSE_LINKED_LIST_FOREACH(descriptors, descriptor)
|
RSE_LINKED_LIST_FOREACH(descriptor_set_handle->descriptor_set_list, descriptor)
|
||||||
{
|
{
|
||||||
switch (descriptor->data.type) {
|
switch (descriptor->data.type) {
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||||
@@ -308,10 +353,10 @@ rse_err_t descriptors_build(struct graphics_context_t* context, struct descripto
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate descriptors from the pool */
|
/* Allocate descriptors from the pool */
|
||||||
alloc_info.descriptorPool = &descriptor_pool;
|
alloc_info.descriptorPool = descriptor_pool;
|
||||||
alloc_info.descriptorSetCount =
|
alloc_info.descriptorSetCount =
|
||||||
pool_max_sets; /* TODO: Always allocating maximum number of sets? This might get weird */
|
pool_max_sets; /* TODO: Always allocating maximum number of sets? This might get weird */
|
||||||
alloc_info.pSetLayouts = set_layout;
|
alloc_info.pSetLayouts = &set_layout;
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
|
|
||||||
if (VK_SUCCESS != vkAllocateDescriptorSets(context->device, &alloc_info, &descriptor_sets)) {
|
if (VK_SUCCESS != vkAllocateDescriptorSets(context->device, &alloc_info, &descriptor_sets)) {
|
||||||
@@ -323,7 +368,84 @@ rse_err_t descriptors_build(struct graphics_context_t* context, struct descripto
|
|||||||
descriptor_set_handle->descriptor_sets = descriptor_sets;
|
descriptor_set_handle->descriptor_sets = descriptor_sets;
|
||||||
descriptor_set_handle->descriptor_sets_layout = set_layout;
|
descriptor_set_handle->descriptor_sets_layout = set_layout;
|
||||||
|
|
||||||
|
context->descriptor_sets = descriptor_set_handle;
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t descriptor_get_layouts()
|
rse_err_t descriptor_get_layout(struct descriptor_set_handle_t* descriptor_set_handle,
|
||||||
|
VkDescriptorSetLayout* descriptor_sets_layout)
|
||||||
|
{
|
||||||
|
if (NULL == descriptor_set_handle->descriptor_sets_layout) {
|
||||||
|
LOGF(_("Requested descriptor set layout is NULL\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*descriptor_sets_layout = descriptor_set_handle->descriptor_sets_layout;
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_err_t descriptor_get_vkhandle(struct descriptor_set_handle_t* descriptor_set_handle, VkDescriptorSet* descriptor_set)
|
||||||
|
{
|
||||||
|
if (NULL == descriptor_set_handle) {
|
||||||
|
LOGF(_("Provided handle is NULL\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*descriptor_set = descriptor_set_handle->descriptor_sets;
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_err_t descriptor_attach_image(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle, uint16_t texture_id, VkSampler sampler, uint32_t binding)
|
||||||
|
{
|
||||||
|
VkDescriptorImageInfo image_info = {0};
|
||||||
|
VkWriteDescriptorSet write_set = {0};
|
||||||
|
|
||||||
|
image_info.sampler = sampler;
|
||||||
|
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
image_info.imageView = context->texture_images[texture_id].image_view;
|
||||||
|
|
||||||
|
write_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
write_set.pImageInfo = &image_info;
|
||||||
|
write_set.dstSet = descriptor_set_handle->descriptor_sets;
|
||||||
|
write_set.dstBinding = binding;
|
||||||
|
write_set.dstArrayElement = 0U;
|
||||||
|
write_set.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; //TODO: Maybe not only samplers?
|
||||||
|
write_set.descriptorCount = 1;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(context->device, 1U, &write_set, 0, NULL);
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_err_t descriptor_attach_buffer(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle, struct vulkan_buffer_t* buffer, uint32_t binding, VkDescriptorType type)
|
||||||
|
{
|
||||||
|
VkDescriptorBufferInfo buffer_info = {0};
|
||||||
|
VkWriteDescriptorSet write_set = {0};
|
||||||
|
|
||||||
|
buffer_info.buffer = buffer->buffer;
|
||||||
|
buffer_info.offset = 0U;
|
||||||
|
buffer_info.range = buffer->allocated_size;
|
||||||
|
|
||||||
|
write_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
write_set.pBufferInfo = &buffer_info;
|
||||||
|
write_set.dstSet = descriptor_set_handle->descriptor_sets;
|
||||||
|
write_set.dstBinding = binding;
|
||||||
|
write_set.dstArrayElement = 0U;
|
||||||
|
write_set.descriptorType = type;
|
||||||
|
write_set.descriptorCount = 1;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(context->device, 1U, &write_set, 0, NULL);
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_descriptors(struct graphics_context_t* context)
|
||||||
|
{
|
||||||
|
vkDestroyDescriptorSetLayout(context->device, context->descriptor_sets->descriptor_sets_layout, NULL);
|
||||||
|
vkDestroyDescriptorPool(context->device, context->descriptor_sets->descriptor_pool, NULL);
|
||||||
|
}
|
||||||
@@ -12,13 +12,34 @@
|
|||||||
#ifndef DESCRIPTOR_BUILDER_H
|
#ifndef DESCRIPTOR_BUILDER_H
|
||||||
#define DESCRIPTOR_BUILDER_H
|
#define DESCRIPTOR_BUILDER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include "graphics_context.h"
|
||||||
|
|
||||||
struct descriptor_set_handle_t;
|
struct descriptor_set_handle_t;
|
||||||
struct descriptor_set_list_t;
|
struct descriptor_set_list_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize new descriptor set handle
|
||||||
|
*
|
||||||
|
* @param descriptor_set_handle Handle to initialize
|
||||||
|
* #return RSE_ERROR_NO_ERROR on success
|
||||||
|
*/
|
||||||
|
rse_err_t descriptor_initialize_handle(struct descriptor_set_handle_t **descriptor_set_handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroy descritptor set handle
|
||||||
|
*
|
||||||
|
* @param descriptor_set_handle Handle to destroy
|
||||||
|
* @return RSE_ERROR_NO_ERROR on succes
|
||||||
|
*/
|
||||||
|
rse_err_t descriptor_free_handle(struct descriptor_set_handle_t **descriptor_set_handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add descriptor set to provided list
|
* @brief Add descriptor set to provided list
|
||||||
*
|
*
|
||||||
* @param descriptor_set_list List to be filled
|
* @param descriptor_set_handle Handle for given descriptor set
|
||||||
* @param binding Descriptors binding
|
* @param binding Descriptors binding
|
||||||
* @param type Type of descriptors
|
* @param type Type of descriptors
|
||||||
* @param descriptor_count Number of descriptors in this set
|
* @param descriptor_count Number of descriptors in this set
|
||||||
@@ -26,18 +47,38 @@ struct descriptor_set_list_t;
|
|||||||
* @param sampler If descriptor set is a sampler, provide it here
|
* @param sampler If descriptor set is a sampler, provide it here
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success, error code on failure
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success, error code on failure
|
||||||
*/
|
*/
|
||||||
rse_err_t descriptor_add_set(struct descriptor_set_list_t* descriptor_set_list, uint32_t binding, VkDescriptorType type,
|
rse_err_t descriptor_add_set(struct descriptor_set_handle_t* descriptor_set_handle, uint32_t binding, VkDescriptorType type,
|
||||||
uint32_t descriptor_count, VkShaderStageFlags shader_stages, VkSampler sampler);
|
uint32_t descriptor_count, VkShaderStageFlags shader_stages, VkSampler* sampler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate descriptor sets from provided list. The data will be stored in opaque descriptor handle
|
* @brief Allocate descriptor sets from provided list. The data will be stored in opaque descriptor handle
|
||||||
*
|
*
|
||||||
* @param context Graphics context
|
* @param context Graphics context
|
||||||
* @param descriptors List of descriptors to build descriptor handle from.
|
|
||||||
* @param descriptor_set_handle Opaque descriptor handle object.
|
* @param descriptor_set_handle Opaque descriptor handle object.
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success, error code on failure
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success, error code on failure
|
||||||
*/
|
*/
|
||||||
rse_err_t descriptors_build(struct graphics_context_t* context, struct descriptor_set_list_t* descriptors,
|
rse_err_t descriptors_build(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle);
|
||||||
struct descriptor_set_handle_t* descriptor_set_handle);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return descriptor set layouts from descritptor handle
|
||||||
|
*
|
||||||
|
* @param descriptor_set_handle Handle for descriptor set
|
||||||
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success
|
||||||
|
*/
|
||||||
|
rse_err_t descriptor_get_layout(struct descriptor_set_handle_t* descriptor_set_handle,
|
||||||
|
VkDescriptorSetLayout* descritptor_sets_layout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get VkDescriptorSet from descriptor handle
|
||||||
|
*
|
||||||
|
* @param descriptor_set_handle_t Handle to get VkDescriptorSet from
|
||||||
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success
|
||||||
|
*/
|
||||||
|
rse_err_t descriptor_get_vkhandle(struct descriptor_set_handle_t* descriptor_set_handle, VkDescriptorSet* descriptor_set);
|
||||||
|
|
||||||
|
rse_err_t descriptor_attach_buffer(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle, struct vulkan_buffer_t* buffer, uint32_t binding, VkDescriptorType type);
|
||||||
|
|
||||||
|
rse_err_t descriptor_attach_image(struct graphics_context_t* context, struct descriptor_set_handle_t* descriptor_set_handle, uint16_t texture_id, VkSampler sampler, uint32_t binding);
|
||||||
|
|
||||||
|
void destroy_descriptors(struct graphics_context_t* context);
|
||||||
#endif // !DESCRIPTOR_BUILDER_H
|
#endif // !DESCRIPTOR_BUILDER_H
|
||||||
@@ -12,17 +12,17 @@
|
|||||||
#ifndef GRAPHICS_CONTEXT_H
|
#ifndef GRAPHICS_CONTEXT_H
|
||||||
#define GRAPHICS_CONTEXT_H
|
#define GRAPHICS_CONTEXT_H
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include "SDL3/SDL.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vma/vk_mem_alloc.h>
|
#include "vma/vk_mem_alloc.h"
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
#include "utilities/linked_list.h"
|
#include "utilities/linked_list.h"
|
||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
#include "vulkan_commons.h"
|
#include "vulkan_commons.h"
|
||||||
|
|
||||||
#define MAX_MESH_NUMBER 256
|
#define MAX_MESH_NUMBER 2
|
||||||
#define MAX_INSTANCE_NUMBER 256
|
#define MAX_INSTANCE_NUMBER 256
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +34,8 @@
|
|||||||
#define MAX_PIPELINE_COUNT 16
|
#define MAX_PIPELINE_COUNT 16
|
||||||
|
|
||||||
RSE_LINKED_LIST_DEFINE(shader_module_list_t, VkShaderModule);
|
RSE_LINKED_LIST_DEFINE(shader_module_list_t, VkShaderModule);
|
||||||
|
RSE_LINKED_LIST_DEFINE(vulkan_buffer_list_t, struct vulkan_buffer_t);
|
||||||
|
RSE_LINKED_LIST_DEFINE(descriptor_sets_list_t, VkDescriptorSet);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Represents data within vertex or instance buffer.
|
* @brief Represents data within vertex or instance buffer.
|
||||||
@@ -93,7 +95,8 @@ struct pipeline_internal_t
|
|||||||
|
|
||||||
struct graphics_context_t
|
struct graphics_context_t
|
||||||
{
|
{
|
||||||
GLFWwindow* window_handle;
|
SDL_Window* window_handle;
|
||||||
|
VkSampler sampler;
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
@@ -114,19 +117,18 @@ struct graphics_context_t
|
|||||||
VkSemaphore render_finished_semaphores[SWAP_BUFFER_COUNT];
|
VkSemaphore render_finished_semaphores[SWAP_BUFFER_COUNT];
|
||||||
VkFence in_flight_fences[SWAP_BUFFER_COUNT];
|
VkFence in_flight_fences[SWAP_BUFFER_COUNT];
|
||||||
struct pipeline_internal_t pipelines_data;
|
struct pipeline_internal_t pipelines_data;
|
||||||
#ifndef NDEBUG
|
struct descriptor_set_handle_t* descriptor_sets;
|
||||||
VkDebugUtilsMessengerEXT debug_messenger;
|
VkDebugUtilsMessengerEXT debug_messenger;
|
||||||
#endif // !NDEBUG
|
|
||||||
bool is_framebuffer_resized; // TODO: Consider moving this to heap
|
bool is_framebuffer_resized; // TODO: Consider moving this to heap
|
||||||
uint32_t current_frame;
|
uint32_t current_frame;
|
||||||
uint32_t queue_family_indices[1];
|
uint32_t queue_family_indices[1];
|
||||||
struct vulkan_buffer_t uniform_buffers[SWAP_BUFFER_COUNT];
|
|
||||||
/* GPU visible buffer */
|
/* GPU visible buffer */
|
||||||
size_t vertex_offset;
|
size_t vertex_offset;
|
||||||
struct vulkan_buffer_t vertex_buffer;
|
struct vulkan_buffer_t vertex_buffer;
|
||||||
struct vulkan_buffer_t index_buffer;
|
struct vulkan_buffer_t index_buffer;
|
||||||
struct vulkan_buffer_t instance_buffers[MAX_MESH_NUMBER];
|
struct vulkan_buffer_t instance_buffers[MAX_MESH_NUMBER];
|
||||||
struct vulkan_buffer_t draw_indirect_command_buffer;
|
struct vulkan_buffer_t draw_indirect_command_buffer;
|
||||||
|
struct vulkan_buffer_list_t* uniform_buffers;
|
||||||
struct vulkan_image_t texture_images[RSE_MAX_IMAGE_COUNT];
|
struct vulkan_image_t texture_images[RSE_MAX_IMAGE_COUNT];
|
||||||
struct vulkan_image_t depth_image;
|
struct vulkan_image_t depth_image;
|
||||||
struct vulkan_image_t color_image;
|
struct vulkan_image_t color_image;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "descriptor_builder.h"
|
#include "src/descriptor_builder.h"
|
||||||
#include "src/graphics_context.h"
|
#include "src/graphics_context.h"
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
#include "utilities/localization.h"
|
#include "utilities/localization.h"
|
||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
#include "vulkan_errors.h"
|
#include "vulkan_errors.h"
|
||||||
#include "vulkan_image.h"
|
|
||||||
|
|
||||||
#define MAX_BINDLESS_RESOURCES 1000
|
#define MAX_BINDLESS_RESOURCES 1000
|
||||||
|
|
||||||
@@ -58,6 +57,7 @@ struct pipeline_t
|
|||||||
struct shader_attribute_list_t* shader_attributes;
|
struct shader_attribute_list_t* shader_attributes;
|
||||||
struct dynamic_state_list_t* dynamic_states;
|
struct dynamic_state_list_t* dynamic_states;
|
||||||
struct required_dynamic_states_t required_dynamic_states;
|
struct required_dynamic_states_t required_dynamic_states;
|
||||||
|
struct descriptor_set_handle_t* descriptor_sets;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,17 +210,19 @@ static rse_err_t pipeline_add_depth_stencil(struct pipeline_t* pipeline)
|
|||||||
* VULKAN_ERROR_PIPELINE_LAYOUT_CREATION_FAILED
|
* VULKAN_ERROR_PIPELINE_LAYOUT_CREATION_FAILED
|
||||||
*/
|
*/
|
||||||
static rse_err_t create_pipeline_layout(struct graphics_context_t* context,
|
static rse_err_t create_pipeline_layout(struct graphics_context_t* context,
|
||||||
struct descriptors_set_handle_t* descriptor_set_handle)
|
struct descriptor_set_handle_t* descriptor_set_handle)
|
||||||
{
|
{
|
||||||
uint32_t descriptor_set_layouts_count = 0;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
VkDescriptorSetLayout descriptor_set_layouts = VK_NULL_HANDLE;
|
VkDescriptorSetLayout descriptor_sets_layouts = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
STATUS_CHECK(descriptor_get_layout(descriptor_set_handle, &descriptor_sets_layouts));
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo create_info = {0};
|
VkPipelineLayoutCreateInfo create_info = {0};
|
||||||
create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
create_info.pNext = NULL;
|
create_info.pNext = NULL;
|
||||||
create_info.flags = 0U;
|
create_info.flags = 0U;
|
||||||
create_info.setLayoutCount = context->pipelines_data.descriptor_set_layouts_count;
|
create_info.setLayoutCount = 1; // FIXME: Make sure we can enable more than one layout
|
||||||
create_info.pSetLayouts = context->pipelines_data.descriptor_set_layouts;
|
create_info.pSetLayouts = &descriptor_sets_layouts;
|
||||||
create_info.pushConstantRangeCount = 0U;
|
create_info.pushConstantRangeCount = 0U;
|
||||||
create_info.pPushConstantRanges = NULL;
|
create_info.pPushConstantRanges = NULL;
|
||||||
|
|
||||||
@@ -385,7 +387,7 @@ rse_err_t pipeline_add_vertex_input_attribute(struct pipeline_t* pipeline, const
|
|||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t pipelines_build(struct graphics_context_t* context, struct pipeline_infos_list_t* pipelines_infos_list)
|
rse_err_t pipelines_build(struct graphics_context_t* context, struct pipeline_infos_list_t* pipelines_infos_list, struct descriptor_set_handle_t* descriptor_set_handles)
|
||||||
{
|
{
|
||||||
assert(NULL != context);
|
assert(NULL != context);
|
||||||
assert(NULL != pipelines_infos_list);
|
assert(NULL != pipelines_infos_list);
|
||||||
@@ -397,7 +399,7 @@ rse_err_t pipelines_build(struct graphics_context_t* context, struct pipeline_in
|
|||||||
|
|
||||||
context->pipelines_data.pipelines_count = pipelines_count;
|
context->pipelines_data.pipelines_count = pipelines_count;
|
||||||
|
|
||||||
STATUS_CHECK(create_pipeline_layout(context));
|
STATUS_CHECK(create_pipeline_layout(context, descriptor_set_handles));
|
||||||
|
|
||||||
rse_malloc(pipeline_infos, sizeof(VkGraphicsPipelineCreateInfo) * pipelines_count);
|
rse_malloc(pipeline_infos, sizeof(VkGraphicsPipelineCreateInfo) * pipelines_count);
|
||||||
|
|
||||||
@@ -543,6 +545,8 @@ void destroy_pipelines(struct graphics_context_t* context)
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t shader_modules_count = RSE_LINKED_LIST_SIZE(context->shader_modules);
|
size_t shader_modules_count = RSE_LINKED_LIST_SIZE(context->shader_modules);
|
||||||
|
|
||||||
|
vkDestroyPipelineLayout(context->device, context->pipelines_data.pipeline_layout, NULL);
|
||||||
|
|
||||||
for (i = 0; i < context->pipelines_data.pipelines_count; i++) {
|
for (i = 0; i < context->pipelines_data.pipelines_count; i++) {
|
||||||
if (context->pipelines_data.pipelines[i] != VK_NULL_HANDLE) {
|
if (context->pipelines_data.pipelines[i] != VK_NULL_HANDLE) {
|
||||||
vkDestroyPipeline(context->device, context->pipelines_data.pipelines[i], NULL);
|
vkDestroyPipeline(context->device, context->pipelines_data.pipelines[i], NULL);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include "descriptor_builder.h"
|
||||||
#include "graphics_context.h"
|
#include "graphics_context.h"
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/linked_list.h"
|
#include "utilities/linked_list.h"
|
||||||
@@ -85,9 +86,10 @@ rse_err_t pipeline_add_dynamic_state(struct pipeline_t* pipeline, const VkDynami
|
|||||||
*
|
*
|
||||||
* param[in/out] context Graphics context handle
|
* param[in/out] context Graphics context handle
|
||||||
* @param[in] pipeline Pipelines list to build
|
* @param[in] pipeline Pipelines list to build
|
||||||
|
* @param[in] descriptor_set_handle Filled handle with descriptor sets
|
||||||
* @return RSE_SUCCESS on success, error code otherwise
|
* @return RSE_SUCCESS on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
rse_err_t pipelines_build(struct graphics_context_t* context, struct pipeline_infos_list_t* pipelines);
|
rse_err_t pipelines_build(struct graphics_context_t* context, struct pipeline_infos_list_t* pipelines, struct descriptor_set_handle_t* descriptor_set_handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add pipeline to list of pipelines
|
* @brief Add pipeline to list of pipelines
|
||||||
|
|||||||
+33
-19
@@ -1,16 +1,20 @@
|
|||||||
#include "rse_graphics.h"
|
#include "rse_graphics.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
#include "descriptor_builder.h"
|
#include "descriptor_builder.h"
|
||||||
#include "graphics_context.h"
|
#include "graphics_context.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "mesh_controller.h"
|
#include "mesh_controller.h"
|
||||||
#include "pipeline_builder.h"
|
#include "pipeline_builder.h"
|
||||||
|
#include "src/vulkan_buffers.h"
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
|
#include "utilities/file_utils.h"
|
||||||
#include "utilities/localization.h"
|
#include "utilities/localization.h"
|
||||||
#include "utilities/logger.h"
|
#include "utilities/logger.h"
|
||||||
#include "vulkan_base.h"
|
#include "vulkan_base.h"
|
||||||
#include "vulkan_commons.h"
|
#include "vulkan_commons.h"
|
||||||
|
#include "vulkan_image.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
struct rse_graphics_context_t
|
struct rse_graphics_context_t
|
||||||
@@ -41,17 +45,17 @@ rse_err_t rse_graphics_init(struct rse_graphics_context_t** context)
|
|||||||
|
|
||||||
void rse_graphics_test_function(struct rse_graphics_context_t* rse_context)
|
void rse_graphics_test_function(struct rse_graphics_context_t* rse_context)
|
||||||
{
|
{
|
||||||
|
char curr_path[4096] = {0};
|
||||||
struct graphics_context_t* context = rse_context->context;
|
struct graphics_context_t* context = rse_context->context;
|
||||||
// rse_err_t status = RSE_ERROR_NO_ERROR;
|
|
||||||
uint16_t tex_id_2 = 0;
|
uint16_t tex_id_2 = 0;
|
||||||
size_t ubo_index = 0;
|
|
||||||
size_t sampler_index = 0;
|
|
||||||
struct pipeline_t* pipeline = NULL;
|
struct pipeline_t* pipeline = NULL;
|
||||||
struct descriptor_set_list_t* descriptor_set_list;
|
struct descriptor_set_handle_t* descriptor_set_handle = NULL;
|
||||||
struct descriptor_set_handle_t* descriptor_set_handle;
|
|
||||||
struct pipeline_infos_list_t* pipeline_infos = NULL;
|
struct pipeline_infos_list_t* pipeline_infos = NULL;
|
||||||
|
struct vulkan_buffer_t ubo = {0};
|
||||||
|
|
||||||
// status = load_texture_from_file("../../test_image.jpg", &tex_id_2);
|
get_curr_path(curr_path, 4096);
|
||||||
|
strncat(curr_path, "../../test_image.jpg", 4095);
|
||||||
|
load_texture_from_file(context, curr_path, &tex_id_2);
|
||||||
// if (status != RSE_ERROR_NO_ERROR) {
|
// if (status != RSE_ERROR_NO_ERROR) {
|
||||||
// LOGE("Failed to do something. Check error messages. Error: %d", status);
|
// LOGE("Failed to do something. Check error messages. Error: %d", status);
|
||||||
// return;
|
// return;
|
||||||
@@ -92,12 +96,15 @@ void rse_graphics_test_function(struct rse_graphics_context_t* rse_context)
|
|||||||
/* Initialize pipeline */
|
/* Initialize pipeline */
|
||||||
pipeline_builder_init(&pipeline);
|
pipeline_builder_init(&pipeline);
|
||||||
|
|
||||||
pipeline_add_shader_stage(context, pipeline, "../graphics/shaders/shader.vert.num", VK_SHADER_STAGE_VERTEX_BIT);
|
get_curr_path(curr_path, 4096);
|
||||||
pipeline_add_shader_stage(context, pipeline, "../graphics/shaders/solid_objects.frag.num",
|
strncat(curr_path, "shader.vert.num", 4095);
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT);
|
pipeline_add_shader_stage(context, pipeline, curr_path, VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
|
get_curr_path(curr_path, 4096);
|
||||||
|
strncat(curr_path, "solid_objects.frag.num", 4095);
|
||||||
|
pipeline_add_shader_stage(context, pipeline, curr_path, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
|
|
||||||
pipeline_add_vertex_input_binding(pipeline, 0, sizeof(struct vertex_t), VK_VERTEX_INPUT_RATE_VERTEX);
|
pipeline_add_vertex_input_binding(pipeline, 0, sizeof(struct vertex_t), VK_VERTEX_INPUT_RATE_VERTEX);
|
||||||
pipeline_add_vertex_input_binding(pipeline, 1, sizeof(struct vertex_t), VK_VERTEX_INPUT_RATE_INSTANCE);
|
pipeline_add_vertex_input_binding(pipeline, 1, sizeof(struct instance_data_t), VK_VERTEX_INPUT_RATE_INSTANCE);
|
||||||
|
|
||||||
pipeline_add_vertex_input_attribute(pipeline, 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct vertex_t, pos));
|
pipeline_add_vertex_input_attribute(pipeline, 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct vertex_t, pos));
|
||||||
pipeline_add_vertex_input_attribute(pipeline, 0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct vertex_t, color));
|
pipeline_add_vertex_input_attribute(pipeline, 0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(struct vertex_t, color));
|
||||||
@@ -113,27 +120,34 @@ void rse_graphics_test_function(struct rse_graphics_context_t* rse_context)
|
|||||||
pipeline_add_dynamic_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT);
|
pipeline_add_dynamic_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT);
|
||||||
pipeline_add_dynamic_state(pipeline, VK_DYNAMIC_STATE_SCISSOR);
|
pipeline_add_dynamic_state(pipeline, VK_DYNAMIC_STATE_SCISSOR);
|
||||||
|
|
||||||
VkSampler sampler = VK_NULL_HANDLE;
|
sampler_create(context, &context->sampler);
|
||||||
|
|
||||||
create_sampler(context, sampler);
|
descriptor_initialize_handle(&descriptor_set_handle);
|
||||||
|
|
||||||
descriptor_add_set(descriptor_set_list, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL);
|
descriptor_add_set(descriptor_set_handle, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL);
|
||||||
descriptor_add_set(descriptor_set_list, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,
|
descriptor_add_set(descriptor_set_handle, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1,
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT, sampler);
|
VK_SHADER_STAGE_FRAGMENT_BIT, &context->sampler);
|
||||||
|
|
||||||
descriptors_build(context, descriptor_set_list, descriptor_set_handle);
|
descriptors_build(context, descriptor_set_handle);
|
||||||
|
|
||||||
add_pipeline(context, pipeline, &pipeline_infos);
|
add_pipeline(context, pipeline, &pipeline_infos);
|
||||||
|
|
||||||
build_pipelines(context, pipeline_infos);
|
pipelines_build(context, pipeline_infos, descriptor_set_handle);
|
||||||
|
|
||||||
|
create_uniform_buffer(context, &ubo);
|
||||||
|
update_uniform_buffers(context, &ubo);
|
||||||
|
|
||||||
|
descriptor_attach_buffer(context, descriptor_set_handle, &ubo, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
|
descriptor_attach_image(context, descriptor_set_handle, tex_id_2, context->sampler, 1);
|
||||||
|
|
||||||
// TODO: Add a shader for text rendering
|
// TODO: Add a shader for text rendering
|
||||||
// pipeline_add_shader_stage("../graphics/shaders/on_screen_text.frag.num", VK_SHADER_STAGE_FRAGMENT_BIT);
|
// pipeline_add_shader_stage("../graphics/shaders/on_screen_text.frag.num", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t rse_graphics_run(struct rse_graphics_context_t* rse_context)
|
int rse_graphics_run(void* arg)
|
||||||
{
|
{
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
|
struct rse_graphics_context_t* rse_context = (struct rse_graphics_context_t*)arg;
|
||||||
struct graphics_context_t* context = rse_context->context;
|
struct graphics_context_t* context = rse_context->context;
|
||||||
|
|
||||||
STATUS_CHECK(run_vulkan(context));
|
STATUS_CHECK(run_vulkan(context));
|
||||||
|
|||||||
+13
-23
@@ -11,10 +11,12 @@
|
|||||||
|
|
||||||
#include "vulkan_base.h"
|
#include "vulkan_base.h"
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <SDL3/SDL_error.h>
|
||||||
#include "utilities/localization.h"
|
#include <SDL3/SDL_main.h>
|
||||||
|
#include <SDL3/SDL_vulkan.h>
|
||||||
#include <vma/vk_mem_alloc.h>
|
#include <vma/vk_mem_alloc.h>
|
||||||
|
|
||||||
|
#include "src/descriptor_builder.h"
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
#include "utilities/logger.h"
|
#include "utilities/logger.h"
|
||||||
@@ -36,7 +38,6 @@
|
|||||||
#define APPLICATION_NAME "RedScarfEngine PoC"
|
#define APPLICATION_NAME "RedScarfEngine PoC"
|
||||||
#define ENGINE_NAME "RedScarf Engine"
|
#define ENGINE_NAME "RedScarf Engine"
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/**
|
/**
|
||||||
* @brief Calback for debug messenger
|
* @brief Calback for debug messenger
|
||||||
*
|
*
|
||||||
@@ -111,6 +112,7 @@ static rse_err_t setup_debug_messenger(VkInstance instance, VkDebugUtilsMessenge
|
|||||||
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||||
create_info.pNext = NULL;
|
create_info.pNext = NULL;
|
||||||
create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||||
|
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
|
||||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||||
create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||||
@@ -145,8 +147,6 @@ static void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMesse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create the Vulkan Instance object
|
* @brief Create the Vulkan Instance object
|
||||||
*
|
*
|
||||||
@@ -173,16 +173,13 @@ static rse_err_t create_instance(VkInstance* instance)
|
|||||||
#ifdef WAYLAND
|
#ifdef WAYLAND
|
||||||
"VK_KHR_wayland_surface",
|
"VK_KHR_wayland_surface",
|
||||||
#else
|
#else
|
||||||
"VK_KHR_xcb_surface",
|
"VK_KHR_xlib_surface",
|
||||||
#endif /* WAYLAND */
|
#endif /* WAYLAND */
|
||||||
#elif defined(_WIN32) || defined(WIN32)
|
#elif defined(_WIN32) || defined(WIN32)
|
||||||
"VK_KHR_win32_surface",
|
"VK_KHR_win32_surface",
|
||||||
#endif /* _WIN32 || WIN32 */
|
#endif /* _WIN32 || WIN32 */
|
||||||
#ifndef NDEBUG
|
|
||||||
"VK_EXT_debug_utils",
|
"VK_EXT_debug_utils",
|
||||||
#endif /* NDEBUG */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
uint32_t enabled_instance_extensions_count = 4;
|
uint32_t enabled_instance_extensions_count = 4;
|
||||||
uint32_t enabled_instance_layers_count = 1;
|
uint32_t enabled_instance_layers_count = 1;
|
||||||
@@ -254,18 +251,14 @@ static rse_err_t create_instance(VkInstance* instance)
|
|||||||
application_info.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
|
application_info.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
|
||||||
application_info.pEngineName = ENGINE_NAME;
|
application_info.pEngineName = ENGINE_NAME;
|
||||||
application_info.engineVersion = VK_MAKE_VERSION(0, 1, 0);
|
application_info.engineVersion = VK_MAKE_VERSION(0, 1, 0);
|
||||||
application_info.apiVersion = VK_API_VERSION_1_3;
|
application_info.apiVersion = VK_API_VERSION_1_4;
|
||||||
|
|
||||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
create_info.pNext = NULL;
|
create_info.pNext = NULL;
|
||||||
create_info.flags = 0U;
|
create_info.flags = 0U;
|
||||||
create_info.pApplicationInfo = &application_info;
|
create_info.pApplicationInfo = &application_info;
|
||||||
create_info.enabledLayerCount = enabled_instance_layers_count;
|
create_info.enabledLayerCount = enabled_instance_layers_count;
|
||||||
#ifndef NDEBUG
|
|
||||||
create_info.ppEnabledLayerNames = enabled_instance_layers_names;
|
create_info.ppEnabledLayerNames = enabled_instance_layers_names;
|
||||||
#else
|
|
||||||
create_info.ppEnabledLayerNames = NULL;
|
|
||||||
#endif
|
|
||||||
create_info.enabledExtensionCount = enabled_instance_extensions_count;
|
create_info.enabledExtensionCount = enabled_instance_extensions_count;
|
||||||
create_info.ppEnabledExtensionNames = enabled_instance_extensions_names;
|
create_info.ppEnabledExtensionNames = enabled_instance_extensions_names;
|
||||||
|
|
||||||
@@ -283,10 +276,10 @@ static rse_err_t create_instance(VkInstance* instance)
|
|||||||
*
|
*
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
||||||
*/
|
*/
|
||||||
static rse_err_t create_surface(VkInstance instance, GLFWwindow* window_handle, VkSurfaceKHR* surface)
|
static rse_err_t create_surface(VkInstance instance, SDL_Window* window_handle, VkSurfaceKHR* surface)
|
||||||
{
|
{
|
||||||
if (VK_SUCCESS != glfwCreateWindowSurface(instance, window_handle, NULL, surface)) {
|
if (true != SDL_Vulkan_CreateSurface(window_handle, instance, NULL, surface)) {
|
||||||
LOGF(_("Failed to create window surface\n"));
|
LOGF(_("Failed to create window surface. Error: %s\n"), SDL_GetError());
|
||||||
return VULKAN_ERROR_SURFACE_CREATION_FAILED;
|
return VULKAN_ERROR_SURFACE_CREATION_FAILED;
|
||||||
}
|
}
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
@@ -546,9 +539,7 @@ rse_err_t init_vulkan(struct graphics_context_t* context)
|
|||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
|
|
||||||
STATUS_CHECK(create_instance(&context->instance));
|
STATUS_CHECK(create_instance(&context->instance));
|
||||||
#ifndef NDEBUG
|
|
||||||
STATUS_CHECK(setup_debug_messenger(context->instance, &context->debug_messenger));
|
STATUS_CHECK(setup_debug_messenger(context->instance, &context->debug_messenger));
|
||||||
#endif
|
|
||||||
STATUS_CHECK(create_surface(context->instance, context->window_handle, &context->surface));
|
STATUS_CHECK(create_surface(context->instance, context->window_handle, &context->surface));
|
||||||
STATUS_CHECK(pick_physical_device(context->instance, &context->physical_device));
|
STATUS_CHECK(pick_physical_device(context->instance, &context->physical_device));
|
||||||
STATUS_CHECK(create_device(context));
|
STATUS_CHECK(create_device(context));
|
||||||
@@ -599,7 +590,7 @@ rse_err_t draw_frame(struct graphics_context_t* context)
|
|||||||
return VULKAN_ERROR_ACQUIRE_SWAPCHAIN_FAILED;
|
return VULKAN_ERROR_ACQUIRE_SWAPCHAIN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_uniform_buffers(context);
|
// update_uniform_buffers(context);
|
||||||
|
|
||||||
/* Only reset the fence if we are submitting work */
|
/* Only reset the fence if we are submitting work */
|
||||||
vkResetFences(context->device, 1, &context->in_flight_fences[context->current_frame]);
|
vkResetFences(context->device, 1, &context->in_flight_fences[context->current_frame]);
|
||||||
@@ -630,7 +621,7 @@ rse_err_t draw_frame(struct graphics_context_t* context)
|
|||||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
|
||||||
present_info.waitSemaphoreCount = 1;
|
present_info.waitSemaphoreCount = 1;
|
||||||
present_info.pWaitSemaphores = signal_semaphores;
|
present_info.pWaitSemaphores = &context->render_finished_semaphores[context->current_frame];
|
||||||
|
|
||||||
swap_chains[0] = context->swapchain;
|
swap_chains[0] = context->swapchain;
|
||||||
present_info.swapchainCount = 1;
|
present_info.swapchainCount = 1;
|
||||||
@@ -669,12 +660,11 @@ void deinit_vulkan(struct graphics_context_t* context)
|
|||||||
destroy_render_pass(context);
|
destroy_render_pass(context);
|
||||||
cleanup_swapchain(context);
|
cleanup_swapchain(context);
|
||||||
destroy_pipelines(context);
|
destroy_pipelines(context);
|
||||||
|
destroy_descriptors(context);
|
||||||
|
|
||||||
vmaDestroyAllocator(context->allocator);
|
vmaDestroyAllocator(context->allocator);
|
||||||
vkDestroyDevice(context->device, NULL);
|
vkDestroyDevice(context->device, NULL);
|
||||||
#ifndef NDEBUG
|
|
||||||
DestroyDebugUtilsMessengerEXT(context->instance, context->debug_messenger, NULL);
|
DestroyDebugUtilsMessengerEXT(context->instance, context->debug_messenger, NULL);
|
||||||
#endif
|
|
||||||
vkDestroySurfaceKHR(context->instance, context->surface, NULL);
|
vkDestroySurfaceKHR(context->instance, context->surface, NULL);
|
||||||
vkDestroyInstance(context->instance, NULL);
|
vkDestroyInstance(context->instance, NULL);
|
||||||
}
|
}
|
||||||
+93
-107
@@ -1,18 +1,20 @@
|
|||||||
#include "vulkan_buffers.h"
|
#include "vulkan_buffers.h"
|
||||||
|
|
||||||
#include "src/graphics_context.h"
|
|
||||||
#include "src/vulkan_commons.h"
|
|
||||||
#include "utilities/commons.h"
|
|
||||||
#include "utilities/linked_list.h"
|
|
||||||
#include "vulkan_errors.h"
|
|
||||||
#include "utilities/logger.h"
|
|
||||||
#include "utilities/localization.h"
|
|
||||||
#include "utilities/errors_common.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include "vulkan_commands.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
#include "src/descriptor_builder.h"
|
||||||
|
#include "src/graphics_context.h"
|
||||||
|
#include "src/vulkan_commons.h"
|
||||||
|
#include "utilities/commons.h"
|
||||||
|
#include "utilities/errors_common.h"
|
||||||
|
#include "utilities/linked_list.h"
|
||||||
|
#include "utilities/localization.h"
|
||||||
|
#include "utilities/logger.h"
|
||||||
|
#include "vulkan_commands.h"
|
||||||
|
#include "vulkan_errors.h"
|
||||||
|
|
||||||
#define MAX_VERTEX_BUFFER_SIZE 33554432 /* 32 MB*/
|
#define MAX_VERTEX_BUFFER_SIZE 33554432 /* 32 MB*/
|
||||||
|
|
||||||
@@ -23,7 +25,8 @@
|
|||||||
* @param dst Destination buffer
|
* @param dst Destination buffer
|
||||||
* @param size Size of buffer to copy
|
* @param size Size of buffer to copy
|
||||||
*/
|
*/
|
||||||
static void copy_buffer(struct graphics_context_t* context, VkBuffer src, VkBuffer dst, VkDeviceSize size, VkDeviceSize dest_offset)
|
static void copy_buffer(struct graphics_context_t* context, VkBuffer src, VkBuffer dst, VkDeviceSize size,
|
||||||
|
VkDeviceSize dest_offset)
|
||||||
{
|
{
|
||||||
/* Vulkan buffers can only be copied using command buffers */
|
/* Vulkan buffers can only be copied using command buffers */
|
||||||
VkBufferCopy copy_region = {0};
|
VkBufferCopy copy_region = {0};
|
||||||
@@ -40,7 +43,6 @@ static void copy_buffer(struct graphics_context_t* context, VkBuffer src, VkBuff
|
|||||||
end_single_time_comands(context, command_buffer);
|
end_single_time_comands(context, command_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a buffer holding all vertex data
|
* @brief Create a buffer holding all vertex data
|
||||||
*
|
*
|
||||||
@@ -59,8 +61,7 @@ static rse_err_t create_vertex_buffer(struct graphics_context_t* context)
|
|||||||
/* Create Vertex Buffer*/
|
/* Create Vertex Buffer*/
|
||||||
STATUS_CHECK(create_buffer(context, buffer_size,
|
STATUS_CHECK(create_buffer(context, buffer_size,
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, /* Will not be mapped with vmaMapMemory */
|
||||||
0, /* Will not be mapped with vmaMapMemory */
|
|
||||||
&context->vertex_buffer));
|
&context->vertex_buffer));
|
||||||
|
|
||||||
context->vertex_buffer.allocated_size = 0;
|
context->vertex_buffer.allocated_size = 0;
|
||||||
@@ -82,9 +83,9 @@ static rse_err_t create_index_buffer(struct graphics_context_t* context)
|
|||||||
buffer_size = MAX_VERTEX_BUFFER_SIZE;
|
buffer_size = MAX_VERTEX_BUFFER_SIZE;
|
||||||
|
|
||||||
/* Create Index Buffer*/
|
/* Create Index Buffer*/
|
||||||
STATUS_CHECK(create_buffer(context, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
STATUS_CHECK(create_buffer(context, buffer_size,
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
0, /* Will not be mapped with vmaMapMemory */
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, /* Will not be mapped with vmaMapMemory */
|
||||||
&context->index_buffer));
|
&context->index_buffer));
|
||||||
|
|
||||||
context->index_buffer.allocated_size = 0;
|
context->index_buffer.allocated_size = 0;
|
||||||
@@ -113,43 +114,35 @@ static rse_err_t create_instance_buffers(struct graphics_context_t* context)
|
|||||||
&context->instance_buffers[iter]));
|
&context->instance_buffers[iter]));
|
||||||
|
|
||||||
context->instance_buffers[iter].allocated_size = 0;
|
context->instance_buffers[iter].allocated_size = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS_CHECK(create_buffer(context, sizeof(VkDrawIndexedIndirectCommand) * MAX_MESH_NUMBER,
|
STATUS_CHECK(create_buffer(
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
context, sizeof(VkDrawIndexedIndirectCommand) * MAX_MESH_NUMBER,
|
||||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||||
| VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
||||||
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||||
&context->draw_indirect_command_buffer));
|
&context->draw_indirect_command_buffer));
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
rse_err_t create_uniform_buffer(struct graphics_context_t* context, struct vulkan_buffer_t* buffer)
|
||||||
* @brief Create a Uniform Buffers
|
|
||||||
*
|
|
||||||
* @param context Graphics context handle
|
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success.
|
|
||||||
*/
|
|
||||||
static rse_err_t create_uniform_buffer(struct graphics_context_t* context)
|
|
||||||
{
|
{
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
VkDeviceSize buffer_size = sizeof(struct uniform_buffer_object_t);
|
VkDeviceSize buffer_size =
|
||||||
|
sizeof(struct uniform_buffer_object_t); // TODO: Change later. Uniform buffer is not only MVP
|
||||||
|
|
||||||
for (size_t i = 0; i < SWAP_BUFFER_COUNT; i++) {
|
|
||||||
STATUS_CHECK(create_buffer(context, buffer_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
STATUS_CHECK(create_buffer(
|
||||||
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
context, buffer_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
||||||
&context->uniform_buffers[i]));
|
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, buffer));
|
||||||
}
|
|
||||||
|
RSE_LINKED_LIST_PUSH_BACK(context->uniform_buffers, *buffer);
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t create_buffer(struct graphics_context_t* context, const VkDeviceSize size,
|
rse_err_t create_buffer(struct graphics_context_t* context, const VkDeviceSize size, VkBufferUsageFlags buffer_usage,
|
||||||
VkBufferUsageFlags buffer_usage,
|
VmaMemoryUsage memory_usage, const VmaAllocationCreateFlags allocation_flags,
|
||||||
VmaMemoryUsage memory_usage,
|
|
||||||
const VmaAllocationCreateFlags allocation_flags,
|
|
||||||
struct vulkan_buffer_t* buffer)
|
struct vulkan_buffer_t* buffer)
|
||||||
{
|
{
|
||||||
VkBufferCreateInfo vertex_buffer_info = {0};
|
VkBufferCreateInfo vertex_buffer_info = {0};
|
||||||
@@ -173,26 +166,27 @@ rse_err_t create_buffer(struct graphics_context_t* context, const VkDeviceSize s
|
|||||||
create_info.pUserData = VK_NULL_HANDLE;
|
create_info.pUserData = VK_NULL_HANDLE;
|
||||||
create_info.priority = 0.0f;
|
create_info.priority = 0.0f;
|
||||||
|
|
||||||
if (VK_SUCCESS != vmaCreateBuffer(context->allocator,
|
if (VK_SUCCESS != vmaCreateBuffer(context->allocator, &vertex_buffer_info, &create_info, &buffer->buffer,
|
||||||
&vertex_buffer_info,
|
&buffer->allocation, &buffer->allocation_info)) {
|
||||||
&create_info,
|
|
||||||
&buffer->buffer,
|
|
||||||
&buffer->allocation,
|
|
||||||
&buffer->allocation_info)) {
|
|
||||||
LOGF(_("Failed to create a vertex buffer\n"));
|
LOGF(_("Failed to create a vertex buffer\n"));
|
||||||
return VULKAN_ERROR_BUFFER_CREATION_FAILED;
|
return VULKAN_ERROR_BUFFER_CREATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int count = 1;
|
||||||
|
LOGI("Created buffers: %d\n", count++);
|
||||||
|
|
||||||
|
buffer->allocated_size = size;
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_buffer(struct graphics_context_t* context, struct vulkan_buffer_t* buffer)
|
void destroy_buffer(struct graphics_context_t* context, struct vulkan_buffer_t* buffer)
|
||||||
{
|
{
|
||||||
vmaDestroyBuffer(context->allocator, buffer->buffer, buffer->allocation);
|
vmaDestroyBuffer(context->allocator, buffer->buffer, buffer->allocation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_uniform_buffers(struct graphics_context_t* context, const struct vulkan_buffer_t* buffer)
|
||||||
void update_uniform_buffers(struct graphics_context_t* context)
|
|
||||||
{
|
{
|
||||||
struct uniform_buffer_object_t ubo = {0};
|
struct uniform_buffer_object_t ubo = {0};
|
||||||
struct vec3_t eye = {0};
|
struct vec3_t eye = {0};
|
||||||
@@ -213,18 +207,13 @@ void update_uniform_buffers(struct graphics_context_t* context)
|
|||||||
|
|
||||||
ubo.model = math_rotate(math_uniform_mat4(), math_deg_to_radians(0.0f), rotation_vec);
|
ubo.model = math_rotate(math_uniform_mat4(), math_deg_to_radians(0.0f), rotation_vec);
|
||||||
ubo.view = math_look_at(&eye, ¢er, &up);
|
ubo.view = math_look_at(&eye, ¢er, &up);
|
||||||
ubo.proj = math_perspective(fovy,
|
ubo.proj = math_perspective(fovy, context->swapchain_extent.width / (float)context->swapchain_extent.height, z_near,
|
||||||
context->swapchain_extent.width / (float)context->swapchain_extent.height,
|
|
||||||
z_near,
|
|
||||||
z_far);
|
z_far);
|
||||||
memcpy(context->uniform_buffers[context->current_frame].allocation_info.pMappedData, &ubo, sizeof(ubo));
|
memcpy(buffer->allocation_info.pMappedData, &ubo, sizeof(ubo));
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t add_vertices(struct graphics_context_t* context, uint16_t mesh_id,
|
rse_err_t add_vertices(struct graphics_context_t* context, uint16_t mesh_id, const struct vertex_t* vertices,
|
||||||
const struct vertex_t* vertices,
|
const uint16_t* indices, struct buffer_data_t* vertex_data, struct buffer_data_t* index_data)
|
||||||
const uint16_t* indices,
|
|
||||||
struct buffer_data_t* vertex_data,
|
|
||||||
struct buffer_data_t* index_data)
|
|
||||||
{
|
{
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
VkDrawIndexedIndirectCommand draw_indirect_command;
|
VkDrawIndexedIndirectCommand draw_indirect_command;
|
||||||
@@ -235,19 +224,14 @@ rse_err_t add_vertices(struct graphics_context_t* context, uint16_t mesh_id,
|
|||||||
struct vulkan_buffer_t* index_buffer = &context->index_buffer;
|
struct vulkan_buffer_t* index_buffer = &context->index_buffer;
|
||||||
|
|
||||||
/* Creating staging buffer*/
|
/* Creating staging buffer*/
|
||||||
STATUS_CHECK(create_buffer(context, MAX_VERTEX_BUFFER_SIZE,
|
STATUS_CHECK(create_buffer(
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
context, MAX_VERTEX_BUFFER_SIZE, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, &staging_buffer));
|
||||||
VMA_ALLOCATION_CREATE_MAPPED_BIT
|
|
||||||
| VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
|
||||||
&staging_buffer));
|
|
||||||
|
|
||||||
/* Fill staging buffer with vertex data */
|
/* Fill staging buffer with vertex data */
|
||||||
memset(staging_buffer.allocation_info.pMappedData, 0, MAX_VERTEX_BUFFER_SIZE);
|
memset(staging_buffer.allocation_info.pMappedData, 0, MAX_VERTEX_BUFFER_SIZE);
|
||||||
memcpy(staging_buffer.allocation_info.pMappedData, vertices, vertices_size);
|
memcpy(staging_buffer.allocation_info.pMappedData, vertices, vertices_size);
|
||||||
copy_buffer(context, staging_buffer.buffer,
|
copy_buffer(context, staging_buffer.buffer, context->vertex_buffer.buffer, vertices_size,
|
||||||
context->vertex_buffer.buffer,
|
|
||||||
vertices_size,
|
|
||||||
context->vertex_buffer.allocated_size);
|
context->vertex_buffer.allocated_size);
|
||||||
|
|
||||||
vertex_data->buffer_offset = context->vertex_offset;
|
vertex_data->buffer_offset = context->vertex_offset;
|
||||||
@@ -257,10 +241,7 @@ rse_err_t add_vertices(struct graphics_context_t* context, uint16_t mesh_id,
|
|||||||
/* Fill staging buffer with index data */
|
/* Fill staging buffer with index data */
|
||||||
memset(staging_buffer.allocation_info.pMappedData, 0, indices_size);
|
memset(staging_buffer.allocation_info.pMappedData, 0, indices_size);
|
||||||
memcpy(staging_buffer.allocation_info.pMappedData, indices, indices_size);
|
memcpy(staging_buffer.allocation_info.pMappedData, indices, indices_size);
|
||||||
copy_buffer(context, staging_buffer.buffer,
|
copy_buffer(context, staging_buffer.buffer, index_buffer->buffer, indices_size, index_buffer->allocated_size);
|
||||||
index_buffer->buffer,
|
|
||||||
indices_size,
|
|
||||||
index_buffer->allocated_size);
|
|
||||||
index_data->buffer_offset = index_buffer->allocated_size;
|
index_data->buffer_offset = index_buffer->allocated_size;
|
||||||
index_buffer->allocated_size += indices_size;
|
index_buffer->allocated_size += indices_size;
|
||||||
|
|
||||||
@@ -272,12 +253,15 @@ rse_err_t add_vertices(struct graphics_context_t* context, uint16_t mesh_id,
|
|||||||
draw_indirect_command.vertexOffset = vertex_data->buffer_offset;
|
draw_indirect_command.vertexOffset = vertex_data->buffer_offset;
|
||||||
draw_indirect_command.firstInstance = 0;
|
draw_indirect_command.firstInstance = 0;
|
||||||
|
|
||||||
memcpy(context->draw_indirect_command_buffer.allocation_info.pMappedData + (mesh_id * sizeof(VkDrawIndexedIndirectCommand)), &draw_indirect_command, sizeof(VkDrawIndexedIndirectCommand));
|
memcpy((char*)context->draw_indirect_command_buffer.allocation_info.pMappedData +
|
||||||
|
(mesh_id * sizeof(VkDrawIndexedIndirectCommand)),
|
||||||
|
&draw_indirect_command, sizeof(VkDrawIndexedIndirectCommand));
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t update_mesh_instances(struct graphics_context_t* context, uint16_t mesh_id, struct instance_data_t* instance_data)
|
rse_err_t update_mesh_instances(struct graphics_context_t* context, uint16_t mesh_id,
|
||||||
|
struct instance_data_t* instance_data)
|
||||||
{
|
{
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
VkDrawIndexedIndirectCommand draw_indirect_command;
|
VkDrawIndexedIndirectCommand draw_indirect_command;
|
||||||
@@ -286,27 +270,27 @@ rse_err_t update_mesh_instances(struct graphics_context_t* context, uint16_t mes
|
|||||||
size_t instance_size = sizeof(struct instance_data_t);
|
size_t instance_size = sizeof(struct instance_data_t);
|
||||||
|
|
||||||
/* Creating staging buffer*/
|
/* Creating staging buffer*/
|
||||||
STATUS_CHECK(create_buffer(context, instance_size,
|
STATUS_CHECK(create_buffer(
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
context, instance_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, &staging_buffer));
|
||||||
VMA_ALLOCATION_CREATE_MAPPED_BIT
|
|
||||||
| VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
|
||||||
&staging_buffer));
|
|
||||||
|
|
||||||
/* Copy transformation information about instance */
|
/* Copy transformation information about instance */
|
||||||
memcpy(staging_buffer.allocation_info.pMappedData, instance_data, instance_size);
|
memcpy(staging_buffer.allocation_info.pMappedData, instance_data, instance_size);
|
||||||
copy_buffer(context, staging_buffer.buffer,
|
copy_buffer(context, staging_buffer.buffer, instance_buffer->buffer, instance_size,
|
||||||
instance_buffer->buffer,
|
|
||||||
instance_size,
|
|
||||||
instance_buffer->allocated_size);
|
instance_buffer->allocated_size);
|
||||||
|
|
||||||
destroy_buffer(context, &staging_buffer);
|
destroy_buffer(context, &staging_buffer);
|
||||||
|
|
||||||
instance_buffer->allocated_size += instance_size;
|
instance_buffer->allocated_size += instance_size;
|
||||||
|
|
||||||
memcpy(&draw_indirect_command, context->draw_indirect_command_buffer.allocation_info.pMappedData + (mesh_id * sizeof(VkDrawIndexedIndirectCommand)), sizeof(VkDrawIndexedIndirectCommand));
|
memcpy(&draw_indirect_command,
|
||||||
|
(char*)context->draw_indirect_command_buffer.allocation_info.pMappedData +
|
||||||
|
(mesh_id * sizeof(VkDrawIndexedIndirectCommand)),
|
||||||
|
sizeof(VkDrawIndexedIndirectCommand));
|
||||||
draw_indirect_command.instanceCount++;
|
draw_indirect_command.instanceCount++;
|
||||||
memcpy(context->draw_indirect_command_buffer.allocation_info.pMappedData + (mesh_id * sizeof(VkDrawIndexedIndirectCommand)), &draw_indirect_command, sizeof(VkDrawIndexedIndirectCommand));
|
memcpy((char*)context->draw_indirect_command_buffer.allocation_info.pMappedData +
|
||||||
|
(mesh_id * sizeof(VkDrawIndexedIndirectCommand)),
|
||||||
|
&draw_indirect_command, sizeof(VkDrawIndexedIndirectCommand));
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -322,17 +306,17 @@ rse_err_t update_mesh_instances(struct graphics_context_t* context, uint16_t mes
|
|||||||
rse_err_t record_command_buffer(struct graphics_context_t* context, uint32_t image_index)
|
rse_err_t record_command_buffer(struct graphics_context_t* context, uint32_t image_index)
|
||||||
{
|
{
|
||||||
VkCommandBuffer command_buffer = context->command_buffers[context->current_frame];
|
VkCommandBuffer command_buffer = context->command_buffers[context->current_frame];
|
||||||
VkDescriptorSet* descriptor_sets = NULL;
|
VkCommandBufferBeginInfo begin_info = {0};
|
||||||
VkCommandBufferBeginInfo begin_info = {};
|
VkRenderPassBeginInfo render_pass_info = {0};
|
||||||
VkRenderPassBeginInfo render_pass_info = {};
|
VkViewport viewport = {0};
|
||||||
VkViewport viewport = {};
|
VkRect2D scissor = {0};
|
||||||
VkRect2D scissor = {};
|
|
||||||
VkDeviceSize offsets[] = {0};
|
VkDeviceSize offsets[] = {0};
|
||||||
VkClearValue clear_values[2] = {}; //For color and depth stencil
|
VkClearValue clear_values[2] = {0}; // For color and depth stencil
|
||||||
|
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
|
||||||
size_t i = 0U;
|
size_t i = 0U;
|
||||||
|
|
||||||
|
// FIXME: Do something with this list
|
||||||
RSE_LINKED_LIST_TO_ARRAY(context->pipelines_data.descriptor_sets, descriptor_sets);
|
// RSE_LINKED_LIST_TO_ARRAY(context->pipelines_data.descriptor_sets, descriptor_sets);
|
||||||
|
|
||||||
clear_values[0].color.float32[0] = 0.0f;
|
clear_values[0].color.float32[0] = 0.0f;
|
||||||
clear_values[0].color.float32[1] = 0.0f;
|
clear_values[0].color.float32[1] = 0.0f;
|
||||||
@@ -345,6 +329,12 @@ rse_err_t record_command_buffer(struct graphics_context_t* context, uint32_t ima
|
|||||||
begin_info.flags = 0;
|
begin_info.flags = 0;
|
||||||
begin_info.pInheritanceInfo = NULL;
|
begin_info.pInheritanceInfo = NULL;
|
||||||
|
|
||||||
|
if (RSE_ERROR_NO_ERROR != descriptor_get_vkhandle(context->descriptor_sets, &descriptor_set)) {
|
||||||
|
LOGF(_("Failed to get vk handle from descriptor set handle\n"));
|
||||||
|
|
||||||
|
return VULKAN_ERROR_RECORD_COMMAND_BEGIN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (vkBeginCommandBuffer(command_buffer, &begin_info) != VK_SUCCESS) {
|
if (vkBeginCommandBuffer(command_buffer, &begin_info) != VK_SUCCESS) {
|
||||||
LOGF(_("Failed to start recording command buffer\n"));
|
LOGF(_("Failed to start recording command buffer\n"));
|
||||||
return VULKAN_ERROR_RECORD_COMMAND_BEGIN_FAILED;
|
return VULKAN_ERROR_RECORD_COMMAND_BEGIN_FAILED;
|
||||||
@@ -378,18 +368,16 @@ rse_err_t record_command_buffer(struct graphics_context_t* context, uint32_t ima
|
|||||||
|
|
||||||
vkCmdBindVertexBuffers(command_buffer, 0, 1, &context->vertex_buffer.buffer, offsets);
|
vkCmdBindVertexBuffers(command_buffer, 0, 1, &context->vertex_buffer.buffer, offsets);
|
||||||
vkCmdBindIndexBuffer(command_buffer, context->index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
vkCmdBindIndexBuffer(command_buffer, context->index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
||||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, context->pipelines_data.pipeline_layout, 0, 2,
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, context->pipelines_data.pipeline_layout, 0,
|
||||||
descriptor_sets, 0, NULL);
|
1, &descriptor_set, 0, NULL);
|
||||||
|
|
||||||
for (i = 0; i < MAX_MESH_NUMBER; ++i) {
|
for (i = 0; i < MAX_MESH_NUMBER; ++i) {
|
||||||
VkBuffer instance_buffer = {context->instance_buffers[i].buffer};
|
VkBuffer instance_buffer = {context->instance_buffers[i].buffer};
|
||||||
|
|
||||||
vkCmdBindVertexBuffers(command_buffer, 1, 1, &instance_buffer, offsets);
|
vkCmdBindVertexBuffers(command_buffer, 1, 1, &instance_buffer, offsets);
|
||||||
|
|
||||||
vkCmdDrawIndexedIndirect(command_buffer,
|
vkCmdDrawIndexedIndirect(command_buffer, context->draw_indirect_command_buffer.buffer,
|
||||||
context->draw_indirect_command_buffer.buffer,
|
sizeof(VkDrawIndexedIndirectCommand) * i, 1,
|
||||||
sizeof(VkDrawIndexedIndirectCommand) * i,
|
|
||||||
1,
|
|
||||||
0); /* Can be 0 since we are not doing multiple draws each loop */
|
0); /* Can be 0 since we are not doing multiple draws each loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +398,6 @@ rse_err_t create_buffers(struct graphics_context_t* context)
|
|||||||
STATUS_CHECK(create_vertex_buffer(context));
|
STATUS_CHECK(create_vertex_buffer(context));
|
||||||
STATUS_CHECK(create_index_buffer(context));
|
STATUS_CHECK(create_index_buffer(context));
|
||||||
STATUS_CHECK(create_instance_buffers(context));
|
STATUS_CHECK(create_instance_buffers(context));
|
||||||
STATUS_CHECK(create_uniform_buffer(context));
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -420,22 +407,21 @@ void reset_command_buffer(struct graphics_context_t* context)
|
|||||||
vkResetCommandBuffer(context->command_buffers[context->current_frame], /*VkCommandBufferResetFlagBits*/ 0);
|
vkResetCommandBuffer(context->command_buffers[context->current_frame], /*VkCommandBufferResetFlagBits*/ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void destroy_buffers(struct graphics_context_t* context)
|
void destroy_buffers(struct graphics_context_t* context)
|
||||||
{
|
{
|
||||||
size_t i = 0U;
|
size_t i = 0U;
|
||||||
|
|
||||||
for (i = 0; i < SWAP_BUFFER_COUNT; ++i) {
|
|
||||||
vmaDestroyBuffer(context->allocator,
|
|
||||||
context->uniform_buffers[i].buffer,
|
|
||||||
context->uniform_buffers[i].allocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
vmaDestroyBuffer(context->allocator, context->vertex_buffer.buffer, context->vertex_buffer.allocation);
|
vmaDestroyBuffer(context->allocator, context->vertex_buffer.buffer, context->vertex_buffer.allocation);
|
||||||
vmaDestroyBuffer(context->allocator, context->index_buffer.buffer, context->index_buffer.allocation);
|
vmaDestroyBuffer(context->allocator, context->index_buffer.buffer, context->index_buffer.allocation);
|
||||||
vmaDestroyBuffer(context->allocator, context->draw_indirect_command_buffer.buffer, context->draw_indirect_command_buffer.allocation);
|
vmaDestroyBuffer(context->allocator, context->draw_indirect_command_buffer.buffer,
|
||||||
|
context->draw_indirect_command_buffer.allocation);
|
||||||
|
|
||||||
for (i = 0; i < MAX_MESH_NUMBER; ++i) {
|
for (i = 0; i < MAX_MESH_NUMBER; ++i) {
|
||||||
vmaDestroyBuffer(context->allocator, context->instance_buffers[i].buffer, context->instance_buffers[i].allocation);
|
vmaDestroyBuffer(context->allocator, context->instance_buffers[i].buffer,
|
||||||
|
context->instance_buffers[i].allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
RSE_LINKED_LIST_FOREACH(context->uniform_buffers, buffer) {
|
||||||
|
vmaDestroyBuffer(context->allocator, buffer->data.buffer, buffer->data.allocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,13 +18,22 @@
|
|||||||
*/
|
*/
|
||||||
rse_err_t create_buffers(struct graphics_context_t* context);
|
rse_err_t create_buffers(struct graphics_context_t* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a Uniform Buffers
|
||||||
|
*
|
||||||
|
* @param context Graphics context handle
|
||||||
|
* @param buffer Buffer handle to hold new buffer
|
||||||
|
* @return rse_err_t RSE_ERROR_NO_ERROR on success.
|
||||||
|
*/
|
||||||
|
rse_err_t create_uniform_buffer(struct graphics_context_t* context, struct vulkan_buffer_t* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update uniform buffers
|
* @brief Update uniform buffers
|
||||||
*
|
*
|
||||||
* @param context Graphics context handle
|
* @param context Graphics context handle
|
||||||
*
|
* @param buffer Uniform buffer to update
|
||||||
*/
|
*/
|
||||||
void update_uniform_buffers(struct graphics_context_t* context);
|
void update_uniform_buffers(struct graphics_context_t* context, const struct vulkan_buffer_t* ubo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add vertices and indices to vulkan buffers
|
* @brief Add vertices and indices to vulkan buffers
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <stdalign.h>
|
#include <stdalign.h>
|
||||||
|
|
||||||
#define SWAP_BUFFER_COUNT 2U
|
#define SWAP_BUFFER_COUNT 3U
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Represents single vertex on the screen
|
* @brief Represents single vertex on the screen
|
||||||
@@ -55,7 +55,7 @@ struct instance_data_t {
|
|||||||
struct vec3_t pos;
|
struct vec3_t pos;
|
||||||
struct vec3_t rot;
|
struct vec3_t rot;
|
||||||
float scale;
|
float scale;
|
||||||
uint8_t texture_id;
|
uint32_t texture_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_time();
|
void init_time();
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
#include "vulkan_descriptors.h"
|
|
||||||
|
|
||||||
#include "utilities/errors_common.h"
|
|
||||||
#include "utilities/localization.h"
|
|
||||||
#include "utilities/logger.h"
|
|
||||||
#include "vulkan_commons.h"
|
|
||||||
#include "vulkan_errors.h"
|
|
||||||
#include "vulkan_image.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a Descriptor Pool
|
|
||||||
*
|
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
|
||||||
* VULKAN_ERROR_DESCRIPTOR_POOL_CREATION_FAILED
|
|
||||||
*/
|
|
||||||
static rse_err_t create_descriptor_pool(struct graphics_context_t* context)
|
|
||||||
{
|
|
||||||
VkDescriptorPoolSize pool_sizes[2] = {};
|
|
||||||
VkDescriptorPoolCreateInfo pool_info = {};
|
|
||||||
|
|
||||||
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
||||||
pool_sizes[0].descriptorCount = (uint32_t)(SWAP_BUFFER_COUNT);
|
|
||||||
|
|
||||||
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
||||||
pool_sizes[1].descriptorCount = MAX_BINDLESS_RESOURCES;
|
|
||||||
|
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
||||||
pool_info.poolSizeCount = 1;
|
|
||||||
pool_info.pPoolSizes = &pool_sizes[0];
|
|
||||||
|
|
||||||
pool_info.maxSets = (uint32_t)(SWAP_BUFFER_COUNT);
|
|
||||||
if (vkCreateDescriptorPool(context->device, &pool_info, NULL,
|
|
||||||
&context->descriptor_pool) != VK_SUCCESS) {
|
|
||||||
LOGF(_("Failed to create descriptor pool\n"));
|
|
||||||
return VULKAN_ERROR_DESCRIPTOR_POOL_CREATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
|
|
||||||
pool_info.maxSets = MAX_BINDLESS_RESOURCES * 2;
|
|
||||||
pool_info.pPoolSizes = &pool_sizes[1];
|
|
||||||
|
|
||||||
if (vkCreateDescriptorPool(context->device, &pool_info, NULL,
|
|
||||||
&context->descriptor_pool_bindless) !=
|
|
||||||
VK_SUCCESS) {
|
|
||||||
LOGF(_("Failed to create descriptor pool\n"));
|
|
||||||
return VULKAN_ERROR_DESCRIPTOR_POOL_CREATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a Descriptor Sets
|
|
||||||
*
|
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success. Possible errors:
|
|
||||||
* VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED */
|
|
||||||
static rse_err_t create_descriptor_sets(struct graphics_context_t* context)
|
|
||||||
{
|
|
||||||
uint32_t max_binding = MAX_BINDLESS_RESOURCES - 1;
|
|
||||||
VkDescriptorSetLayout layouts[SWAP_BUFFER_COUNT] = {
|
|
||||||
context->descriptor_set_layout, context->descriptor_set_layout};
|
|
||||||
VkDescriptorSetLayout layouts_bindless[SWAP_BUFFER_COUNT] = {
|
|
||||||
context->descriptor_set_layout_bindless,
|
|
||||||
context->descriptor_set_layout_bindless};
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo = {};
|
|
||||||
VkDescriptorSetAllocateInfo allocInfo_bindless = {};
|
|
||||||
VkDescriptorSetVariableDescriptorCountAllocateInfoEXT count_info = {};
|
|
||||||
|
|
||||||
count_info.sType =
|
|
||||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT;
|
|
||||||
count_info.descriptorSetCount = 1;
|
|
||||||
count_info.pDescriptorCounts = &max_binding;
|
|
||||||
|
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
||||||
allocInfo.descriptorPool = context->descriptor_pool;
|
|
||||||
allocInfo.descriptorSetCount = (uint32_t)(SWAP_BUFFER_COUNT);
|
|
||||||
allocInfo.pSetLayouts = layouts;
|
|
||||||
|
|
||||||
allocInfo_bindless = allocInfo;
|
|
||||||
allocInfo_bindless.descriptorPool = context->descriptor_pool_bindless;
|
|
||||||
allocInfo_bindless.pSetLayouts = layouts_bindless;
|
|
||||||
allocInfo_bindless.pNext = &count_info;
|
|
||||||
allocInfo_bindless.descriptorSetCount = 1;
|
|
||||||
|
|
||||||
if (vkAllocateDescriptorSets(context->device, &allocInfo,
|
|
||||||
context->descriptor_sets) != VK_SUCCESS) {
|
|
||||||
LOGF(_("Failed to allocate descriptor sets\n"));
|
|
||||||
return VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vkAllocateDescriptorSets(context->device, &allocInfo_bindless,
|
|
||||||
&context->descriptor_sets_bindless) !=
|
|
||||||
VK_SUCCESS) {
|
|
||||||
LOGF(_("Failed to allocate descriptor sets\n"));
|
|
||||||
return VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < SWAP_BUFFER_COUNT; i++) {
|
|
||||||
VkDescriptorBufferInfo buffer_info = {};
|
|
||||||
VkWriteDescriptorSet descriptor_writes[2] = {};
|
|
||||||
VkDescriptorImageInfo image_infos[RSE_MAX_IMAGE_COUNT] = {};
|
|
||||||
size_t image_iterator = 0U;
|
|
||||||
size_t image_info_iterator = 0U;
|
|
||||||
|
|
||||||
buffer_info.buffer = context->uniform_buffers[i].buffer;
|
|
||||||
buffer_info.offset = 0;
|
|
||||||
buffer_info.range = sizeof(struct uniform_buffer_object_t);
|
|
||||||
|
|
||||||
for (image_iterator = 0U; image_iterator < RSE_MAX_IMAGE_COUNT;
|
|
||||||
++image_iterator) {
|
|
||||||
if (image_exists(context, image_iterator)) {
|
|
||||||
image_infos[image_info_iterator].imageLayout =
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
||||||
image_infos[image_info_iterator].imageView =
|
|
||||||
context->swapchain_image_views[image_iterator];
|
|
||||||
image_infos[image_info_iterator].sampler = context->sampler;
|
|
||||||
image_info_iterator++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
||||||
descriptor_writes[0].dstSet = context->descriptor_sets[i];
|
|
||||||
descriptor_writes[0].dstBinding = 0;
|
|
||||||
descriptor_writes[0].dstArrayElement = 0;
|
|
||||||
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
||||||
descriptor_writes[0].descriptorCount = 1;
|
|
||||||
descriptor_writes[0].pBufferInfo = &buffer_info;
|
|
||||||
|
|
||||||
descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
||||||
descriptor_writes[1].dstSet = context->descriptor_sets_bindless;
|
|
||||||
descriptor_writes[1].dstBinding = 1;
|
|
||||||
descriptor_writes[1].dstArrayElement = 0;
|
|
||||||
descriptor_writes[1].descriptorType =
|
|
||||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
||||||
descriptor_writes[1].descriptorCount = image_info_iterator;
|
|
||||||
descriptor_writes[1].pImageInfo = image_infos;
|
|
||||||
|
|
||||||
vkUpdateDescriptorSets(context->device, 2, descriptor_writes, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
rse_err_t create_descriptors(struct graphics_context_t* context)
|
|
||||||
{
|
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
|
||||||
|
|
||||||
STATUS_CHECK(create_descriptor_pool(context));
|
|
||||||
STATUS_CHECK(create_descriptor_sets(context));
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy_descriptors(struct graphics_context_t* context)
|
|
||||||
{
|
|
||||||
vkDestroyDescriptorPool(context->device, context->descriptor_pool, NULL);
|
|
||||||
vkDestroyDescriptorPool(context->device, context->descriptor_pool_bindless,
|
|
||||||
NULL);
|
|
||||||
vkDestroyDescriptorSetLayout(context->device,
|
|
||||||
context->descriptor_set_layout, NULL);
|
|
||||||
vkDestroyDescriptorSetLayout(context->device,
|
|
||||||
context->descriptor_set_layout_bindless, NULL);
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#ifndef VULKAN_DESCRIPTORS_H
|
|
||||||
#define VULKAN_DESCRIPTORS_H
|
|
||||||
|
|
||||||
#include "utilities/commons.h"
|
|
||||||
#include "graphics_context.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_BINDLESS_RESOURCES 16536
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create descriptors
|
|
||||||
*
|
|
||||||
* @param context Graphics context handle
|
|
||||||
* @param vulkan_state
|
|
||||||
* @return rse_err_t RSE_ERROR_NO_ERROR on success
|
|
||||||
*/
|
|
||||||
rse_err_t create_descriptors(struct graphics_context_t* context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Destroy all descriptors
|
|
||||||
*
|
|
||||||
* @param context Graphics context handle
|
|
||||||
*/
|
|
||||||
void destroy_descriptors(struct graphics_context_t* context);
|
|
||||||
|
|
||||||
#endif /* VULKAN_DESCRIPTORS_H */
|
|
||||||
@@ -59,7 +59,6 @@ enum vulkan_error_t
|
|||||||
VULKAN_ERROR_UNKNOWN_DESCRIPTOR_TYPE,
|
VULKAN_ERROR_UNKNOWN_DESCRIPTOR_TYPE,
|
||||||
VULKAN_ERROR_DESCRIPTOR_SET_LAYOUT_CREATION_FAILED,
|
VULKAN_ERROR_DESCRIPTOR_SET_LAYOUT_CREATION_FAILED,
|
||||||
VULKAN_ERROR_DESCRIPTOR_SET_CREATION_FAILED,
|
VULKAN_ERROR_DESCRIPTOR_SET_CREATION_FAILED,
|
||||||
VULKAN_ERROR_DESCRIPTOR_POOL_CREATION_FAILED,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+11
-67
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
#include "utilities/file_utils.h"
|
|
||||||
#include "utilities/localization.h"
|
#include "utilities/localization.h"
|
||||||
#include "utilities/logger.h"
|
#include "utilities/logger.h"
|
||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
@@ -17,18 +16,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "stb/stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
||||||
#define IMAGE_TAKEN 1U
|
#define IMAGE_TAKEN 1U
|
||||||
#define IMAGE_FREE 0U
|
#define IMAGE_FREE 0U
|
||||||
|
|
||||||
/**
|
rse_err_t sampler_create(struct graphics_context_t* context, VkSampler* sampler)
|
||||||
* @brief Create a sampler object for texture sampling
|
|
||||||
*
|
|
||||||
* @param[in/out] context Graphics context to create sampler in
|
|
||||||
* @return RSE_ERROR_NO_ERROR on success, error code otherwise
|
|
||||||
*/
|
|
||||||
rse_err_t create_sampler(struct graphics_context_t* context, VkSampler sampler)
|
|
||||||
{
|
{
|
||||||
VkSamplerCreateInfo create_info = {0};
|
VkSamplerCreateInfo create_info = {0};
|
||||||
|
|
||||||
@@ -51,7 +44,7 @@ rse_err_t create_sampler(struct graphics_context_t* context, VkSampler sampler)
|
|||||||
create_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
create_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||||
create_info.unnormalizedCoordinates = VK_FALSE;
|
create_info.unnormalizedCoordinates = VK_FALSE;
|
||||||
|
|
||||||
if (VK_SUCCESS != vkCreateSampler(context->device, &create_info, NULL, &sampler)) {
|
if (VK_SUCCESS != vkCreateSampler(context->device, &create_info, NULL, sampler)) {
|
||||||
LOGF("Failed to create image view");
|
LOGF("Failed to create image view");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -126,6 +119,9 @@ static rse_err_t create_image(struct graphics_context_t* context, struct vulkan_
|
|||||||
return VULKAN_ERROR_IMAGE_NOT_CREATED;
|
return VULKAN_ERROR_IMAGE_NOT_CREATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int count = 1;
|
||||||
|
LOGI("Created image: %d\n", count++);
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,43 +305,13 @@ static rse_err_t create_textured_image(struct graphics_context_t* context, uint3
|
|||||||
|
|
||||||
staging_buffer_size = staging_buffer_size * width * height;
|
staging_buffer_size = staging_buffer_size * width * height;
|
||||||
|
|
||||||
STATUS_CHECK(create_image(context, free_texture_image, width, height, format, VK_SAMPLE_COUNT_8_BIT,
|
STATUS_CHECK(create_image(context, free_texture_image, width, height, format, VK_SAMPLE_COUNT_1_BIT,
|
||||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT));
|
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT));
|
||||||
|
|
||||||
// /* Put image into correct layout to copy pixels from buffer to image
|
|
||||||
// memory */ range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
// range.baseMipLevel = 0;
|
|
||||||
// range.levelCount = 1;
|
|
||||||
// range.baseArrayLayer = 0;
|
|
||||||
// range.layerCount = 1;
|
|
||||||
//
|
|
||||||
// image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
||||||
// image_barrier.pNext = NULL;
|
|
||||||
// image_barrier.srcAccessMask = 0U;
|
|
||||||
// image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
||||||
// image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
// image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
||||||
// image_barrier.srcQueueFamilyIndex = 0U;
|
|
||||||
// image_barrier.dstQueueFamilyIndex = 0U;
|
|
||||||
// image_barrier.image = free_texture_image->image;
|
|
||||||
// image_barrier.subresourceRange = range;
|
|
||||||
//
|
|
||||||
// command_buffer = begin_single_time_command();
|
|
||||||
// vkCmdPipelineBarrier(command_buffer,
|
|
||||||
// VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// NULL,
|
|
||||||
// 0,
|
|
||||||
// NULL,
|
|
||||||
// 1,
|
|
||||||
// &image_barrier);
|
|
||||||
// end_single_time_comands(command_buffer);
|
|
||||||
|
|
||||||
transition_image_layout(context, free_texture_image, VK_IMAGE_LAYOUT_UNDEFINED,
|
transition_image_layout(context, free_texture_image, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
/* Copy pixel data to GPU memory */
|
/* Copy pixel data to GPU memory */
|
||||||
STATUS_CHECK(create_buffer(
|
STATUS_CHECK(create_buffer(
|
||||||
context, staging_buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
context, staging_buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
|
||||||
@@ -371,28 +337,6 @@ static rse_err_t create_textured_image(struct graphics_context_t* context, uint3
|
|||||||
end_single_time_comands(context, command_buffer);
|
end_single_time_comands(context, command_buffer);
|
||||||
destroy_buffer(context, &staging_buffer);
|
destroy_buffer(context, &staging_buffer);
|
||||||
|
|
||||||
transition_image_layout(context, free_texture_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
|
|
||||||
// /* Change image layout for shaders to be able to read it */
|
|
||||||
// image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
||||||
// image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
||||||
// image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
||||||
// image_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
||||||
//
|
|
||||||
// command_buffer = begin_single_time_command();
|
|
||||||
// vkCmdPipelineBarrier(command_buffer,
|
|
||||||
// VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
|
||||||
// 0,
|
|
||||||
// 0,
|
|
||||||
// NULL,
|
|
||||||
// 0,
|
|
||||||
// NULL,
|
|
||||||
// 1,
|
|
||||||
// &image_barrier);
|
|
||||||
// end_single_time_comands(command_buffer);
|
|
||||||
|
|
||||||
STATUS_CHECK(create_image_view(context, free_texture_image, format, VK_IMAGE_ASPECT_COLOR_BIT));
|
STATUS_CHECK(create_image_view(context, free_texture_image, format, VK_IMAGE_ASPECT_COLOR_BIT));
|
||||||
|
|
||||||
free_texture_image->id_taken = IMAGE_TAKEN;
|
free_texture_image->id_taken = IMAGE_TAKEN;
|
||||||
@@ -446,8 +390,6 @@ void destroy_textures(struct graphics_context_t* context)
|
|||||||
{
|
{
|
||||||
size_t i = 0U;
|
size_t i = 0U;
|
||||||
|
|
||||||
vkDestroySampler(context->device, context->sampler, NULL);
|
|
||||||
|
|
||||||
for (i = 0U; i < RSE_MAX_IMAGE_COUNT; ++i) {
|
for (i = 0U; i < RSE_MAX_IMAGE_COUNT; ++i) {
|
||||||
if (context->texture_images[i].id_taken == IMAGE_TAKEN) {
|
if (context->texture_images[i].id_taken == IMAGE_TAKEN) {
|
||||||
vkDestroyImageView(context->device, context->texture_images[i].image_view, NULL);
|
vkDestroyImageView(context->device, context->texture_images[i].image_view, NULL);
|
||||||
@@ -455,6 +397,8 @@ void destroy_textures(struct graphics_context_t* context)
|
|||||||
context->texture_images[i].allocation);
|
context->texture_images[i].allocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vkDestroySampler(context->device, context->sampler, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_depth_resource(struct graphics_context_t* context)
|
void destroy_depth_resource(struct graphics_context_t* context)
|
||||||
|
|||||||
@@ -83,6 +83,12 @@ void destroy_color_resource(struct graphics_context_t* context);
|
|||||||
rse_err_t create_depth_resources(struct graphics_context_t* context);
|
rse_err_t create_depth_resources(struct graphics_context_t* context);
|
||||||
void destroy_depth_resource(struct graphics_context_t* context);
|
void destroy_depth_resource(struct graphics_context_t* context);
|
||||||
|
|
||||||
rse_err_t create_sampler(struct graphics_context_t* context, VkSampler sampler);
|
/**
|
||||||
|
* @brief Create a sampler object for texture sampling
|
||||||
|
*
|
||||||
|
* @param[in/out] context Graphics context to create sampler in
|
||||||
|
* @return RSE_ERROR_NO_ERROR on success, error code otherwise
|
||||||
|
*/
|
||||||
|
rse_err_t sampler_create(struct graphics_context_t* context, VkSampler* sampler);
|
||||||
|
|
||||||
#endif /* TEXTURE_H */
|
#endif /* TEXTURE_H */
|
||||||
@@ -20,16 +20,16 @@
|
|||||||
rse_err_t create_render_pass(struct graphics_context_t* context)
|
rse_err_t create_render_pass(struct graphics_context_t* context)
|
||||||
{
|
{
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
VkAttachmentDescription attachments[3] = {};
|
VkAttachmentDescription attachments[3] = {0};
|
||||||
VkAttachmentDescription color_attachment = {};
|
VkAttachmentDescription color_attachment = {0};
|
||||||
VkAttachmentReference color_attachment_ref = {};
|
VkAttachmentReference color_attachment_ref = {0};
|
||||||
VkAttachmentDescription color_attachment_resolve = {};
|
VkAttachmentDescription color_attachment_resolve = {0};
|
||||||
VkAttachmentReference color_attachment_resolve_ref = {};
|
VkAttachmentReference color_attachment_resolve_ref = {0};
|
||||||
VkSubpassDescription subpass = {};
|
VkSubpassDescription subpass = {0};
|
||||||
VkRenderPassCreateInfo renderpass_info = {};
|
VkRenderPassCreateInfo renderpass_info = {0};
|
||||||
VkAttachmentDescription depth_attachment = {};
|
VkAttachmentDescription depth_attachment = {0};
|
||||||
VkAttachmentReference depth_attachment_ref = {};
|
VkAttachmentReference depth_attachment_ref = {0};
|
||||||
VkSubpassDependency dependency = {};
|
VkSubpassDependency dependency = {0};
|
||||||
|
|
||||||
STATUS_CHECK(find_depth_format(context, &depth_attachment.format));
|
STATUS_CHECK(find_depth_format(context, &depth_attachment.format));
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <SDL3/SDL_events.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -7,7 +8,6 @@
|
|||||||
#include "utilities/localization.h"
|
#include "utilities/localization.h"
|
||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
#include "vulkan_commons.h"
|
#include "vulkan_commons.h"
|
||||||
#include "vulkan_descriptors.h"
|
|
||||||
#include "vulkan_errors.h"
|
#include "vulkan_errors.h"
|
||||||
#include "vulkan_image.h"
|
#include "vulkan_image.h"
|
||||||
#include "vulkan_swapchain.h"
|
#include "vulkan_swapchain.h"
|
||||||
@@ -41,7 +41,7 @@ static rse_err_t create_swapchain(struct graphics_context_t* context)
|
|||||||
create_info.pNext = NULL;
|
create_info.pNext = NULL;
|
||||||
create_info.flags = 0U;
|
create_info.flags = 0U;
|
||||||
create_info.surface = context->surface;
|
create_info.surface = context->surface;
|
||||||
create_info.minImageCount = SWAP_BUFFER_COUNT + 1;
|
create_info.minImageCount = SWAP_BUFFER_COUNT;
|
||||||
create_info.imageFormat = IMAGE_FORMAT;
|
create_info.imageFormat = IMAGE_FORMAT;
|
||||||
create_info.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
create_info.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||||
create_info.imageExtent = context->swapchain_extent;
|
create_info.imageExtent = context->swapchain_extent;
|
||||||
@@ -132,7 +132,7 @@ static rse_err_t create_framebuffers(struct graphics_context_t* context)
|
|||||||
context->depth_image.image_view,
|
context->depth_image.image_view,
|
||||||
context->swapchain_image_views[i]};
|
context->swapchain_image_views[i]};
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebufferInfo = {};
|
VkFramebufferCreateInfo framebufferInfo = {0};
|
||||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
framebufferInfo.renderPass = context->render_pass;
|
framebufferInfo.renderPass = context->render_pass;
|
||||||
framebufferInfo.attachmentCount = 3;
|
framebufferInfo.attachmentCount = 3;
|
||||||
@@ -158,13 +158,14 @@ static rse_err_t create_framebuffers(struct graphics_context_t* context)
|
|||||||
*/
|
*/
|
||||||
void recreate_swapchain(struct graphics_context_t* context)
|
void recreate_swapchain(struct graphics_context_t* context)
|
||||||
{
|
{
|
||||||
|
SDL_Event event;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
glfwGetFramebufferSize(context->window_handle, &width, &height);
|
SDL_GetWindowSizeInPixels(context->window_handle, &width, &height);
|
||||||
while (width == 0 || height == 0) {
|
while (width == 0 || height == 0) {
|
||||||
glfwGetFramebufferSize(context->window_handle, &width, &height);
|
SDL_GetWindowSizeInPixels(context->window_handle, &width, &height);
|
||||||
glfwWaitEvents();
|
SDL_WaitEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDeviceWaitIdle(context->device);
|
vkDeviceWaitIdle(context->device);
|
||||||
|
|||||||
+20
-73
@@ -10,8 +10,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include <SDL3/SDL_events.h>
|
||||||
|
#include <SDL3/SDL_init.h>
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "GLFW/glfw3.h"
|
#include "utilities/commons.h"
|
||||||
#include "utilities/localization.h"
|
#include "utilities/localization.h"
|
||||||
#include "window_errors.h"
|
#include "window_errors.h"
|
||||||
#include "utilities/logger.h"
|
#include "utilities/logger.h"
|
||||||
@@ -19,88 +23,32 @@
|
|||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
#include "vulkan_base.h"
|
#include "vulkan_base.h"
|
||||||
|
|
||||||
/**
|
rse_err_t window_init(SDL_Window **window_handle, bool *is_framebuffer_resized)
|
||||||
* @brief GLFW error callback
|
|
||||||
*
|
|
||||||
* @param error Error code
|
|
||||||
* @param description Error description
|
|
||||||
*/
|
|
||||||
static void error_callback(int error, const char* description)
|
|
||||||
{
|
{
|
||||||
(void)error;
|
SDL_Init(SDL_INIT_VIDEO); //TODO: Move to initial phase of RSE initialization
|
||||||
LOGE("Error: %s", description);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
*window_handle = SDL_CreateWindow("RedScarfEngine", 1024, 768, SDL_WINDOW_VULKAN);
|
||||||
* @brief Pressed key callback
|
|
||||||
*
|
|
||||||
* @param window Window in which contex the key has been pressed
|
|
||||||
* @param key The keyboard key that was pressed or released
|
|
||||||
* @param scancode The system-specific scancode of the key.
|
|
||||||
* @param action GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT
|
|
||||||
* @param mods Bit field describing which modifier keys were held down
|
|
||||||
*/
|
|
||||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
||||||
{
|
|
||||||
(void)scancode;
|
|
||||||
(void)action;
|
|
||||||
(void)mods;
|
|
||||||
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
|
||||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void framebuffer_resized_callback(GLFWwindow* window, int width, int height)
|
|
||||||
{
|
|
||||||
bool* is_frambuffer_resized = (bool*)glfwGetWindowUserPointer(window);
|
|
||||||
(void)window;
|
|
||||||
(void)width;
|
|
||||||
(void)height;
|
|
||||||
*is_frambuffer_resized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rse_err_t window_init(GLFWwindow** window_handle, bool* is_framebuffer_resized)
|
|
||||||
{
|
|
||||||
/* Initiliaze GLFW AP */
|
|
||||||
if (GLFW_TRUE != glfwInit())
|
|
||||||
{
|
|
||||||
LOGF(_("GLFW init failed!\n"));
|
|
||||||
return WINDOW_ERROR_GLFW_INIT_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Check for Vulkan support */
|
|
||||||
if (GLFW_FALSE == glfwVulkanSupported()) {
|
|
||||||
LOGF(_("Unable to load Vulkan\n"));
|
|
||||||
return WINDOW_ERROR_VULKAN_NOT_LOADED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set error callback */
|
|
||||||
glfwSetErrorCallback(error_callback);
|
|
||||||
|
|
||||||
/* Create window */
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
||||||
|
|
||||||
*window_handle = glfwCreateWindow(640, 480, "RedScarfEngine", NULL, NULL);
|
|
||||||
|
|
||||||
if (NULL == *window_handle) {
|
if (NULL == *window_handle) {
|
||||||
LOGF(_("Window context creation failed\n"));
|
LOGF(_("Window context creation failed\n"));
|
||||||
return WINDOW_ERROR_WINDOW_NOT_CREATED;
|
return WINDOW_ERROR_WINDOW_NOT_CREATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSetKeyCallback(*window_handle, key_callback);
|
|
||||||
glfwSetFramebufferSizeCallback(*window_handle, framebuffer_resized_callback);
|
|
||||||
glfwSetWindowUserPointer(*window_handle, is_framebuffer_resized);
|
|
||||||
|
|
||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t window_loop(struct graphics_context_t* context)
|
rse_err_t window_loop(struct graphics_context_t* context)
|
||||||
{
|
{
|
||||||
while (!glfwWindowShouldClose(context->window_handle)) {
|
uint8_t done = 0;
|
||||||
glfwPollEvents();
|
SDL_Event event;
|
||||||
|
|
||||||
|
while (0 == done) {
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
if (SDL_EVENT_QUIT == event.type) {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draw_frame(context);
|
draw_frame(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +56,7 @@ rse_err_t window_loop(struct graphics_context_t* context)
|
|||||||
return RSE_ERROR_NO_ERROR;
|
return RSE_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_terminate(GLFWwindow* window_handle)
|
void window_terminate(SDL_Window* window_handle)
|
||||||
{
|
{
|
||||||
glfwDestroyWindow(window_handle);
|
SDL_DestroyWindow(window_handle);
|
||||||
glfwTerminate();
|
|
||||||
}
|
}
|
||||||
@@ -12,10 +12,10 @@
|
|||||||
#ifndef WINDOW_H
|
#ifndef WINDOW_H
|
||||||
#define WINDOW_H
|
#define WINDOW_H
|
||||||
|
|
||||||
|
#include <SDL3/SDL_main.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
/* Vulkan header MUST be included before glfw */
|
/* Vulkan header MUST be included before glfw */
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "utilities/commons.h"
|
#include "utilities/commons.h"
|
||||||
#include "graphics_context.h"
|
#include "graphics_context.h"
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
* WINDOW_WINDOW_NOT_CREATED
|
* WINDOW_WINDOW_NOT_CREATED
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
rse_err_t window_init(GLFWwindow** window_handle, bool* is_framebuffer_resized);
|
rse_err_t window_init(SDL_Window **window_handle, bool *is_framebuffer_resized);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Main window loop
|
* @brief Main window loop
|
||||||
@@ -45,6 +45,6 @@ rse_err_t window_loop(struct graphics_context_t* context);
|
|||||||
*
|
*
|
||||||
* @param window_handle Pointer to window window_handle
|
* @param window_handle Pointer to window window_handle
|
||||||
*/
|
*/
|
||||||
void window_terminate(GLFWwindow* window_handle);
|
void window_terminate(SDL_Window* window_handle);
|
||||||
|
|
||||||
#endif /* WINDOW_H */
|
#endif /* WINDOW_H */
|
||||||
@@ -1,22 +1,30 @@
|
|||||||
|
#include <SDL3/SDL_init.h>
|
||||||
#include "graphics/rse_graphics.h"
|
#include "graphics/rse_graphics.h"
|
||||||
#include "utilities/task.h"
|
|
||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
|
#include "utilities/logger.h"
|
||||||
|
#include "SDL3/SDL_thread.h"
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||||
thread_t graphics_task;
|
|
||||||
struct rse_graphics_context_t* context = NULL;
|
struct rse_graphics_context_t* context = NULL;
|
||||||
|
SDL_Thread* graphics_task = NULL;
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
STATUS_CHECK(rse_graphics_init(&context));
|
STATUS_CHECK(rse_graphics_init(&context));
|
||||||
rse_graphics_test_function(context);
|
rse_graphics_test_function(context);
|
||||||
create_task(&graphics_task, (thread_worker_t)rse_graphics_run, context);
|
|
||||||
|
|
||||||
task_join(&graphics_task);
|
graphics_task = SDL_CreateThread(rse_graphics_run, "graphics_task", (void*) context);
|
||||||
task_exit();
|
|
||||||
|
if (NULL == graphics_task) {
|
||||||
|
LOGE(_("Failed to create graphics task"));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_WaitThread(graphics_task, NULL);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
+19530
File diff suppressed because it is too large.
Load diff
@@ -1,3 +1,5 @@
|
|||||||
|
find_package(Intl)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
|
||||||
|
|
||||||
add_library(utilities SHARED)
|
add_library(utilities SHARED)
|
||||||
@@ -9,8 +11,7 @@ target_include_directories(utilities PRIVATE
|
|||||||
target_sources(utilities PRIVATE
|
target_sources(utilities PRIVATE
|
||||||
src/file_utils.c
|
src/file_utils.c
|
||||||
src/logger.c
|
src/logger.c
|
||||||
src/task_linux.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(utilities PRIVATE
|
target_link_libraries(utilities PRIVATE
|
||||||
pthread)
|
Intl::Intl)
|
||||||
@@ -26,6 +26,8 @@ enum common_error_t
|
|||||||
RSE_ERROR_NULL_POINTER,
|
RSE_ERROR_NULL_POINTER,
|
||||||
RSE_ERROR_ALREADY_INITIALIZED,
|
RSE_ERROR_ALREADY_INITIALIZED,
|
||||||
RSE_COMMON_ERROR_MALLLOC_FAILED,
|
RSE_COMMON_ERROR_MALLLOC_FAILED,
|
||||||
|
RSE_ERROR_INVALID_PARAM,
|
||||||
|
RSE_ERROR_INTERNAL_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ERRORS_COMMON_H
|
#define ERRORS_COMMON_H
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define FILE_UTILS_H
|
#define FILE_UTILS_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include "utilities/commons.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads file and puts its content into char buffer. If NULL is provided as buffer, than just bytes_count
|
* @brief Reads file and puts its content into char buffer. If NULL is provided as buffer, than just bytes_count
|
||||||
@@ -15,5 +16,7 @@ void read_file(const char* file_path, size_t* bytes_count, char* buffer);
|
|||||||
|
|
||||||
void write_to_file(const char* file_name, size_t bytes_count, char* buffer);
|
void write_to_file(const char* file_name, size_t bytes_count, char* buffer);
|
||||||
|
|
||||||
|
rse_err_t get_curr_path(char* path, size_t max_path_length);
|
||||||
|
|
||||||
#endif /* FILE_UTILS_H */
|
#endif /* FILE_UTILS_H */
|
||||||
|
|
||||||
+10
-10
@@ -30,21 +30,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define RSE_LINKED_LIST_PUSH_FRONT(list, value) \
|
#define RSE_LINKED_LIST_PUSH_FRONT(list, value) \
|
||||||
typeof(list) new_node = NULL; \
|
__typeof__(list) new_node = NULL; \
|
||||||
rse_malloc(new_node, sizeof(*(list))); \
|
rse_malloc(new_node, sizeof(*(list))); \
|
||||||
new_node->data = value; \
|
new_node->data = value; \
|
||||||
new_node->next = list; \
|
new_node->next = list; \
|
||||||
list = new_node
|
list = new_node
|
||||||
|
|
||||||
#define RSE_LINKED_LIST_PUSH_BACK(list, value) \
|
#define RSE_LINKED_LIST_PUSH_BACK(list, value) \
|
||||||
typeof(list) new_node = NULL; \
|
__typeof__((list)) new_node = NULL; \
|
||||||
rse_malloc(new_node, sizeof(*(list))); \
|
rse_malloc(new_node, sizeof(*(list))); \
|
||||||
new_node->data = value; \
|
new_node->data = value; \
|
||||||
new_node->next = NULL; \
|
new_node->next = NULL; \
|
||||||
if (list == NULL) { \
|
if (list == NULL) { \
|
||||||
list = new_node; \
|
list = new_node; \
|
||||||
} else { \
|
} else { \
|
||||||
typeof(list) current = list; \
|
__typeof__(list) current = list; \
|
||||||
while (current->next != NULL) { \
|
while (current->next != NULL) { \
|
||||||
current = current->next; \
|
current = current->next; \
|
||||||
} \
|
} \
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
#define RSE_LINKED_LIST_POP_FRONT(list) \
|
#define RSE_LINKED_LIST_POP_FRONT(list) \
|
||||||
if (list != NULL) { \
|
if (list != NULL) { \
|
||||||
typeof(list) temp = list; \
|
__typeof__(list) temp = list; \
|
||||||
list = list->next; \
|
list = list->next; \
|
||||||
rse_free(temp); \
|
rse_free(temp); \
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
rse_free(list); \
|
rse_free(list); \
|
||||||
list = NULL; \
|
list = NULL; \
|
||||||
} else { \
|
} else { \
|
||||||
typeof(list) *current = list; \
|
__typeof__(list) *current = list; \
|
||||||
while (current->next->next != NULL) { \
|
while (current->next->next != NULL) { \
|
||||||
current = current->next; \
|
current = current->next; \
|
||||||
} \
|
} \
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
#define RSE_LINKED_LIST_BACK(list) \
|
#define RSE_LINKED_LIST_BACK(list) \
|
||||||
if (list != NULL) { \
|
if (list != NULL) { \
|
||||||
typeof(list) *current = list; \
|
__typeof__(list) *current = list; \
|
||||||
while (current->next != NULL) { \
|
while (current->next != NULL) { \
|
||||||
current = current->next; \
|
current = current->next; \
|
||||||
} \
|
} \
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
#define RSE_LINKED_LIST_SIZE(list) \
|
#define RSE_LINKED_LIST_SIZE(list) \
|
||||||
({ \
|
({ \
|
||||||
int size = 0; \
|
int size = 0; \
|
||||||
typeof(list) current = list; \
|
__typeof__(list) current = list; \
|
||||||
while (current != NULL) { \
|
while (current != NULL) { \
|
||||||
size++; \
|
size++; \
|
||||||
current = current->next; \
|
current = current->next; \
|
||||||
@@ -101,17 +101,17 @@
|
|||||||
|
|
||||||
#define RSE_LINKED_LIST_CLEAR(list) \
|
#define RSE_LINKED_LIST_CLEAR(list) \
|
||||||
while (list != NULL) { \
|
while (list != NULL) { \
|
||||||
typeof(list) temp = list; \
|
__typeof__(list) temp = list; \
|
||||||
list = list->next; \
|
list = list->next; \
|
||||||
rse_free(temp); \
|
rse_free(temp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RSE_LINKED_LIST_FOREACH(list, i) \
|
#define RSE_LINKED_LIST_FOREACH(list, i) \
|
||||||
for (typeof(list) i = list; i != NULL; i = i->next)
|
for (__typeof__(list) i = list; i != NULL; i = i->next)
|
||||||
|
|
||||||
|
|
||||||
#define RSE_LINKED_LIST_FOREACH_REVERSE(list, i) \
|
#define RSE_LINKED_LIST_FOREACH_REVERSE(list, i) \
|
||||||
for (typeof(list) i = list; i != NULL; i = i->next)
|
for (__typeof__(list) i = list; i != NULL; i = i->next)
|
||||||
|
|
||||||
#define RSE_LINKED_LIST_TO_ARRAY(list, array) \
|
#define RSE_LINKED_LIST_TO_ARRAY(list, array) \
|
||||||
({ \
|
({ \
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#ifndef LOGGER_H
|
#ifndef LOGGER_H
|
||||||
#define LOGGER_H
|
#define LOGGER_H
|
||||||
|
|
||||||
|
#include "utilities/localization.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,27 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "utilities/commons.h"
|
||||||
|
#include "utilities/errors_common.h"
|
||||||
|
#include "utilities/localization.h"
|
||||||
|
#include "utilities/logger.h"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#endif /* ifndef __linux */
|
||||||
|
|
||||||
|
#define MAX_PATH_LENGTH (4096U)
|
||||||
|
|
||||||
void read_file(const char* file_name, size_t* bytes_count, char* buffer)
|
void read_file(const char* file_name, size_t* bytes_count, char* buffer)
|
||||||
{
|
{
|
||||||
errno_t err = 0;
|
|
||||||
FILE* file = NULL;
|
FILE* file = NULL;
|
||||||
|
|
||||||
err = fopen_s(&file, file_name, "rb");
|
file = fopen(file_name, "rb");
|
||||||
|
|
||||||
if (0 != err) {
|
if (NULL == file) {
|
||||||
perror("Failed to open file");
|
LOGE(_("Failed to open file for read: %s\n"), file_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,16 +44,71 @@ void read_file(const char* file_name, size_t* bytes_count, char* buffer)
|
|||||||
|
|
||||||
void write_to_file(const char* file_name, size_t bytes_count, char* buffer)
|
void write_to_file(const char* file_name, size_t bytes_count, char* buffer)
|
||||||
{
|
{
|
||||||
errno_t err = 0;
|
|
||||||
FILE* file = NULL;
|
FILE* file = NULL;
|
||||||
|
|
||||||
err = fopen_s(&file, file_name, "wb");
|
file = fopen(file_name, "wb");
|
||||||
|
|
||||||
if (0 != err) {
|
if (NULL == file) {
|
||||||
perror("Failed to open file.");
|
LOGE(_("Failed to open file for write: %s\n"), file_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(buffer, bytes_count, 1, file);
|
fwrite(buffer, bytes_count, 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rse_err_t get_curr_path(char* path, size_t path_size)
|
||||||
|
{
|
||||||
|
char* last_sep = NULL;
|
||||||
|
char* tmp_path = NULL;
|
||||||
|
size_t binary_path_length = 0U;
|
||||||
|
size_t directory_path_length = 0U;
|
||||||
|
|
||||||
|
if (NULL == path) {
|
||||||
|
LOGE(_("Failed to get path. Provided pointer is NULL\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == path_size) {
|
||||||
|
LOGE(_("Max path length cannot be 0\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rse_memset(path, '\0', path_size);
|
||||||
|
rse_malloc(tmp_path, MAX_PATH_LENGTH);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
binary_path_length = readlink("/proc/self/exe", tmp_path, MAX_PATH_LENGTH - 1);
|
||||||
|
if (binary_path_length == -1) {
|
||||||
|
LOGF(_("Failed to read current binary path\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_path[binary_path_length] = '\0';
|
||||||
|
#endif /* ifdef __linux__ */
|
||||||
|
|
||||||
|
last_sep = strrchr(tmp_path, '/') + 1;
|
||||||
|
|
||||||
|
if (NULL == last_sep) {
|
||||||
|
LOGE(_("Failed to get last separator in path\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
directory_path_length = last_sep - tmp_path;
|
||||||
|
|
||||||
|
if (directory_path_length > path_size) {
|
||||||
|
LOGE(_("Provided path buffer is too small\n"));
|
||||||
|
|
||||||
|
return RSE_ERROR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(path, tmp_path, directory_path_length);
|
||||||
|
|
||||||
|
free(tmp_path);
|
||||||
|
|
||||||
|
return RSE_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ const char* log_levels[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifndef LOGLEVEL
|
#ifndef LOGLEVEL
|
||||||
#define LOGLEVEL LOGLEVEL_DEBUG
|
#define LOGLEVEL LOGLEVEL_TRACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _log_log(unsigned int level, const char* file, int line, const char* fmt, ...)
|
void _log_log(unsigned int level, const char* file, int line, const char* fmt, ...)
|
||||||
|
|||||||
Reference in new issue
Block a user