aboutsummaryrefslogtreecommitdiffstats
path: root/src/vk-bindless.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vk-bindless.cpp')
-rw-r--r--src/vk-bindless.cpp238
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);
+ }
+}