Add bindless textures
Created bindless descriptors for holding texture data.
This commit is contained in:
1 parent
d328e38761
commit
bd4dd74881
13 files changed
+136
-43
No files matched your search
@@ -25,6 +25,15 @@ function(compile_shader)
|
|||||||
endforeach()
|
endforeach()
|
||||||
endfunction()
|
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 "<CMAKE_IMAGE_MAX_COUNT>" "1" FILE_CONTENTS "${FILE_CONTENTS}")
|
||||||
|
file(WRITE src/rse_vulkan_image.c "${FILE_CONTENTS}")
|
||||||
|
|
||||||
|
file(READ shaders/shader.frag FILE_CONTENTS)
|
||||||
|
string(REPLACE "<CMAKE_IMAGE_MAX_COUNT>" "1" FILE_CONTENTS "${FILE_CONTENTS}")
|
||||||
|
file(WRITE src/shaders/shader.frag "${FILE_CONTENTS}")
|
||||||
|
|
||||||
|
|
||||||
compile_shader(rse_graphics
|
compile_shader(rse_graphics
|
||||||
|
|||||||
@@ -6,4 +6,6 @@
|
|||||||
void rse_graphics_init(void);
|
void rse_graphics_init(void);
|
||||||
uint8_t rse_graphics_run(void);
|
uint8_t rse_graphics_run(void);
|
||||||
|
|
||||||
|
void rse_graphics_test_function(void);
|
||||||
|
|
||||||
#endif /* RSE_GRAPHICS_H */
|
#endif /* RSE_GRAPHICS_H */
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/* Each time texture count is changed this value also need to change. I have to fix it somehow. */
|
/* 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 = 0) in vec3 fragColor;
|
||||||
layout(location = 1) in vec2 fragTexCoord;
|
layout(location = 1) in vec2 fragTexCoord;
|
||||||
|
|||||||
+11
-21
@@ -12,37 +12,24 @@ extern struct rse_vulkan_state_t g_vulkan_state;
|
|||||||
|
|
||||||
void rse_graphics_init(void)
|
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.graphics_queue = VK_NULL_HANDLE;
|
||||||
g_vulkan_state.physical_device = VK_NULL_HANDLE;
|
g_vulkan_state.physical_device = VK_NULL_HANDLE;
|
||||||
g_vulkan_state.current_frame = 0U;
|
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.render_pass = VK_NULL_HANDLE;
|
||||||
g_vulkan_state.descriptor_set_layout = 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.graphics_pipeline = VK_NULL_HANDLE;
|
||||||
g_vulkan_state.pipeline_layout = VK_NULL_HANDLE;
|
g_vulkan_state.pipeline_layout = VK_NULL_HANDLE;
|
||||||
g_vulkan_state.swapchain = 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();
|
window_init();
|
||||||
|
|
||||||
if (0 != preinit_vulkan())
|
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");
|
tex_id_2 = rse_load_texture("../../test_image.png");
|
||||||
|
|
||||||
@@ -82,10 +69,13 @@ uint8_t rse_graphics_run(void)
|
|||||||
1.0f,
|
1.0f,
|
||||||
tex_id_2
|
tex_id_2
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rse_graphics_run(void)
|
||||||
if (0 != init_vulkan())
|
{
|
||||||
|
if (0 != init_vulkan()) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
window_loop();
|
window_loop();
|
||||||
|
|
||||||
|
|||||||
@@ -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.image = free_texture_image->image;
|
||||||
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
image_view_create_info.format = format;
|
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.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
image_view_create_info.subresourceRange.baseMipLevel = 0;
|
image_view_create_info.subresourceRange.baseMipLevel = 0;
|
||||||
image_view_create_info.subresourceRange.levelCount = 1;
|
image_view_create_info.subresourceRange.levelCount = 1;
|
||||||
@@ -389,8 +388,6 @@ uint8_t init_vulkan_images()
|
|||||||
{
|
{
|
||||||
uint8_t status = VULKAN_ERROR_NO_ERROR;
|
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_sampler());
|
||||||
STATUS_CHECK(create_depth_resources());
|
STATUS_CHECK(create_depth_resources());
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -342,6 +342,8 @@ uint8_t pick_physical_device()
|
|||||||
{
|
{
|
||||||
uint32_t physical_device_count = 0U;
|
uint32_t physical_device_count = 0U;
|
||||||
VkPhysicalDevice* physical_devices = NULL;
|
VkPhysicalDevice* physical_devices = NULL;
|
||||||
|
VkPhysicalDeviceProperties device_properties = {0};;
|
||||||
|
VkPhysicalDeviceFeatures device_features = {0};
|
||||||
|
|
||||||
/* Get number of existing physical devices */
|
/* Get number of existing physical devices */
|
||||||
vkEnumeratePhysicalDevices(g_vulkan_instance, &physical_device_count, NULL);
|
vkEnumeratePhysicalDevices(g_vulkan_instance, &physical_device_count, NULL);
|
||||||
@@ -356,8 +358,6 @@ uint8_t pick_physical_device()
|
|||||||
|
|
||||||
/* Check for suitability */
|
/* Check for suitability */
|
||||||
for (size_t physicalDeviceIdx = 0U; physicalDeviceIdx < physical_device_count; ++physicalDeviceIdx) {
|
for (size_t physicalDeviceIdx = 0U; physicalDeviceIdx < physical_device_count; ++physicalDeviceIdx) {
|
||||||
VkPhysicalDeviceProperties device_properties;
|
|
||||||
VkPhysicalDeviceFeatures device_features;
|
|
||||||
vkGetPhysicalDeviceProperties(physical_devices[physicalDeviceIdx], &device_properties);
|
vkGetPhysicalDeviceProperties(physical_devices[physicalDeviceIdx], &device_properties);
|
||||||
vkGetPhysicalDeviceFeatures(physical_devices[physicalDeviceIdx], &device_features);
|
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 */
|
VkDeviceQueueCreateInfo device_queue_createinfos[2] = {}; /* TODO: Change when we want more queues */
|
||||||
float* graphics_familiy_queue_priorities = NULL;
|
float* graphics_familiy_queue_priorities = NULL;
|
||||||
float* presentation_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 */
|
/* Get information about supported queue families */
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(g_vulkan_state.physical_device, &queue_families_property_count, NULL);
|
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_queue_createinfos[1].pQueuePriorities = presentation_familiy_queue_priorities;
|
||||||
|
|
||||||
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
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.flags = 0U;
|
||||||
device_create_info.queueCreateInfoCount = device_queues_count;
|
device_create_info.queueCreateInfoCount = device_queues_count;
|
||||||
device_create_info.pQueueCreateInfos = device_queue_createinfos;
|
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.ppEnabledExtensionNames = g_enabled_device_extensions_names;
|
||||||
device_create_info.pEnabledFeatures = NULL; /* TODO: Enable features, when needed */
|
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)) {
|
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]);
|
LOGF(vulkan_error_messages[VULKAN_FAILED_TO_CREATE_DEVICE]);
|
||||||
return VULKAN_ERROR_DEVICE_CREATION_FAILED;
|
return VULKAN_ERROR_DEVICE_CREATION_FAILED;
|
||||||
|
|||||||
@@ -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)
|
uint8_t record_command_buffer(uint32_t image_index)
|
||||||
{
|
{
|
||||||
VkCommandBuffer command_buffer = g_vulkan_state.command_buffers[g_vulkan_state.current_frame];
|
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 = {};
|
VkCommandBufferBeginInfo begin_info = {};
|
||||||
VkRenderPassBeginInfo render_pass_info = {};
|
VkRenderPassBeginInfo render_pass_info = {};
|
||||||
VkViewport viewport = {};
|
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);
|
vkCmdBindVertexBuffers(command_buffer, 0, 1, &g_vertex_buffer.buffer, offsets);
|
||||||
vkCmdBindIndexBuffer(command_buffer, g_index_buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
|
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,
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_vulkan_state.pipeline_layout, 0, 2,
|
||||||
&g_vulkan_state.descriptor_sets[g_vulkan_state.current_frame], 0, NULL);
|
descriptor_sets, 0, NULL);
|
||||||
|
|
||||||
for (i = 0; i < 2; ++i) {
|
for (i = 0; i < 2; ++i) {
|
||||||
VkBuffer instance_buffer = {g_instance_buffers[i].buffer};
|
VkBuffer instance_buffer = {g_instance_buffers[i].buffer};
|
||||||
|
|||||||
@@ -64,10 +64,12 @@ struct rse_vulkan_state_t
|
|||||||
struct rse_vulkan_buffer_t uniform_buffers[SWAP_BUFFER_COUNT];
|
struct rse_vulkan_buffer_t uniform_buffers[SWAP_BUFFER_COUNT];
|
||||||
VkCommandBuffer command_buffers[SWAP_BUFFER_COUNT];
|
VkCommandBuffer command_buffers[SWAP_BUFFER_COUNT];
|
||||||
VkDescriptorSet descriptor_sets[SWAP_BUFFER_COUNT];
|
VkDescriptorSet descriptor_sets[SWAP_BUFFER_COUNT];
|
||||||
|
VkDescriptorSet descriptor_sets_bindless;
|
||||||
VkImageView* swapchain_image_views;
|
VkImageView* swapchain_image_views;
|
||||||
VkExtent2D swapchain_extent;
|
VkExtent2D swapchain_extent;
|
||||||
VkRenderPass render_pass;
|
VkRenderPass render_pass;
|
||||||
VkDescriptorSetLayout descriptor_set_layout;
|
VkDescriptorSetLayout descriptor_set_layout;
|
||||||
|
VkDescriptorSetLayout descriptor_set_layout_bindless;
|
||||||
VkFramebuffer* swapchain_framebuffers;
|
VkFramebuffer* swapchain_framebuffers;
|
||||||
VkPipeline graphics_pipeline;
|
VkPipeline graphics_pipeline;
|
||||||
VkPipelineLayout pipeline_layout;
|
VkPipelineLayout pipeline_layout;
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
|
|
||||||
VkDescriptorPool gDescriptorPool;
|
VkDescriptorPool gDescriptorPool;
|
||||||
|
VkDescriptorPool gDescriptorPool_bindless;
|
||||||
|
|
||||||
static uint8_t create_descriptor_pool();
|
static uint8_t create_descriptor_pool();
|
||||||
static uint8_t create_descriptor_sets();
|
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].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
pool_sizes[0].descriptorCount = (uint32_t)(SWAP_BUFFER_COUNT);
|
pool_sizes[0].descriptorCount = (uint32_t)(SWAP_BUFFER_COUNT);
|
||||||
|
|
||||||
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
pool_sizes[1].descriptorCount = (uint32_t)(SWAP_BUFFER_COUNT*get_textures_count());
|
pool_sizes[1].descriptorCount = MAX_BINDLESS_RESOURCES;
|
||||||
|
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
pool_info.poolSizeCount = 2;
|
pool_info.poolSizeCount = 1;
|
||||||
pool_info.pPoolSizes = pool_sizes;
|
pool_info.pPoolSizes = &pool_sizes[0];
|
||||||
|
|
||||||
pool_info.maxSets = (uint32_t)(SWAP_BUFFER_COUNT);
|
pool_info.maxSets = (uint32_t)(SWAP_BUFFER_COUNT);
|
||||||
if (vkCreateDescriptorPool(g_vulkan_state.device, &pool_info, NULL, &gDescriptorPool) != VK_SUCCESS) {
|
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;
|
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;
|
return VULKAN_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,22 +61,44 @@ uint8_t create_descriptor_pool()
|
|||||||
* VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED */
|
* VULKAN_ERROR_DESCRIPTOR_SETS_ALLOCATION_FAILED */
|
||||||
uint8_t create_descriptor_sets()
|
uint8_t create_descriptor_sets()
|
||||||
{
|
{
|
||||||
|
uint32_t max_binding = MAX_BINDLESS_RESOURCES - 1;
|
||||||
VkDescriptorSetLayout layouts[SWAP_BUFFER_COUNT] = {
|
VkDescriptorSetLayout layouts[SWAP_BUFFER_COUNT] = {
|
||||||
g_vulkan_state.descriptor_set_layout,
|
g_vulkan_state.descriptor_set_layout,
|
||||||
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 = {};
|
||||||
|
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.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
allocInfo.descriptorPool = gDescriptorPool;
|
allocInfo.descriptorPool = gDescriptorPool;
|
||||||
allocInfo.descriptorSetCount = (uint32_t)(SWAP_BUFFER_COUNT);
|
allocInfo.descriptorSetCount = (uint32_t)(SWAP_BUFFER_COUNT);
|
||||||
allocInfo.pSetLayouts = layouts;
|
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) {
|
if (vkAllocateDescriptorSets(g_vulkan_state.device, &allocInfo, g_vulkan_state.descriptor_sets) != VK_SUCCESS) {
|
||||||
LOGF(vulkan_error_messages[VULKAN_DESCRIPTOR_SETS_ALLOCATION_FAILED]);
|
LOGF(vulkan_error_messages[VULKAN_DESCRIPTOR_SETS_ALLOCATION_FAILED]);
|
||||||
return VULKAN_ERROR_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++) {
|
for (size_t i = 0; i < SWAP_BUFFER_COUNT; i++) {
|
||||||
VkDescriptorBufferInfo buffer_info = {};
|
VkDescriptorBufferInfo buffer_info = {};
|
||||||
VkWriteDescriptorSet descriptor_writes[2] = {};
|
VkWriteDescriptorSet descriptor_writes[2] = {};
|
||||||
@@ -95,7 +128,7 @@ uint8_t create_descriptor_sets()
|
|||||||
descriptor_writes[0].pBufferInfo = &buffer_info;
|
descriptor_writes[0].pBufferInfo = &buffer_info;
|
||||||
|
|
||||||
descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
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].dstBinding = 1;
|
||||||
descriptor_writes[1].dstArrayElement = 0;
|
descriptor_writes[1].dstArrayElement = 0;
|
||||||
descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
@@ -121,5 +154,7 @@ uint8_t create_descriptors()
|
|||||||
void destroy_descriptors()
|
void destroy_descriptors()
|
||||||
{
|
{
|
||||||
vkDestroyDescriptorPool(g_vulkan_state.device, gDescriptorPool, NULL);
|
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, NULL);
|
||||||
|
vkDestroyDescriptorSetLayout(g_vulkan_state.device, g_vulkan_state.descriptor_set_layout_bindless, NULL);
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
#define RSE_VULKAN_DESCRIPTORS_H
|
#define RSE_VULKAN_DESCRIPTORS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX_BINDLESS_RESOURCES 16536
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create descriptors
|
* @brief Create descriptors
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "vulkan_errors.h"
|
#include "vulkan_errors.h"
|
||||||
#include "mesh_controller.h"
|
#include "mesh_controller.h"
|
||||||
#include "rse_vulkan_image.h"
|
#include "rse_vulkan_image.h"
|
||||||
|
#include "vulkan_descriptors.h"
|
||||||
|
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
@@ -294,10 +295,18 @@ uint8_t create_render_pass()
|
|||||||
uint8_t create_descriptor_set_layout()
|
uint8_t create_descriptor_set_layout()
|
||||||
{
|
{
|
||||||
VkDescriptorSetLayoutCreateInfo layout_info = {};
|
VkDescriptorSetLayoutCreateInfo layout_info = {};
|
||||||
|
VkDescriptorSetLayoutCreateInfo layout_info_bindless = {};
|
||||||
VkDescriptorSetLayoutBinding bindings[2];
|
VkDescriptorSetLayoutBinding bindings[2];
|
||||||
VkDescriptorSetLayoutBinding ubo_layout_binding = {};
|
VkDescriptorSetLayoutBinding ubo_layout_binding = {};
|
||||||
VkDescriptorSetLayoutBinding sampler_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.binding = 0;
|
||||||
ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
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.binding = 1;
|
||||||
sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
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.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
sampler_layout_binding.pImmutableSamplers = NULL;
|
sampler_layout_binding.pImmutableSamplers = NULL;
|
||||||
|
|
||||||
@@ -315,16 +324,24 @@ uint8_t create_descriptor_set_layout()
|
|||||||
bindings[1] = sampler_layout_binding;
|
bindings[1] = sampler_layout_binding;
|
||||||
|
|
||||||
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
layout_info.pNext = NULL;
|
layout_info.bindingCount = 1U;
|
||||||
layout_info.flags = 0U;
|
layout_info.pBindings = &bindings[0];
|
||||||
layout_info.bindingCount = 2U;
|
|
||||||
layout_info.pBindings = bindings;
|
|
||||||
|
|
||||||
if (vkCreateDescriptorSetLayout(g_vulkan_state.device, &layout_info, NULL, &g_vulkan_state.descriptor_set_layout) != VK_SUCCESS) {
|
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]);
|
LOGF(vulkan_error_messages[VULKAN_DESCRIPTORSETLAYOUT_CREATION_FAILED]);
|
||||||
return VULKAN_ERROR_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;
|
return VULKAN_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -335,12 +352,13 @@ uint8_t create_descriptor_set_layout()
|
|||||||
*/
|
*/
|
||||||
uint8_t create_pipeline_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 = {};
|
VkPipelineLayoutCreateInfo create_info = {};
|
||||||
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 = 1U;
|
create_info.setLayoutCount = 2U;
|
||||||
create_info.pSetLayouts = &g_vulkan_state.descriptor_set_layout;
|
create_info.pSetLayouts = set_layouts;
|
||||||
create_info.pushConstantRangeCount = 0U;
|
create_info.pushConstantRangeCount = 0U;
|
||||||
create_info.pPushConstantRanges = NULL;
|
create_info.pPushConstantRanges = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ int main(int argc, char** argv)
|
|||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
rse_graphics_init();
|
rse_graphics_init();
|
||||||
|
rse_graphics_test_function();
|
||||||
rse_create_task(&graphics_task, (thread_worker_t)rse_graphics_run, NULL);
|
rse_create_task(&graphics_task, (thread_worker_t)rse_graphics_run, NULL);
|
||||||
|
|
||||||
rse_task_join(&graphics_task);
|
rse_task_join(&graphics_task);
|
||||||
|
|||||||
Reference in new issue
Block a user