diff options
Diffstat (limited to 'src/vk-bindless.cpp')
| -rw-r--r-- | src/vk-bindless.cpp | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/src/vk-bindless.cpp b/src/vk-bindless.cpp new file mode 100644 index 0000000..9e517df --- /dev/null +++ b/src/vk-bindless.cpp @@ -0,0 +1,238 @@ +#include "vk-bindless.hpp" + +#include "vk-device.hpp" +#include "vk-utils.hpp" + +device_buffer& bindless_model::get_uniform_buffer(enum UniformTypes type) const { + return vkdevice::get().get_buffer(uniform_buffers[type]); +} + +void bindless_model::init() { + vkdevice& render_device = vkdevice::get(); + VkDevice device = render_device.get_device(); + + // ------------------------- + // create immutable samplers + // ------------------------- + { + VkSamplerCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = VK_NULL_HANDLE, + .flags = 0, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, + .mipLodBias = 0.f, + .anisotropyEnable = VK_FALSE, + .compareEnable = VK_FALSE, + .compareOp = VK_COMPARE_OP_NEVER, + .minLod = 0.f, + .maxLod = 0.f, + .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + .unnormalizedCoordinates = VK_FALSE, + }; + + // Nearest sampler + { + VkFilter filter = VK_FILTER_NEAREST; + VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_REPEAT; + + create_info.magFilter = filter, + create_info.minFilter = filter, + create_info.addressModeU = address_mode, + create_info.addressModeV = address_mode, + create_info.addressModeW = address_mode, + + VKCHECK(vkCreateSampler(device, &create_info, VK_NULL_HANDLE, &samplers[SamplerType::NEAREST])); + } + + // Linear sampler + { + VkFilter filter = VK_FILTER_LINEAR; + VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_REPEAT; + + create_info.magFilter = filter, + create_info.minFilter = filter, + create_info.addressModeU = address_mode, + create_info.addressModeV = address_mode, + create_info.addressModeW = address_mode, + + VKCHECK(vkCreateSampler(device, &create_info, VK_NULL_HANDLE, &samplers[SamplerType::LINEAR])); + } + } + + // Set 0 global resources + // Binding 0 Storage images + // Binding 1 Sampled images + // Binding 2 Samplers + { + VkDescriptorSetLayoutBinding set_layout_bindings[]{ + { + .binding = 0U, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = SamplerType::MAX_SAMPLER, + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = samplers, + }, + { + .binding = 1U, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = set_descriptors_count, + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = nullptr, + }, + { + .binding = 2U, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .descriptorCount = set_descriptors_count, + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = nullptr, + }, + }; + + VkDescriptorBindingFlags flags[]{ + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, + }; + + VkDescriptorSetLayoutBindingFlagsCreateInfo layout_binding_flags{ + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .pNext = VK_NULL_HANDLE, + .bindingCount = sizeof(flags) / sizeof(VkDescriptorBindingFlags), + .pBindingFlags = flags, + }; + + VkDescriptorSetLayoutCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = &layout_binding_flags, + .flags = 0U, + .bindingCount = sizeof(set_layout_bindings) / sizeof(VkDescriptorSetLayoutBinding), + .pBindings = set_layout_bindings, + }; + + VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &global_set_layout)); + } + + // ---------------------- + // create layout + // ---------------------- + { + VkPushConstantRange push_constant { + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT, + .offset = 0U, + .size = push_constant_slot_size * push_constant_slots, + }; + + VkPipelineLayoutCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0U, + .setLayoutCount = 1U, + .pSetLayouts = &global_set_layout, + .pushConstantRangeCount = 1U, + .pPushConstantRanges = &push_constant, + }; + + VKCHECK(vkCreatePipelineLayout(device, &create_info, nullptr, &global_layout)); + } + + // ---------------------- + // create descriptor pool + // ---------------------- + { + VkDescriptorPoolSize pool_sizes[]{ + { + .type = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = set_descriptors_count, + }, + { + .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = set_descriptors_count, + }, + { + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .descriptorCount = set_descriptors_count, + }, + }; + + VkDescriptorPoolCreateInfo descriptor_pool_create_info{ + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = 0U, + .maxSets = descriptor_pool_allocable_sets_count, + .poolSizeCount = sizeof(pool_sizes) / sizeof(VkDescriptorPoolSize), + .pPoolSizes = pool_sizes, + }; + VKCHECK(vkCreateDescriptorPool(device, &descriptor_pool_create_info, nullptr, &descriptor_pool)); + } + + // ----------------------- + // create descriptors sets + // ----------------------- + { + VkDescriptorSetAllocateInfo allocate_info{ + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorPool = descriptor_pool, + .descriptorSetCount = 1U, + .pSetLayouts = &global_set_layout, + }; + VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &global_set)); + } + + // --------------------- + // global uniform buffer + // --------------------- + { + uniform_buffers[UniformTypes::GLOBAL] = render_device.create_buffer({ + .size = globals_uniform_buffer_size, + .usages = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, + .name = "global uniform buffer", + }); + } + + // --------------------- + // passes uniform buffer + // --------------------- + { + uniform_buffers[UniformTypes::PASS] = render_device.create_buffer({ + .size = passes_uniform_buffer_size, + .usages = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, + .name = "passes uniform buffer" + }); + } + + // -------------------- + // draws uniform buffer + // -------------------- + { + uniform_buffers[UniformTypes::DRAW] = render_device.create_buffer({ + .size = draws_uniform_buffer_size, + .usages = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU, + .name = "draws uniform buffer", + }); + } +} + +void bindless_model::deinit() { + vkdevice& render_device = vkdevice::get(); + VkDevice device = render_device.get_device(); + + vkDestroyDescriptorPool(device, descriptor_pool, nullptr); + + vkDestroyDescriptorSetLayout(device, global_set_layout, nullptr); + vkDestroyPipelineLayout(device, global_layout, nullptr); + + render_device.destroy_buffer(uniform_buffers[UniformTypes::GLOBAL]); + render_device.destroy_buffer(uniform_buffers[UniformTypes::PASS]); + render_device.destroy_buffer(uniform_buffers[UniformTypes::DRAW]); + + for (VkSampler sampler : samplers) { + vkDestroySampler(device, sampler, nullptr); + } +} |
