From 430dc1f7db6bc82311a024c5d4a117f3d5099264 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 5 Dec 2024 00:01:17 -0800 Subject: [PATCH] vk: support unused bind groups --- blade-graphics/src/vulkan/command.rs | 26 ++++++++++++++---------- blade-graphics/src/vulkan/mod.rs | 10 +++++++-- blade-graphics/src/vulkan/pipeline.rs | 29 +++++++++++++++++++++------ docs/CHANGELOG.md | 2 ++ 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/blade-graphics/src/vulkan/command.rs b/blade-graphics/src/vulkan/command.rs index c8d4425..b778686 100644 --- a/blade-graphics/src/vulkan/command.rs +++ b/blade-graphics/src/vulkan/command.rs @@ -833,22 +833,26 @@ impl super::PipelineEncoder<'_, '_> { impl crate::traits::PipelineEncoder for super::PipelineEncoder<'_, '_> { fn bind(&mut self, group: u32, data: &D) { let dsl = &self.layout.descriptor_set_layouts[group as usize]; - self.update_data.clear(); - self.update_data.resize(dsl.template_size as usize, 0); - data.fill(super::PipelineContext { - update_data: self.update_data.as_mut_slice(), - template_offsets: &dsl.template_offsets, - }); + if !dsl.is_empty() { + self.update_data.clear(); + self.update_data.resize(dsl.template_size as usize, 0); + data.fill(super::PipelineContext { + update_data: self.update_data.as_mut_slice(), + template_offsets: &dsl.template_offsets, + }); + } let vk_set = self .device .allocate_descriptor_set(&mut self.cmd_buf.descriptor_pool, dsl); unsafe { - self.device.core.update_descriptor_set_with_template( - vk_set, - dsl.update_template, - self.update_data.as_ptr() as *const _, - ); + if !dsl.is_empty() { + self.device.core.update_descriptor_set_with_template( + vk_set, + dsl.update_template, + self.update_data.as_ptr() as *const _, + ); + } self.device.core.cmd_bind_descriptor_sets( self.cmd_buf.raw, self.bind_point, diff --git a/blade-graphics/src/vulkan/mod.rs b/blade-graphics/src/vulkan/mod.rs index 400b95a..c985ef7 100644 --- a/blade-graphics/src/vulkan/mod.rs +++ b/blade-graphics/src/vulkan/mod.rs @@ -1,5 +1,5 @@ use ash::{khr, vk}; -use std::{num::NonZeroU32, path::PathBuf, ptr, sync::Mutex}; +use std::{mem, num::NonZeroU32, path::PathBuf, ptr, sync::Mutex}; mod command; mod descriptor; @@ -222,6 +222,12 @@ struct DescriptorSetLayout { template_offsets: Box<[u32]>, } +impl DescriptorSetLayout { + fn is_empty(&self) -> bool { + self.template_size == 0 + } +} + #[derive(Debug)] struct PipelineLayout { raw: vk::PipelineLayout, @@ -444,7 +450,7 @@ impl crate::traits::CommandDevice for Context { unsafe { self.device .core - .destroy_command_pool(command_encoder.pool, None) + .destroy_command_pool(mem::take(&mut command_encoder.pool), None) }; if let Some(crash_handler) = command_encoder.crash_handler.take() { self.destroy_buffer(crash_handler.marker_buf); diff --git a/blade-graphics/src/vulkan/pipeline.rs b/blade-graphics/src/vulkan/pipeline.rs index 17d914b..8182aa8 100644 --- a/blade-graphics/src/vulkan/pipeline.rs +++ b/blade-graphics/src/vulkan/pipeline.rs @@ -164,8 +164,18 @@ impl super::Context { info: &crate::ShaderDataInfo, ) -> super::DescriptorSetLayout { if info.visibility.is_empty() { - return super::DescriptorSetLayout::default(); + // we need to have a valid `VkDescriptorSetLayout` regardless + return super::DescriptorSetLayout { + raw: unsafe { + self.device + .core + .create_descriptor_set_layout(&Default::default(), None) + .unwrap() + }, + ..Default::default() + }; } + let stage_flags = map_shader_visibility(info.visibility); let mut vk_bindings = Vec::with_capacity(layout.bindings.len()); let mut template_entries = Vec::with_capacity(layout.bindings.len()); @@ -230,6 +240,7 @@ impl super::Context { vk::DescriptorBindingFlags::empty(), ), }; + vk_bindings.push(vk::DescriptorSetLayoutBinding { binding: binding_index as u32, descriptor_type, @@ -245,8 +256,8 @@ impl super::Context { offset: update_offset, stride: descriptor_size, }); - template_offsets.push(update_offset as u32); binding_flags.push(flag); + template_offsets.push(update_offset as u32); update_offset += descriptor_size * descriptor_count as usize; } @@ -310,16 +321,22 @@ impl super::Context { fn destroy_pipeline_layout(&self, layout: &mut super::PipelineLayout) { unsafe { - self.device.core.destroy_pipeline_layout(layout.raw, None); + self.device + .core + .destroy_pipeline_layout(mem::take(&mut layout.raw), None); } for dsl in layout.descriptor_set_layouts.drain(..) { unsafe { self.device .core .destroy_descriptor_set_layout(dsl.raw, None); - self.device - .core - .destroy_descriptor_update_template(dsl.update_template, None); + } + if !dsl.is_empty() { + unsafe { + self.device + .core + .destroy_descriptor_update_template(dsl.update_template, None); + } } } } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d1e6aa3..88c0636 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,6 +16,8 @@ Changelog for Blade - concurrent compute dispatches - Egl: - destroy old surface on resize + - Vulkan: + - support unused bind groups ## blade-egui-0.5 (09 Nov 2024)