diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2021-08-09 22:41:03 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2021-08-09 22:41:03 +0200 |
| commit | 8c1e26e552556e36a5c1fecd9558d9ab9dd3d454 (patch) | |
| tree | 554af62f3bd3fb237c07de55dfad1da7dac30592 /src | |
| parent | 03fdcb0341d35bb99fccb2e155ee967f932c9961 (diff) | |
Bindless graphics pipeline
Diffstat (limited to 'src')
| -rw-r--r-- | src/vk-api.cpp | 226 | ||||
| -rw-r--r-- | src/vk-renderer.cpp | 103 |
2 files changed, 149 insertions, 180 deletions
diff --git a/src/vk-api.cpp b/src/vk-api.cpp index 33b32ee..795fa42 100644 --- a/src/vk-api.cpp +++ b/src/vk-api.cpp @@ -24,15 +24,15 @@ vkapi::vkapi() { .descriptorCount = (uint32_t)1024, }, { - .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = (uint32_t)1024, }, { - .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .descriptorCount = (uint32_t)1024, }, { - .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = (uint32_t)1024, } }; @@ -51,18 +51,34 @@ vkapi::vkapi() { VkDescriptorSetLayoutBinding bindless_layout_bindings[] = { { .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = 1024, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = 1024, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 2, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 1024, .stageFlags = VK_SHADER_STAGE_ALL, }, }; - VkDescriptorBindingFlags flag = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT; + 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 descriptor_set_layout_binding_flags = {}; descriptor_set_layout_binding_flags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO; descriptor_set_layout_binding_flags.pNext = VK_NULL_HANDLE; - descriptor_set_layout_binding_flags.bindingCount = 1; - descriptor_set_layout_binding_flags.pBindingFlags = &flag; + descriptor_set_layout_binding_flags.bindingCount = sizeof(flags) / sizeof(VkDescriptorBindingFlags); + descriptor_set_layout_binding_flags.pBindingFlags = flags; VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info = {}; descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; @@ -74,10 +90,23 @@ vkapi::vkapi() { VKRESULT(vkCreateDescriptorSetLayout(context.device, &descriptor_set_layout_create_info, nullptr, &bindless_descriptor.set_layout)) - VkPushConstantRange push_constant = {}; - push_constant.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; - push_constant.offset = 0; - push_constant.size = 64; + VkPushConstantRange push_constants[] = { + { + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, + .offset = 0, + .size = 32, + }, + { + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .offset = 32, + .size = 24, + }, + { + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .offset = 56, + .size = 8, + }, + }; VkPipelineLayoutCreateInfo layout_create_info = {}; layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; @@ -85,8 +114,8 @@ vkapi::vkapi() { layout_create_info.flags = 0; layout_create_info.setLayoutCount = 1; layout_create_info.pSetLayouts = &bindless_descriptor.set_layout; - layout_create_info.pushConstantRangeCount = 1; - layout_create_info.pPushConstantRanges = &push_constant; + layout_create_info.pushConstantRangeCount = sizeof(push_constants) / sizeof(VkPushConstantRange); + layout_create_info.pPushConstantRanges = push_constants; VKRESULT(vkCreatePipelineLayout(context.device, &layout_create_info, nullptr, &bindless_descriptor.pipeline_layout)) @@ -147,7 +176,7 @@ void vkapi::copy_buffer(VkCommandBuffer cmd_buf, Buffer src, Buffer dst, size_t vkCmdCopyBuffer(cmd_buf, src.handle, dst.handle, 1, &buffer_copy); } -void vkapi::copy_buffer(VkCommandBuffer cmd_buf, Buffer src, Image dst) { +void vkapi::copy_buffer(VkCommandBuffer cmd_buf, Buffer src, image dst) { VkImageSubresourceLayers image_subresource_layers = {}; image_subresource_layers.aspectMask = dst.subresource_range.aspectMask; image_subresource_layers.mipLevel = 0; @@ -170,8 +199,8 @@ void vkapi::destroy_buffer(Buffer& buffer) { } -Image vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages) { - Image image; +image vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages) { + image image; image.size = size; @@ -220,20 +249,21 @@ Image vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags us VKRESULT(vkCreateImageView(context.device, &image_view_create_info, VK_NULL_HANDLE, &image.view)) - image.bindless_index = bindless_descriptor.indices.back(); - bindless_descriptor.indices.pop_back(); + image.bindless_storage_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + image.bindless_sampled_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); return std::move(image); } -void vkapi::destroy_image(Image &image) { - bindless_descriptor.indices.push_back(image.bindless_index); +void vkapi::destroy_image(image &image) { + bindless_descriptor.free(image.bindless_storage_index, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + bindless_descriptor.free(image.bindless_sampled_index, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); vmaDestroyImage(context.allocator, image.handle, image.alloc); vkDestroyImageView(context.device, image.view, nullptr); } -std::vector<Image> vkapi::create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count) { - std::vector<Image> images { image_count }; +std::vector<image> vkapi::create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count) { + std::vector<image> images { image_count }; for (size_t image_index = 0; image_index < image_count; image_index++) { images[image_index] = create_image(size, format, usages); @@ -242,7 +272,7 @@ std::vector<Image> vkapi::create_images(VkExtent3D size, VkFormat format, VkImag return std::move(images); } -void vkapi::destroy_images(std::vector<Image> &images) { +void vkapi::destroy_images(std::vector<image> &images) { for (auto &image: images) { destroy_image(image); } @@ -315,7 +345,7 @@ void vkapi::destroy_semaphores(std::vector<VkSemaphore> &semaphores) { } -VkSampler vkapi::create_sampler(VkFilter filter, VkSamplerAddressMode address_mode) { +sampler vkapi::create_sampler(VkFilter filter, VkSamplerAddressMode address_mode) { VkSamplerCreateInfo sampler_create_info = {}; sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler_create_info.pNext = VK_NULL_HANDLE; @@ -335,14 +365,18 @@ VkSampler vkapi::create_sampler(VkFilter filter, VkSamplerAddressMode address_mo sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; sampler_create_info.unnormalizedCoordinates = VK_FALSE; - VkSampler sampler; - VKRESULT(vkCreateSampler(context.device, &sampler_create_info, VK_NULL_HANDLE, &sampler)) + sampler sampler; + VKRESULT(vkCreateSampler(context.device, &sampler_create_info, VK_NULL_HANDLE, &sampler.handle)) + + sampler.bindless_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLER); - return sampler; + return std::move(sampler); } -void vkapi::destroy_sampler(VkSampler sampler) { - vkDestroySampler(context.device, sampler, VK_NULL_HANDLE); +void vkapi::destroy_sampler(sampler sampler) { + bindless_descriptor.free(sampler.bindless_index, VK_DESCRIPTOR_TYPE_SAMPLER); + + vkDestroySampler(context.device, sampler.handle, VK_NULL_HANDLE); } @@ -422,7 +456,7 @@ void vkapi::destroy_render_pass(VkRenderPass render_pass) { } -VkFramebuffer vkapi::create_framebuffer(VkRenderPass render_pass, std::vector<Image>& images, VkExtent2D size) { +VkFramebuffer vkapi::create_framebuffer(VkRenderPass render_pass, std::vector<image>& images, VkExtent2D size) { VkFramebuffer framebuffer; std::vector<VkImageView> attachements; for (auto& image: images) { @@ -445,7 +479,7 @@ VkFramebuffer vkapi::create_framebuffer(VkRenderPass render_pass, std::vector<Im return framebuffer; } -std::vector<VkFramebuffer> vkapi::create_framebuffers(VkRenderPass render_pass, std::vector<Image>& images, VkExtent2D size, uint32_t framebuffer_count) { +std::vector<VkFramebuffer> vkapi::create_framebuffers(VkRenderPass render_pass, std::vector<image>& images, VkExtent2D size, uint32_t framebuffer_count) { std::vector<VkFramebuffer> framebuffers { framebuffer_count }; for (auto& framebuffer: framebuffers) { @@ -518,7 +552,7 @@ Pipeline vkapi::create_compute_pipeline(const char* shader_name) { return std::move(pipeline); } -Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<VkDescriptorSetLayoutBinding>& bindings, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass, std::vector<VkDynamicState> dynamic_states) { +Pipeline vkapi::create_graphics_pipeline(const char* shader_name, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass, std::vector<VkDynamicState> dynamic_states) { Pipeline pipeline { .bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS }; @@ -561,28 +595,6 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk } - VkDescriptorSetLayoutCreateInfo descriptor_set_layout_create_info = {}; - descriptor_set_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptor_set_layout_create_info.pNext = nullptr; - descriptor_set_layout_create_info.flags = 0; - descriptor_set_layout_create_info.bindingCount = bindings.size(); - descriptor_set_layout_create_info.pBindings = bindings.data(); - - VKRESULT(vkCreateDescriptorSetLayout(context.device, &descriptor_set_layout_create_info, nullptr, &pipeline.descriptor_set_layout)) - - - VkPipelineLayoutCreateInfo layout_create_info = {}; - layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - layout_create_info.pNext = nullptr; - layout_create_info.flags = 0; - layout_create_info.setLayoutCount = 1; - layout_create_info.pSetLayouts = &pipeline.descriptor_set_layout; - layout_create_info.pushConstantRangeCount = 0; - layout_create_info.pPushConstantRanges = nullptr; - - VKRESULT(vkCreatePipelineLayout(context.device, &layout_create_info, nullptr, &pipeline.layout)) - - VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info = {}; vertex_input_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; @@ -659,7 +671,7 @@ Pipeline vkapi::create_graphics_pipeline(const char* shader_name, std::vector<Vk pipeline_create_info.pMultisampleState = &multisample_state_create_info; pipeline_create_info.pColorBlendState = &color_blend_state_create_info; pipeline_create_info.pDynamicState = &dynamic_state_create_info; - pipeline_create_info.layout = pipeline.layout; + pipeline_create_info.layout = bindless_descriptor.pipeline_layout; pipeline_create_info.renderPass = render_pass; pipeline_create_info.subpass = 0; @@ -673,8 +685,6 @@ void vkapi::destroy_pipeline(Pipeline &pipeline) { vkDestroyShaderModule(context.device, shader_module, nullptr); } - vkDestroyDescriptorSetLayout(context.device, pipeline.descriptor_set_layout, nullptr); - vkDestroyPipelineLayout(context.device, pipeline.layout, nullptr); vkDestroyPipeline(context.device, pipeline.handle, nullptr); } @@ -802,7 +812,7 @@ Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VKRESULT(vkGetSwapchainImagesKHR(context.device, swapchain.handle, &image_count, VK_NULL_HANDLE)) swapchain.image_count = image_count; - swapchain.images = std::vector<Image>{ swapchain.image_count }; + swapchain.images = std::vector<image>{ swapchain.image_count }; auto images = std::vector<VkImage>{ swapchain.image_count }; auto views = std::vector<VkImageView>{ swapchain.image_count }; @@ -822,8 +832,8 @@ Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, }; for (size_t image_index = 0; image_index < swapchain.image_count; image_index++) { - swapchain.images[image_index].bindless_index = bindless_descriptor.indices.back(); - bindless_descriptor.indices.pop_back(); + swapchain.images[image_index].bindless_storage_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + swapchain.images[image_index].bindless_sampled_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); swapchain.images[image_index].handle = images[image_index]; swapchain.images[image_index].size = image_size; @@ -852,7 +862,8 @@ Swapchain vkapi::create_swapchain(VkSurfaceKHR surface, size_t min_image_count, void vkapi::destroy_swapchain(Swapchain& swapchain) { for(auto &image: swapchain.images) { - bindless_descriptor.indices.push_back(image.bindless_index); + bindless_descriptor.free(image.bindless_storage_index, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + bindless_descriptor.free(image.bindless_sampled_index, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); vkDestroyImageView(context.device, image.view, nullptr); } @@ -860,68 +871,23 @@ void vkapi::destroy_swapchain(Swapchain& swapchain) { } -void vkapi::update_descriptor_set_buffer(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding, Buffer& buffer) { - update_descriptor_set_buffer(set, binding, buffer, 0, VK_WHOLE_SIZE); -} - -void vkapi::update_descriptor_set_buffer(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding, Buffer& buffer, VkDeviceSize offset, VkDeviceSize range) { - VkDescriptorBufferInfo descriptor_buffer_info = {}; - descriptor_buffer_info.buffer = buffer.handle; - descriptor_buffer_info.offset = 0; - descriptor_buffer_info.range = VK_WHOLE_SIZE; - - VkWriteDescriptorSet write_descriptor = {}; - write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor.pNext = nullptr; - write_descriptor.dstSet = set; - write_descriptor.dstBinding = binding.binding; - write_descriptor.dstArrayElement = 0; - write_descriptor.descriptorCount = binding.descriptorCount; - write_descriptor.descriptorType = binding.descriptorType; - write_descriptor.pImageInfo = VK_NULL_HANDLE; - write_descriptor.pBufferInfo = &descriptor_buffer_info; - write_descriptor.pTexelBufferView = VK_NULL_HANDLE; - - vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr); -} - -void vkapi::update_descriptor_set_image(VkDescriptorSet set, VkDescriptorSetLayoutBinding binding, VkImageView view, VkSampler sampler) { - VkDescriptorImageInfo descriptor_image_info = {}; - descriptor_image_info.sampler = sampler; - descriptor_image_info.imageView = view; - descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - - VkWriteDescriptorSet write_descriptor = {}; - write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor.pNext = nullptr; - write_descriptor.dstSet = set; - write_descriptor.dstBinding = binding.binding; - write_descriptor.dstArrayElement = 0; - write_descriptor.descriptorCount = binding.descriptorCount; - write_descriptor.descriptorType = binding.descriptorType; - write_descriptor.pImageInfo = &descriptor_image_info; - write_descriptor.pBufferInfo = VK_NULL_HANDLE; - write_descriptor.pTexelBufferView = VK_NULL_HANDLE; - - vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr); -} - -void vkapi::update_bindless_descriptor_set_images(std::vector<Image> &images, std::vector<VkSampler> &samplers) { +void vkapi::update_descriptor_images(std::vector<image> &images, VkDescriptorType type) { std::vector<VkDescriptorImageInfo> descriptor_images_info { images.size() }; std::vector<VkWriteDescriptorSet> writes_descriptor { images.size() }; for (size_t image_index = 0; image_index < images.size(); image_index++) { - descriptor_images_info[image_index].sampler = samplers[image_index]; - descriptor_images_info[image_index].imageView = images[image_index].view; + auto &image = images[image_index]; + descriptor_images_info[image_index].sampler = VK_NULL_HANDLE; + descriptor_images_info[image_index].imageView = image.view; descriptor_images_info[image_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL; writes_descriptor[image_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes_descriptor[image_index].pNext = nullptr; writes_descriptor[image_index].dstSet = bindless_descriptor.set; - writes_descriptor[image_index].dstBinding = 0; - writes_descriptor[image_index].dstArrayElement = images[image_index].bindless_index; + writes_descriptor[image_index].dstBinding = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2 : 1; + writes_descriptor[image_index].dstArrayElement = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? image.bindless_storage_index : image.bindless_sampled_index; writes_descriptor[image_index].descriptorCount = 1; - writes_descriptor[image_index].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + writes_descriptor[image_index].descriptorType = type; writes_descriptor[image_index].pImageInfo = &descriptor_images_info[image_index]; writes_descriptor[image_index].pBufferInfo = VK_NULL_HANDLE; writes_descriptor[image_index].pTexelBufferView = VK_NULL_HANDLE; @@ -930,6 +896,30 @@ void vkapi::update_bindless_descriptor_set_images(std::vector<Image> &images, st vkUpdateDescriptorSets(context.device, writes_descriptor.size(), writes_descriptor.data(), 0, nullptr); } +void vkapi::update_descriptor_samplers(std::vector<sampler> &samplers) { + std::vector<VkDescriptorImageInfo> descriptor_images_info { samplers.size() }; + std::vector<VkWriteDescriptorSet> writes_descriptor { samplers.size() }; + + for (size_t sampler_index = 0; sampler_index < samplers.size(); sampler_index++) { + descriptor_images_info[sampler_index].sampler = samplers[sampler_index].handle; + descriptor_images_info[sampler_index].imageView = VK_NULL_HANDLE; + descriptor_images_info[sampler_index].imageLayout = VK_IMAGE_LAYOUT_GENERAL; + + writes_descriptor[sampler_index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes_descriptor[sampler_index].pNext = nullptr; + writes_descriptor[sampler_index].dstSet = bindless_descriptor.set; + writes_descriptor[sampler_index].dstBinding = 0; + writes_descriptor[sampler_index].dstArrayElement = samplers[sampler_index].bindless_index; + writes_descriptor[sampler_index].descriptorCount = 1; + writes_descriptor[sampler_index].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + writes_descriptor[sampler_index].pImageInfo = &descriptor_images_info[sampler_index]; + writes_descriptor[sampler_index].pBufferInfo = VK_NULL_HANDLE; + writes_descriptor[sampler_index].pTexelBufferView = VK_NULL_HANDLE; + } + + vkUpdateDescriptorSets(context.device, writes_descriptor.size(), writes_descriptor.data(), 0, nullptr); +} + void vkapi::start_record(VkCommandBuffer command_buffer) { VkCommandBufferBeginInfo cmd_buf_begin_info = {}; @@ -941,7 +931,7 @@ void vkapi::start_record(VkCommandBuffer command_buffer) { vkBeginCommandBuffer(command_buffer, &cmd_buf_begin_info); } -void vkapi::image_barrier(VkCommandBuffer command_buffer, VkImageLayout src_layout, VkImageLayout dst_layout, VkPipelineStageFlagBits src_stage, VkPipelineStageFlagBits dst_stage, VkAccessFlags src_access, VkAccessFlags dst_access, Image image) { +void vkapi::image_barrier(VkCommandBuffer command_buffer, VkImageLayout src_layout, VkImageLayout dst_layout, VkPipelineStageFlagBits src_stage, VkPipelineStageFlagBits dst_stage, VkAccessFlags src_access, VkAccessFlags dst_access, image image) { VkImageMemoryBarrier undefined_to_general_barrier = {}; undefined_to_general_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; undefined_to_general_barrier.pNext = nullptr; @@ -1005,21 +995,21 @@ void vkapi::run_compute_pipeline(VkCommandBuffer command_buffer, Pipeline pipeli vkCmdDispatch(command_buffer, group_count_x, group_count_y, group_count_z); } -void vkapi::draw(VkCommandBuffer command_buffer, Pipeline pipeline, VkDescriptorSet set, uint32_t vertex_count, uint32_t vertex_offset) { - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &set, 0, nullptr); +void vkapi::draw(VkCommandBuffer command_buffer, Pipeline pipeline, uint32_t vertex_count, uint32_t vertex_offset) { + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless_descriptor.pipeline_layout, 0, 1, &bindless_descriptor.set, 0, nullptr); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.handle); vkCmdDraw(command_buffer, vertex_count, 1, vertex_offset, 0); } -void vkapi::draw(VkCommandBuffer command_buffer, Pipeline pipeline, VkDescriptorSet set, Buffer index_buffer, uint32_t index_count, uint32_t index_offset, uint32_t vertex_offset) { +void vkapi::draw(VkCommandBuffer command_buffer, Pipeline pipeline, Buffer index_buffer, uint32_t index_count, uint32_t index_offset, uint32_t vertex_offset) { vkCmdBindIndexBuffer(command_buffer, index_buffer.handle, 0, VK_INDEX_TYPE_UINT16); - vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.layout, 0, 1, &set, 0, nullptr); + vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bindless_descriptor.pipeline_layout, 0, 1, &bindless_descriptor.set, 0, nullptr); vkCmdDrawIndexed(command_buffer, index_count, 1, index_offset, vertex_offset, 0); } -void vkapi::blit_full(VkCommandBuffer command_buffer, Image src_image, Image dst_image) { +void vkapi::blit_full(VkCommandBuffer command_buffer, image src_image, image dst_image) { VkImageSubresourceLayers images_subres_layers { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .mipLevel = 0, diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp index 4d7646a..54a0008 100644 --- a/src/vk-renderer.cpp +++ b/src/vk-renderer.cpp @@ -55,44 +55,21 @@ vkrenderer::vkrenderer(window& wnd, size_t scene_buffer_size, size_t geometry_bu geometry_buffer = api.create_buffer(geometry_buffer_size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_ONLY); bvh_buffer = api.create_buffer(bvh_buffer_size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_GPU_ONLY); + std::vector<VkFormat> attachments_format { swapchain.surface_format.format }; render_pass = api.create_render_pass(attachments_format, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); - for (auto& image : swapchain.images) { - std::vector<Image> attachments { image }; + for (auto& current_image : swapchain.images) { + std::vector<image> attachments { current_image }; framebuffers.push_back(api.create_framebuffer(render_pass, attachments, swapchain.extent)); } - ui_sets_bindings = { - { - .binding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - .pImmutableSamplers = VK_NULL_HANDLE, - }, - { - .binding = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - .pImmutableSamplers = VK_NULL_HANDLE, - }, - { - .binding = 2, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = VK_NULL_HANDLE, - }, - }; std::vector<VkDynamicState> dynamic_states { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; - ui_pipeline = api.create_graphics_pipeline("ui", ui_sets_bindings, (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass, dynamic_states); - ui_sets = api.create_descriptor_sets(ui_pipeline.descriptor_set_layout, virtual_frames_count); + ui_pipeline = api.create_graphics_pipeline("ui", (VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), render_pass, dynamic_states); ImGui::CreateContext(); auto io = ImGui::GetIO(); @@ -136,7 +113,7 @@ vkrenderer::vkrenderer(window& wnd, size_t scene_buffer_size, size_t geometry_bu api.destroy_buffer(staging_buffer); - std::vector<Image> images = { + std::vector<image> images = { accumulation_images[0], accumulation_images[1], @@ -144,25 +121,25 @@ vkrenderer::vkrenderer(window& wnd, size_t scene_buffer_size, size_t geometry_bu swapchain.images[1], swapchain.images[2] }; - std::vector<VkSampler> samplers { images.size(), VK_NULL_HANDLE }; - api.update_bindless_descriptor_set_images(images, samplers); + api.update_descriptor_images(images, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); - virtual_frame_index++; + std::vector<image> sampled_images = { + ui_texture + }; + api.update_descriptor_images(sampled_images, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); ui_texture_sampler = api.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); - for (size_t index = 0; index < virtual_frames_count; index++) { - api.update_descriptor_set_image(ui_sets[index], ui_sets_bindings[2], ui_texture.view, ui_texture_sampler); - } + std::vector<sampler> samplers = { + ui_texture_sampler, + }; + api.update_descriptor_samplers(samplers); + + virtual_frame_index++; ui_vertex_buffers.resize(virtual_frames_count); ui_index_buffers.resize(virtual_frames_count); - - for (size_t index = 0; index < virtual_frames_count; index++) { - ui_transforms_buffers.push_back(api.create_buffer(sizeof(UiTransforms), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU)); - api.update_descriptor_set_buffer(ui_sets[index], ui_sets_bindings[1], ui_transforms_buffers[index]); - } } vkrenderer::~vkrenderer() { @@ -187,10 +164,6 @@ vkrenderer::~vkrenderer() { api.destroy_framebuffer(framebuffer); } - for (auto& transforms_buffer: ui_transforms_buffers) { - api.destroy_buffer(transforms_buffer); - } - for (auto& vertex_buffer: ui_vertex_buffers) { api.destroy_buffer(vertex_buffer); } @@ -205,8 +178,6 @@ vkrenderer::~vkrenderer() { api.destroy_pipeline(tonemapping_pipeline); api.destroy_pipeline(ui_pipeline); - api.destroy_descriptor_sets(ui_sets); - api.destroy_swapchain(swapchain); api.destroy_surface(platform_surface); } @@ -215,19 +186,13 @@ void vkrenderer::begin_frame() { ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); - ((UiTransforms*)ui_transforms_buffers[virtual_frame_index].alloc_info.pMappedData)->scale_x = 2.f / draw_data->DisplaySize.x; - ((UiTransforms*)ui_transforms_buffers[virtual_frame_index].alloc_info.pMappedData)->scale_y = 2.f / draw_data->DisplaySize.y; - ((UiTransforms*)ui_transforms_buffers[virtual_frame_index].alloc_info.pMappedData)->translate_x = -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x); - ((UiTransforms*)ui_transforms_buffers[virtual_frame_index].alloc_info.pMappedData)->translate_y = -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y); - VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[virtual_frame_index], VK_TRUE, UINT64_MAX)) VKRESULT(vkResetFences(api.context.device, 1, &submission_fences[virtual_frame_index])) if (ui_vertex_buffers[virtual_frame_index].size < draw_data->TotalVtxCount * sizeof(VkVertex)) { api.destroy_buffer(ui_vertex_buffers[virtual_frame_index]); - ui_vertex_buffers[virtual_frame_index] = api.create_buffer(draw_data->TotalVtxCount * sizeof(VkVertex), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); - api.update_descriptor_set_buffer(ui_sets[virtual_frame_index], ui_sets_bindings[0], ui_vertex_buffers[virtual_frame_index]); + ui_vertex_buffers[virtual_frame_index] = api.create_buffer(draw_data->TotalVtxCount * sizeof(VkVertex), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); } if (ui_index_buffers[virtual_frame_index].size < draw_data->TotalIdxCount * sizeof(ImDrawIdx)) { api.destroy_buffer(ui_index_buffers[virtual_frame_index]); @@ -295,6 +260,21 @@ void vkrenderer::ui() { vkCmdSetViewport(cmd_buf, 0, 1, &viewport); + float scale[] { + 2.f / draw_data->DisplaySize.x, + 2.f / draw_data->DisplaySize.y, + }; + float translate[] { + -1.f - draw_data->DisplayPos.x * (2.f / draw_data->DisplaySize.x), + -1.f - draw_data->DisplayPos.y * (2.f / draw_data->DisplaySize.y), + }; + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 32, 8, (void*)&ui_vertex_buffers[virtual_frame_index].device_address); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 40, 8, (void*)&scale); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 48, 8, (void*)&translate); + + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 56, 4, (void*)&ui_texture.bindless_sampled_index); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 60, 4, (void*)&ui_texture_sampler.bindless_index); + off_t vertex_buffer_offset = 0; off_t index_buffer_offset = 0; for (size_t cmd_index = 0; cmd_index < draw_data->CmdListsCount; cmd_index++) { @@ -312,7 +292,7 @@ void vkrenderer::ui() { }; vkCmdSetScissor(cmd_buf, 0, 1, &rect); - api.draw(cmd_buf, ui_pipeline, ui_sets[virtual_frame_index], ui_index_buffers[virtual_frame_index], draw_cmd.ElemCount, index_buffer_offset + draw_cmd.IdxOffset, vertex_buffer_offset + draw_cmd.VtxOffset); + api.draw(cmd_buf, ui_pipeline, ui_index_buffers[virtual_frame_index], draw_cmd.ElemCount, index_buffer_offset + draw_cmd.IdxOffset, vertex_buffer_offset + draw_cmd.VtxOffset); } vertex_buffer_offset += draw_list->VtxBuffer.Size; @@ -328,16 +308,16 @@ void vkrenderer::compute(uint32_t width, uint32_t height) { vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, (void*)&scene_buffer.device_address); vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 8, 8, (void*)&geometry_buffer.device_address); vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 16, 8, (void*)&bvh_buffer.device_address); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 24, 4, (void*)&accumulation_images[0].bindless_index); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 28, 4, (void*)&accumulation_images[1].bindless_index); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 24, 4, (void*)&accumulation_images[0].bindless_storage_index); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 28, 4, (void*)&accumulation_images[1].bindless_storage_index); api.run_compute_pipeline(cmd_buf, compute_pipeline, (width / 8) + 1, (height / 8) + 1, 1); api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, swapchain.images[swapchain_image_index]); vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, (void*)&scene_buffer.device_address); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 8, 4, (void*)&swapchain.images[swapchain_image_index].bindless_index); - vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 12, 4, (void*)&accumulation_images[0].bindless_index); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 8, 4, (void*)&swapchain.images[swapchain_image_index].bindless_storage_index); + vkCmdPushConstants(cmd_buf, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 12, 4, (void*)&accumulation_images[0].bindless_storage_index); api.run_compute_pipeline(cmd_buf, tonemapping_pipeline, (width / 8) + 1, (height / 8) + 1, 1); } @@ -393,7 +373,7 @@ void vkrenderer::recreate_swapchain() { VKRESULT(vkWaitForFences(api.context.device, 1, &submission_fences[0], VK_TRUE, UINT64_MAX)) - std::vector<Image> images = { + std::vector<image> images = { accumulation_images[0], accumulation_images[1], @@ -401,17 +381,16 @@ void vkrenderer::recreate_swapchain() { swapchain.images[1], swapchain.images[2] }; - std::vector<VkSampler> samplers { images.size(), VK_NULL_HANDLE }; - api.update_bindless_descriptor_set_images(images, samplers); + api.update_descriptor_images(images, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); for (auto& framebuffer: framebuffers) { api.destroy_framebuffer(framebuffer); } framebuffers.clear(); - for (auto& image : swapchain.images) { - std::vector<Image> attachments { image }; + for (auto& current_image : swapchain.images) { + std::vector<image> attachments { current_image }; framebuffers.push_back(api.create_framebuffer(render_pass, attachments, swapchain.extent)); } } |
