From bd4dd748812460dcae0e9e6f93cf3f5c7b909fe6 Mon Sep 17 00:00:00 2001 From: Piotr Krygier Date: Wed, 4 Oct 2023 13:28:06 +0200 Subject: [PATCH] Add bindless textures Created bindless descriptors for holding texture data. --- graphics/CMakeLists.txt | 9 +++++++ graphics/rse_graphics.h | 2 ++ graphics/shaders/shader.frag | 5 +++- graphics/src/rse_graphics.c | 32 ++++++++-------------- graphics/src/rse_vulkan_image.c | 3 --- graphics/src/shaders/shader.frag | 14 ++++++++++ graphics/src/vulkan_base.c | 23 +++++++++++++--- graphics/src/vulkan_buffers.c | 6 +++-- graphics/src/vulkan_commons.h | 2 ++ graphics/src/vulkan_descriptors.c | 45 +++++++++++++++++++++++++++---- graphics/src/vulkan_descriptors.h | 3 +++ graphics/src/vulkan_pipeline.c | 34 +++++++++++++++++------ red_scarf_engine/src/main.c | 1 + 13 files changed, 136 insertions(+), 43 deletions(-) create mode 100644 graphics/src/shaders/shader.frag diff --git a/graphics/CMakeLists.txt b/graphics/CMakeLists.txt index 1608148c..6b702e11 100644 --- a/graphics/CMakeLists.txt +++ b/graphics/CMakeLists.txt @@ -25,6 +25,15 @@ function(compile_shader) endforeach() endfunction() +# Replace CMAKE_IMAGE_MAX_COUNT in both source file and shader +# TODO: Please do better +file(READ src/rse_vulkan_image.c FILE_CONTENTS) +string(REPLACE "" "1" FILE_CONTENTS "${FILE_CONTENTS}") +file(WRITE src/rse_vulkan_image.c "${FILE_CONTENTS}") + +file(READ shaders/shader.frag FILE_CONTENTS) +string(REPLACE "" "1" FILE_CONTENTS "${FILE_CONTENTS}") +file(WRITE src/shaders/shader.frag "${FILE_CONTENTS}") compile_shader(rse_graphics diff --git a/graphics/rse_graphics.h b/graphics/rse_graphics.h index 64829281..b5ef3c6e 100644 --- a/graphics/rse_graphics.h +++ b/graphics/rse_graphics.h @@ -6,4 +6,6 @@ void rse_graphics_init(void); uint8_t rse_graphics_run(void); +void rse_graphics_test_function(void); + #endif /* RSE_GRAPHICS_H */ \ No newline at end of file diff --git a/graphics/shaders/shader.frag b/graphics/shaders/shader.frag index 9784f2dc..64b5b629 100644 --- a/graphics/shaders/shader.frag +++ b/graphics/shaders/shader.frag @@ -1,7 +1,10 @@ #version 450 /* Each time texture count is changed this value also need to change. I have to fix it somehow. */ -layout(binding = 1) uniform sampler2D texSampler[1]; + +#extension GL_EXT_nonuniform_qualifier : enable + +layout(set = 1, binding = 1) uniform sampler2D texSampler[]; layout(location = 0) in vec3 fragColor; layout(location = 1) in vec2 fragTexCoord; diff --git a/graphics/src/rse_graphics.c b/graphics/src/rse_graphics.c index 2f0ce573..1ad10820 100644 --- a/graphics/src/rse_graphics.c +++ b/graphics/src/rse_graphics.c @@ -12,37 +12,24 @@ extern struct rse_vulkan_state_t g_vulkan_state; void rse_graphics_init(void) { - // g_vulkan_state = malloc(sizeof(struct rse_vulkan_state_t)); g_vulkan_state.graphics_queue = VK_NULL_HANDLE; g_vulkan_state.physical_device = VK_NULL_HANDLE; g_vulkan_state.current_frame = 0U; - // vulkan_state->queueFamilyIndices = {0U}; /* TODO: Change when more families are needed */ - // g_vulkan_state->uniformBuffers = {}; - // g_vulkan_state->pCommandBuffers = {}; - // g_vulkan_state->descriptorSets = {}; - // g_vulkan_state->swapChainImageViews = {}; TODO: Allocate later - // g_vulkan_state->swapchainExtent = {}; TODO: Allocate later g_vulkan_state.render_pass = VK_NULL_HANDLE; g_vulkan_state.descriptor_set_layout = VK_NULL_HANDLE; - // g_vulkan_state->swapchainFramebuffers = {}; TODO: Allocate later g_vulkan_state.graphics_pipeline = VK_NULL_HANDLE; g_vulkan_state.pipeline_layout = VK_NULL_HANDLE; g_vulkan_state.swapchain = VK_NULL_HANDLE; -} -void rse_graphics_deinit() -{ - // free(g_vulkan_state); -} - - -uint8_t rse_graphics_run(void) -{ - int8_t tex_id_2 = 0; window_init(); if (0 != preinit_vulkan()) - return -1; + return; +} + +void rse_graphics_test_function(void) +{ + int8_t tex_id_2 = 0; tex_id_2 = rse_load_texture("../../test_image.png"); @@ -82,10 +69,13 @@ uint8_t rse_graphics_run(void) 1.0f, tex_id_2 }); +} - - if (0 != init_vulkan()) +uint8_t rse_graphics_run(void) +{ + if (0 != init_vulkan()) { return -1; + } window_loop(); diff --git a/graphics/src/rse_vulkan_image.c b/graphics/src/rse_vulkan_image.c index 735720c9..44c01e87 100644 --- a/graphics/src/rse_vulkan_image.c +++ b/graphics/src/rse_vulkan_image.c @@ -366,7 +366,6 @@ static int8_t create_vulkan_image(uint32_t width, uint32_t height, VkFormat form image_view_create_info.image = free_texture_image->image; image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; image_view_create_info.format = format; - // image_view_create_info.components = 0; image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; image_view_create_info.subresourceRange.baseMipLevel = 0; image_view_create_info.subresourceRange.levelCount = 1; @@ -389,8 +388,6 @@ uint8_t init_vulkan_images() { uint8_t status = VULKAN_ERROR_NO_ERROR; - // memset(g_texture_images, 0, sizeof(struct rse_vulkan_image_t) * RSE_MAX_IMAGE_COUNT); - STATUS_CHECK(create_sampler()); STATUS_CHECK(create_depth_resources()); diff --git a/graphics/src/shaders/shader.frag b/graphics/src/shaders/shader.frag new file mode 100644 index 00000000..9784f2dc --- /dev/null +++ b/graphics/src/shaders/shader.frag @@ -0,0 +1,14 @@ +#version 450 + +/* Each time texture count is changed this value also need to change. I have to fix it somehow. */ +layout(binding = 1) uniform sampler2D texSampler[1]; + +layout(location = 0) in vec3 fragColor; +layout(location = 1) in vec2 fragTexCoord; +layout(location = 2) in flat uint instanceTextureId; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor * texture(texSampler[instanceTextureId], fragTexCoord).rgb, 1.0); +} \ No newline at end of file diff --git a/graphics/src/vulkan_base.c b/graphics/src/vulkan_base.c index d7b89934..292a1ff5 100644 --- a/graphics/src/vulkan_base.c +++ b/graphics/src/vulkan_base.c @@ -342,6 +342,8 @@ uint8_t pick_physical_device() { uint32_t physical_device_count = 0U; VkPhysicalDevice* physical_devices = NULL; + VkPhysicalDeviceProperties device_properties = {0};; + VkPhysicalDeviceFeatures device_features = {0}; /* Get number of existing physical devices */ vkEnumeratePhysicalDevices(g_vulkan_instance, &physical_device_count, NULL); @@ -356,8 +358,6 @@ uint8_t pick_physical_device() /* Check for suitability */ for (size_t physicalDeviceIdx = 0U; physicalDeviceIdx < physical_device_count; ++physicalDeviceIdx) { - VkPhysicalDeviceProperties device_properties; - VkPhysicalDeviceFeatures device_features; vkGetPhysicalDeviceProperties(physical_devices[physicalDeviceIdx], &device_properties); vkGetPhysicalDeviceFeatures(physical_devices[physicalDeviceIdx], &device_features); @@ -398,6 +398,22 @@ uint8_t create_device() VkDeviceQueueCreateInfo device_queue_createinfos[2] = {}; /* TODO: Change when we want more queues */ float* graphics_familiy_queue_priorities = NULL; float* presentation_familiy_queue_priorities = NULL; + VkPhysicalDeviceFeatures2 physical_features2 = {0}; + VkPhysicalDeviceDescriptorIndexingFeatures indexing_features = {0}; + VkBool32 bindless_supported = VK_FALSE; + + indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; + + physical_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + physical_features2.pNext = &indexing_features; + + vkGetPhysicalDeviceFeatures2(g_vulkan_state.physical_device, &physical_features2); + + bindless_supported = indexing_features.descriptorBindingPartiallyBound && indexing_features.runtimeDescriptorArray; + if (bindless_supported == VK_FALSE) { + LOGE("This engine requires bindless support"); + return 1; + } /* Get information about supported queue families */ vkGetPhysicalDeviceQueueFamilyProperties(g_vulkan_state.physical_device, &queue_families_property_count, NULL); @@ -473,7 +489,7 @@ uint8_t create_device() device_queue_createinfos[1].pQueuePriorities = presentation_familiy_queue_priorities; device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - device_create_info.pNext = NULL; + device_create_info.pNext = &physical_features2; device_create_info.flags = 0U; device_create_info.queueCreateInfoCount = device_queues_count; device_create_info.pQueueCreateInfos = device_queue_createinfos; @@ -483,6 +499,7 @@ uint8_t create_device() device_create_info.ppEnabledExtensionNames = g_enabled_device_extensions_names; device_create_info.pEnabledFeatures = NULL; /* TODO: Enable features, when needed */ + if (VK_SUCCESS != vkCreateDevice(g_vulkan_state.physical_device, &device_create_info, NULL, &g_vulkan_state.device)) { LOGF(vulkan_error_messages[VULKAN_FAILED_TO_CREATE_DEVICE]); return VULKAN_ERROR_DEVICE_CREATION_FAILED; diff --git a/graphics/src/vulkan_buffers.c b/graphics/src/vulkan_buffers.c index 3b99bc6e..8aa3d49e 100644 --- a/graphics/src/vulkan_buffers.c +++ b/graphics/src/vulkan_buffers.c @@ -330,6 +330,8 @@ uint8_t update_mesh_instances(uint16_t mesh_id, struct rse_instance_data_t* inst uint8_t record_command_buffer(uint32_t image_index) { VkCommandBuffer command_buffer = g_vulkan_state.command_buffers[g_vulkan_state.current_frame]; + VkDescriptorSet descriptor_sets[] = {g_vulkan_state.descriptor_sets[g_vulkan_state.current_frame], + g_vulkan_state.descriptor_sets_bindless}; VkCommandBufferBeginInfo begin_info = {}; VkRenderPassBeginInfo render_pass_info = {}; VkViewport viewport = {}; @@ -381,8 +383,8 @@ uint8_t record_command_buffer(uint32_t image_index) vkCmdBindVertexBuffers(command_buffer, 0, 1, &g_vertex_buffer.buffer, offsets); vkCmdBindIndexBuffer(command_buffer, g_index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_vulkan_state.pipeline_layout, 0, 1, - &g_vulkan_state.descriptor_sets[g_vulkan_state.current_frame], 0, NULL); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_vulkan_state.pipeline_layout, 0, 2, + descriptor_sets, 0, NULL); for (i = 0; i < 2; ++i) { VkBuffer instance_buffer = {g_instance_buffers[i].buffer}; diff --git a/graphics/src/vulkan_commons.h b/graphics/src/vulkan_commons.h index 63b0339a..3143cc38 100644 --- a/graphics/src/vulkan_commons.h +++ b/graphics/src/vulkan_commons.h @@ -64,10 +64,12 @@ struct rse_vulkan_state_t struct rse_vulkan_buffer_t uniform_buffers[SWAP_BUFFER_COUNT]; VkCommandBuffer command_buffers[SWAP_BUFFER_COUNT]; VkDescriptorSet descriptor_sets[SWAP_BUFFER_COUNT]; + VkDescriptorSet descriptor_sets_bindless; VkImageView* swapchain_image_views; VkExtent2D swapchain_extent; VkRenderPass render_pass; VkDescriptorSetLayout descriptor_set_layout; + VkDescriptorSetLayout descriptor_set_layout_bindless; VkFramebuffer* swapchain_framebuffers; VkPipeline graphics_pipeline; VkPipelineLayout pipeline_layout; diff --git a/graphics/src/vulkan_descriptors.c b/graphics/src/vulkan_descriptors.c index 5c1a0eb0..4ff1c0b3 100644 --- a/graphics/src/vulkan_descriptors.c +++ b/graphics/src/vulkan_descriptors.c @@ -8,7 +8,9 @@ #include "vulkan/vulkan.h" + VkDescriptorPool gDescriptorPool; +VkDescriptorPool gDescriptorPool_bindless; static uint8_t create_descriptor_pool(); static uint8_t create_descriptor_sets(); @@ -27,12 +29,12 @@ uint8_t create_descriptor_pool() 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_SAMPLER; - pool_sizes[1].descriptorCount = (uint32_t)(SWAP_BUFFER_COUNT*get_textures_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 = 2; - pool_info.pPoolSizes = pool_sizes; + pool_info.poolSizeCount = 1; + pool_info.pPoolSizes = &pool_sizes[0]; pool_info.maxSets = (uint32_t)(SWAP_BUFFER_COUNT); if (vkCreateDescriptorPool(g_vulkan_state.device, &pool_info, NULL, &gDescriptorPool) != VK_SUCCESS) { @@ -40,6 +42,15 @@ uint8_t create_descriptor_pool() 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(g_vulkan_state.device, &pool_info, NULL, &gDescriptorPool_bindless) != VK_SUCCESS) { + LOGF(vulkan_error_messages[VULKAN_DESCRIPTOR_POOL_CREATION_FAILED]); + return VULKAN_ERROR_DESCRIPTOR_POOL_CREATION_FAILED; + } + return VULKAN_ERROR_NO_ERROR; } @@ -50,22 +61,44 @@ uint8_t create_descriptor_pool() * VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED */ uint8_t create_descriptor_sets() { + uint32_t max_binding = MAX_BINDLESS_RESOURCES - 1; VkDescriptorSetLayout layouts[SWAP_BUFFER_COUNT] = { g_vulkan_state.descriptor_set_layout, g_vulkan_state.descriptor_set_layout }; + VkDescriptorSetLayout layouts_bindless[SWAP_BUFFER_COUNT] = { + g_vulkan_state.descriptor_set_layout_bindless, + g_vulkan_state.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 = gDescriptorPool; allocInfo.descriptorSetCount = (uint32_t)(SWAP_BUFFER_COUNT); allocInfo.pSetLayouts = layouts; + allocInfo_bindless = allocInfo; + allocInfo_bindless.descriptorPool = gDescriptorPool_bindless; + allocInfo_bindless.pSetLayouts = layouts_bindless; + allocInfo_bindless.pNext = &count_info; + allocInfo_bindless.descriptorSetCount = 1; + if (vkAllocateDescriptorSets(g_vulkan_state.device, &allocInfo, g_vulkan_state.descriptor_sets) != VK_SUCCESS) { LOGF(vulkan_error_messages[VULKAN_DESCRIPTOR_SETS_ALLOCATION_FAILED]); return VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED; } + if (vkAllocateDescriptorSets(g_vulkan_state.device, &allocInfo_bindless, &g_vulkan_state.descriptor_sets_bindless) != VK_SUCCESS) { + LOGF(vulkan_error_messages[VULKAN_DESCRIPTOR_SETS_ALLOCATION_FAILED]); + return VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED; + } + for (size_t i = 0; i < SWAP_BUFFER_COUNT; i++) { VkDescriptorBufferInfo buffer_info = {}; VkWriteDescriptorSet descriptor_writes[2] = {}; @@ -95,7 +128,7 @@ uint8_t create_descriptor_sets() descriptor_writes[0].pBufferInfo = &buffer_info; descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_writes[1].dstSet = g_vulkan_state.descriptor_sets[i]; + descriptor_writes[1].dstSet = g_vulkan_state.descriptor_sets_bindless; descriptor_writes[1].dstBinding = 1; descriptor_writes[1].dstArrayElement = 0; descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; @@ -121,5 +154,7 @@ uint8_t create_descriptors() void destroy_descriptors() { vkDestroyDescriptorPool(g_vulkan_state.device, gDescriptorPool, NULL); + vkDestroyDescriptorPool(g_vulkan_state.device, gDescriptorPool_bindless, NULL); vkDestroyDescriptorSetLayout(g_vulkan_state.device, g_vulkan_state.descriptor_set_layout, NULL); + vkDestroyDescriptorSetLayout(g_vulkan_state.device, g_vulkan_state.descriptor_set_layout_bindless, NULL); } \ No newline at end of file diff --git a/graphics/src/vulkan_descriptors.h b/graphics/src/vulkan_descriptors.h index d80ccf95..07b7144f 100644 --- a/graphics/src/vulkan_descriptors.h +++ b/graphics/src/vulkan_descriptors.h @@ -2,6 +2,9 @@ #define RSE_VULKAN_DESCRIPTORS_H #include + +#define MAX_BINDLESS_RESOURCES 16536 + /** * @brief Create descriptors * diff --git a/graphics/src/vulkan_pipeline.c b/graphics/src/vulkan_pipeline.c index 3471eed6..5e56a088 100644 --- a/graphics/src/vulkan_pipeline.c +++ b/graphics/src/vulkan_pipeline.c @@ -6,6 +6,7 @@ #include "vulkan_errors.h" #include "mesh_controller.h" #include "rse_vulkan_image.h" +#include "vulkan_descriptors.h" #include "vulkan/vulkan.h" @@ -294,10 +295,18 @@ uint8_t create_render_pass() uint8_t create_descriptor_set_layout() { VkDescriptorSetLayoutCreateInfo layout_info = {}; + VkDescriptorSetLayoutCreateInfo layout_info_bindless = {}; VkDescriptorSetLayoutBinding bindings[2]; VkDescriptorSetLayoutBinding ubo_layout_binding = {}; VkDescriptorSetLayoutBinding sampler_layout_binding = {}; - // VkDescriptorSetLayoutBinding textures_layout_binding = {}; + VkDescriptorSetLayoutBindingFlagsCreateInfoEXT extended_info = {0}; + VkDescriptorBindingFlags bindless_flags = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT + | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT + | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT; + + extended_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT; + extended_info.bindingCount = 1; + extended_info.pBindingFlags = &bindless_flags; ubo_layout_binding.binding = 0; ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -307,7 +316,7 @@ uint8_t create_descriptor_set_layout() sampler_layout_binding.binding = 1; sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - sampler_layout_binding.descriptorCount = get_textures_count(); + sampler_layout_binding.descriptorCount = MAX_BINDLESS_RESOURCES; sampler_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; sampler_layout_binding.pImmutableSamplers = NULL; @@ -315,16 +324,24 @@ uint8_t create_descriptor_set_layout() bindings[1] = sampler_layout_binding; layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layout_info.pNext = NULL; - layout_info.flags = 0U; - layout_info.bindingCount = 2U; - layout_info.pBindings = bindings; + layout_info.bindingCount = 1U; + layout_info.pBindings = &bindings[0]; if (vkCreateDescriptorSetLayout(g_vulkan_state.device, &layout_info, NULL, &g_vulkan_state.descriptor_set_layout) != VK_SUCCESS) { LOGF(vulkan_error_messages[VULKAN_DESCRIPTORSETLAYOUT_CREATION_FAILED]); return VULKAN_ERROR_DESCRIPTORSETLAYOUT_CREATION_FAILED; } + layout_info_bindless = layout_info; + layout_info_bindless.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT; + layout_info_bindless.pNext = &extended_info; + layout_info_bindless.pBindings = &bindings[1]; + + if (vkCreateDescriptorSetLayout(g_vulkan_state.device, &layout_info_bindless, NULL, &g_vulkan_state.descriptor_set_layout_bindless) != VK_SUCCESS) { + LOGF(vulkan_error_messages[VULKAN_DESCRIPTORSETLAYOUT_CREATION_FAILED]); + return VULKAN_ERROR_DESCRIPTORSETLAYOUT_CREATION_FAILED; + } + return VULKAN_ERROR_NO_ERROR; } /** @@ -335,12 +352,13 @@ uint8_t create_descriptor_set_layout() */ uint8_t create_pipeline_layout() { + VkDescriptorSetLayout set_layouts[2] = {g_vulkan_state.descriptor_set_layout, g_vulkan_state.descriptor_set_layout_bindless}; VkPipelineLayoutCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; create_info.pNext = NULL; create_info.flags = 0U; - create_info.setLayoutCount = 1U; - create_info.pSetLayouts = &g_vulkan_state.descriptor_set_layout; + create_info.setLayoutCount = 2U; + create_info.pSetLayouts = set_layouts; create_info.pushConstantRangeCount = 0U; create_info.pPushConstantRanges = NULL; diff --git a/red_scarf_engine/src/main.c b/red_scarf_engine/src/main.c index b438f964..0c08f888 100644 --- a/red_scarf_engine/src/main.c +++ b/red_scarf_engine/src/main.c @@ -9,6 +9,7 @@ int main(int argc, char** argv) (void)argv; rse_graphics_init(); + rse_graphics_test_function(); rse_create_task(&graphics_task, (thread_worker_t)rse_graphics_run, NULL); rse_task_join(&graphics_task);