Skip to content

Commit 0337f1e

Browse files
committed
[vulkan] Use corresponding bind group layout entries when creating bind groups, rather than list of vk::DescriptorType
This is a refactoring of Vulkan BindGroupLayout and BindGroup creation in preparation for implementing external texture support. Currently when creating a BindGroupLayout the Vulkan backend creates a list of the vk::DescriptorType for each entry, as well as the count, for binding arrays. Then when creating the BindGroup, it iterates through this list and does whatever it needs to do for each entry based on these values. In order to support external textures, we will have to create multiple descriptors for each BindingType::ExternalTexture. This means we cannot map each binding type to a single Vulkan descriptor type. Instead, store the list of BindGroupLayoutEntries on the BindGroupLayout and use those when creating the BindGroup, using the same "layout_and_entry_iter" idiom used by other backends. In subsequent patches this will allow us to create multiple descriptors for a single resource binding.
1 parent c7fd582 commit 0337f1e

File tree

2 files changed

+87
-86
lines changed

2 files changed

+87
-86
lines changed

wgpu-hal/src/vulkan/device.rs

Lines changed: 85 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,20 +1480,46 @@ impl crate::Device for super::Device {
14801480
&self,
14811481
desc: &crate::BindGroupLayoutDescriptor,
14821482
) -> Result<super::BindGroupLayout, crate::DeviceError> {
1483+
// Iterate through the entries and accumulate our Vulkan
1484+
// DescriptorSetLayoutBindings and DescriptorBindingFlags, as well as
1485+
// the list of which bindings are binding arrays, and our descriptor
1486+
// counts.
1487+
// Note: not bothering with on stack arrays here as it's low frequency
1488+
let mut vk_bindings = Vec::new();
1489+
let mut binding_flags = Vec::new();
1490+
let mut binding_arrays = Vec::new();
14831491
let mut desc_count = gpu_descriptor::DescriptorTotalCount::default();
1484-
let mut types = Vec::new();
1485-
for entry in desc.entries {
1492+
for (i, entry) in desc.entries.iter().enumerate() {
1493+
if let Some(count) = entry.count {
1494+
binding_arrays.push((i as u32, count))
1495+
}
1496+
1497+
let partially_bound = desc
1498+
.flags
1499+
.contains(crate::BindGroupLayoutFlags::PARTIALLY_BOUND);
1500+
let mut flags = vk::DescriptorBindingFlags::empty();
1501+
if partially_bound && entry.count.is_some() {
1502+
flags |= vk::DescriptorBindingFlags::PARTIALLY_BOUND;
1503+
}
1504+
if entry.count.is_some() {
1505+
flags |= vk::DescriptorBindingFlags::UPDATE_AFTER_BIND;
1506+
}
1507+
14861508
let count = entry.count.map_or(1, |c| c.get());
1487-
if entry.binding as usize >= types.len() {
1488-
types.resize(
1489-
entry.binding as usize + 1,
1490-
(vk::DescriptorType::INPUT_ATTACHMENT, 0),
1491-
);
1509+
match entry.ty {
1510+
wgt::BindingType::ExternalTexture => unimplemented!(),
1511+
_ => {
1512+
vk_bindings.push(vk::DescriptorSetLayoutBinding {
1513+
binding: entry.binding,
1514+
descriptor_type: conv::map_binding_type(entry.ty),
1515+
descriptor_count: count,
1516+
stage_flags: conv::map_shader_stage(entry.visibility),
1517+
p_immutable_samplers: ptr::null(),
1518+
_marker: Default::default(),
1519+
});
1520+
binding_flags.push(flags);
1521+
}
14921522
}
1493-
types[entry.binding as usize] = (
1494-
conv::map_binding_type(entry.ty),
1495-
entry.count.map_or(1, |c| c.get()),
1496-
);
14971523

14981524
match entry.ty {
14991525
wgt::BindingType::Buffer {
@@ -1532,27 +1558,6 @@ impl crate::Device for super::Device {
15321558
}
15331559
}
15341560

1535-
//Note: not bothering with on stack array here as it's low frequency
1536-
let vk_bindings = desc
1537-
.entries
1538-
.iter()
1539-
.map(|entry| vk::DescriptorSetLayoutBinding {
1540-
binding: entry.binding,
1541-
descriptor_type: types[entry.binding as usize].0,
1542-
descriptor_count: types[entry.binding as usize].1,
1543-
stage_flags: conv::map_shader_stage(entry.visibility),
1544-
p_immutable_samplers: ptr::null(),
1545-
_marker: Default::default(),
1546-
})
1547-
.collect::<Vec<_>>();
1548-
1549-
let binding_arrays: Vec<_> = desc
1550-
.entries
1551-
.iter()
1552-
.enumerate()
1553-
.filter_map(|(idx, entry)| entry.count.map(|count| (idx as u32, count)))
1554-
.collect();
1555-
15561561
let vk_info = vk::DescriptorSetLayoutCreateInfo::default()
15571562
.bindings(&vk_bindings)
15581563
.flags(if !binding_arrays.is_empty() {
@@ -1561,30 +1566,8 @@ impl crate::Device for super::Device {
15611566
vk::DescriptorSetLayoutCreateFlags::empty()
15621567
});
15631568

1564-
let partially_bound = desc
1565-
.flags
1566-
.contains(crate::BindGroupLayoutFlags::PARTIALLY_BOUND);
1567-
1568-
let binding_flag_vec = desc
1569-
.entries
1570-
.iter()
1571-
.map(|entry| {
1572-
let mut flags = vk::DescriptorBindingFlags::empty();
1573-
1574-
if partially_bound && entry.count.is_some() {
1575-
flags |= vk::DescriptorBindingFlags::PARTIALLY_BOUND;
1576-
}
1577-
1578-
if entry.count.is_some() {
1579-
flags |= vk::DescriptorBindingFlags::UPDATE_AFTER_BIND;
1580-
}
1581-
1582-
flags
1583-
})
1584-
.collect::<Vec<_>>();
1585-
1586-
let mut binding_flag_info = vk::DescriptorSetLayoutBindingFlagsCreateInfo::default()
1587-
.binding_flags(&binding_flag_vec);
1569+
let mut binding_flag_info =
1570+
vk::DescriptorSetLayoutBindingFlagsCreateInfo::default().binding_flags(&binding_flags);
15881571

15891572
let vk_info = vk_info.push_next(&mut binding_flag_info);
15901573

@@ -1604,7 +1587,7 @@ impl crate::Device for super::Device {
16041587
Ok(super::BindGroupLayout {
16051588
raw,
16061589
desc_count,
1607-
types: types.into_boxed_slice(),
1590+
entries: desc.entries.into(),
16081591
binding_arrays,
16091592
})
16101593
}
@@ -1787,28 +1770,36 @@ impl crate::Device for super::Device {
17871770
Vec::with_capacity(desc.acceleration_structures.len());
17881771
let mut raw_acceleration_structures =
17891772
ExtendStack::from_vec_capacity(&mut raw_acceleration_structures);
1790-
for entry in desc.entries {
1791-
let (ty, size) = desc.layout.types[entry.binding as usize];
1792-
if size == 0 {
1793-
continue; // empty slot
1794-
}
1795-
let mut write = vk::WriteDescriptorSet::default()
1796-
.dst_set(*set.raw())
1797-
.dst_binding(entry.binding)
1798-
.descriptor_type(ty);
1799-
1800-
write = match ty {
1801-
vk::DescriptorType::SAMPLER => {
1773+
1774+
let layout_and_entry_iter = desc.entries.iter().map(|entry| {
1775+
let layout = desc
1776+
.layout
1777+
.entries
1778+
.iter()
1779+
.find(|layout_entry| layout_entry.binding == entry.binding)
1780+
.expect("internal error: no layout entry found with binding slot");
1781+
(layout, entry)
1782+
});
1783+
for (layout, entry) in layout_and_entry_iter {
1784+
let write = vk::WriteDescriptorSet::default().dst_set(*set.raw());
1785+
1786+
match layout.ty {
1787+
wgt::BindingType::Sampler(_) => {
18021788
let start = entry.resource_index;
18031789
let end = start + entry.count;
18041790
let local_image_infos;
18051791
(image_infos, local_image_infos) =
18061792
image_infos.extend(desc.samplers[start as usize..end as usize].iter().map(
18071793
|sampler| vk::DescriptorImageInfo::default().sampler(sampler.raw),
18081794
));
1809-
write.image_info(local_image_infos)
1795+
writes.push(
1796+
write
1797+
.dst_binding(entry.binding)
1798+
.descriptor_type(conv::map_binding_type(layout.ty))
1799+
.image_info(local_image_infos),
1800+
);
18101801
}
1811-
vk::DescriptorType::SAMPLED_IMAGE | vk::DescriptorType::STORAGE_IMAGE => {
1802+
wgt::BindingType::Texture { .. } | wgt::BindingType::StorageTexture { .. } => {
18121803
let start = entry.resource_index;
18131804
let end = start + entry.count;
18141805
let local_image_infos;
@@ -1822,12 +1813,14 @@ impl crate::Device for super::Device {
18221813
.image_layout(layout)
18231814
},
18241815
));
1825-
write.image_info(local_image_infos)
1816+
writes.push(
1817+
write
1818+
.dst_binding(entry.binding)
1819+
.descriptor_type(conv::map_binding_type(layout.ty))
1820+
.image_info(local_image_infos),
1821+
);
18261822
}
1827-
vk::DescriptorType::UNIFORM_BUFFER
1828-
| vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC
1829-
| vk::DescriptorType::STORAGE_BUFFER
1830-
| vk::DescriptorType::STORAGE_BUFFER_DYNAMIC => {
1823+
wgt::BindingType::Buffer { .. } => {
18311824
let start = entry.resource_index;
18321825
let end = start + entry.count;
18331826
let local_buffer_infos;
@@ -1842,9 +1835,14 @@ impl crate::Device for super::Device {
18421835
)
18431836
},
18441837
));
1845-
write.buffer_info(local_buffer_infos)
1838+
writes.push(
1839+
write
1840+
.dst_binding(entry.binding)
1841+
.descriptor_type(conv::map_binding_type(layout.ty))
1842+
.buffer_info(local_buffer_infos),
1843+
);
18461844
}
1847-
vk::DescriptorType::ACCELERATION_STRUCTURE_KHR => {
1845+
wgt::BindingType::AccelerationStructure { .. } => {
18481846
let start = entry.resource_index;
18491847
let end = start + entry.count;
18501848

@@ -1867,14 +1865,16 @@ impl crate::Device for super::Device {
18671865
.acceleration_structures(local_raw_acceleration_structures),
18681866
);
18691867

1870-
write
1871-
.descriptor_count(entry.count)
1872-
.push_next(local_acceleration_structure_infos)
1868+
writes.push(
1869+
write
1870+
.dst_binding(entry.binding)
1871+
.descriptor_type(conv::map_binding_type(layout.ty))
1872+
.descriptor_count(entry.count)
1873+
.push_next(local_acceleration_structure_infos),
1874+
);
18731875
}
1874-
_ => unreachable!(),
1875-
};
1876-
1877-
writes.push(write);
1876+
wgt::BindingType::ExternalTexture => unimplemented!(),
1877+
}
18781878
}
18791879

18801880
unsafe { self.shared.raw.update_descriptor_sets(&writes, &[]) };

wgpu-hal/src/vulkan/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,8 @@ impl crate::DynSampler for Sampler {}
10051005
pub struct BindGroupLayout {
10061006
raw: vk::DescriptorSetLayout,
10071007
desc_count: gpu_descriptor::DescriptorTotalCount,
1008-
types: Box<[(vk::DescriptorType, u32)]>,
1008+
/// Sorted list of entries.
1009+
entries: Box<[wgt::BindGroupLayoutEntry]>,
10091010
/// Map of binding index to size,
10101011
binding_arrays: Vec<(u32, NonZeroU32)>,
10111012
}

0 commit comments

Comments
 (0)