mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 14:56:42 +00:00
Replace ImageAccess::descriptor_layouts()
(#2197)
* Replace `ImageAccess::descriptor_layouts()` * Add `WriteDescriptorSet` constructors for image views with layout * Replace `descriptor_layouts` for real * Small changes * More improvements
This commit is contained in:
parent
7741e00348
commit
93babbebae
@ -20,8 +20,8 @@ use vulkano::{
|
|||||||
allocator::StandardCommandBufferAllocator, AutoCommandBufferBuilder, CommandBufferUsage,
|
allocator::StandardCommandBufferAllocator, AutoCommandBufferBuilder, CommandBufferUsage,
|
||||||
},
|
},
|
||||||
descriptor_set::{
|
descriptor_set::{
|
||||||
allocator::StandardDescriptorSetAllocator, layout::DescriptorType, DescriptorSet,
|
allocator::StandardDescriptorSetAllocator, layout::DescriptorType, DescriptorBufferInfo,
|
||||||
PersistentDescriptorSet, WriteDescriptorSet,
|
DescriptorSet, PersistentDescriptorSet, WriteDescriptorSet,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
@ -226,8 +226,10 @@ fn main() {
|
|||||||
// this range.
|
// this range.
|
||||||
WriteDescriptorSet::buffer_with_range(
|
WriteDescriptorSet::buffer_with_range(
|
||||||
0,
|
0,
|
||||||
input_buffer,
|
DescriptorBufferInfo {
|
||||||
0..size_of::<cs::InData>() as DeviceSize,
|
buffer: input_buffer,
|
||||||
|
range: 0..size_of::<cs::InData>() as DeviceSize,
|
||||||
|
},
|
||||||
),
|
),
|
||||||
WriteDescriptorSet::buffer(1, output_buffer.clone()),
|
WriteDescriptorSet::buffer(1, output_buffer.clone()),
|
||||||
],
|
],
|
||||||
|
@ -17,10 +17,10 @@ use crate::{
|
|||||||
AutoCommandBufferBuilder,
|
AutoCommandBufferBuilder,
|
||||||
},
|
},
|
||||||
descriptor_set::{
|
descriptor_set::{
|
||||||
check_descriptor_write, layout::DescriptorType, sys::UnsafeDescriptorSet,
|
layout::DescriptorType, set_descriptor_write_image_layouts, sys::UnsafeDescriptorSet,
|
||||||
DescriptorBindingResources, DescriptorSetResources, DescriptorSetUpdateError,
|
validate_descriptor_write, DescriptorBindingResources, DescriptorBufferInfo,
|
||||||
DescriptorSetWithOffsets, DescriptorSetsCollection, DescriptorWriteInfo,
|
DescriptorSetResources, DescriptorSetUpdateError, DescriptorSetWithOffsets,
|
||||||
WriteDescriptorSet,
|
DescriptorSetsCollection, DescriptorWriteInfo, WriteDescriptorSet,
|
||||||
},
|
},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
memory::{is_aligned, DeviceAlignment},
|
memory::{is_aligned, DeviceAlignment},
|
||||||
@ -194,7 +194,9 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((buffer, range)) = element {
|
if let Some(buffer_info) = element {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
// VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979
|
// VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979
|
||||||
if offset as DeviceSize + range.end > buffer.size() {
|
if offset as DeviceSize + range.end > buffer.size() {
|
||||||
return Err(BindPushError::DynamicOffsetOutOfBufferBounds {
|
return Err(BindPushError::DynamicOffsetOutOfBufferBounds {
|
||||||
@ -623,7 +625,15 @@ where
|
|||||||
set_num: u32,
|
set_num: u32,
|
||||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let descriptor_writes: SmallVec<[_; 8]> = descriptor_writes.into_iter().collect();
|
let mut descriptor_writes: SmallVec<[_; 8]> = descriptor_writes.into_iter().collect();
|
||||||
|
|
||||||
|
// Set the image layouts
|
||||||
|
if let Some(set_layout) = pipeline_layout.set_layouts().get(set_num as usize) {
|
||||||
|
for write in &mut descriptor_writes {
|
||||||
|
set_descriptor_write_image_layouts(write, set_layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.validate_push_descriptor_set(
|
self.validate_push_descriptor_set(
|
||||||
pipeline_bind_point,
|
pipeline_bind_point,
|
||||||
&pipeline_layout,
|
&pipeline_layout,
|
||||||
@ -706,7 +716,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
for write in descriptor_writes {
|
for write in descriptor_writes {
|
||||||
check_descriptor_write(write, descriptor_set_layout, 0)?;
|
validate_descriptor_write(write, descriptor_set_layout, 0)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -901,9 +911,16 @@ impl SyncCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let descriptor_writes: SmallVec<[WriteDescriptorSet; 8]> =
|
let mut descriptor_writes: SmallVec<[WriteDescriptorSet; 8]> =
|
||||||
descriptor_writes.into_iter().collect();
|
descriptor_writes.into_iter().collect();
|
||||||
|
|
||||||
|
// Set the image layouts
|
||||||
|
if let Some(set_layout) = pipeline_layout.set_layouts().get(set_num as usize) {
|
||||||
|
for write in &mut descriptor_writes {
|
||||||
|
set_descriptor_write_image_layouts(write, set_layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let state = self.current_state.invalidate_descriptor_sets(
|
let state = self.current_state.invalidate_descriptor_sets(
|
||||||
pipeline_bind_point,
|
pipeline_bind_point,
|
||||||
pipeline_layout.clone(),
|
pipeline_layout.clone(),
|
||||||
@ -1213,12 +1230,15 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
descriptor_writes: impl IntoIterator<Item = &'a WriteDescriptorSet>,
|
descriptor_writes: impl IntoIterator<Item = &'a WriteDescriptorSet>,
|
||||||
) {
|
) {
|
||||||
debug_assert!(self.device.enabled_extensions().khr_push_descriptor);
|
debug_assert!(self.device.enabled_extensions().khr_push_descriptor);
|
||||||
|
let set_layout = &pipeline_layout.set_layouts()[set_num as usize];
|
||||||
|
|
||||||
let (infos, mut writes): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = descriptor_writes
|
let (infos_vk, mut writes_vk): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = descriptor_writes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|write| {
|
.map(|write| {
|
||||||
let binding =
|
let mut write = write.clone(); // Ew!
|
||||||
&pipeline_layout.set_layouts()[set_num as usize].bindings()[&write.binding()];
|
set_descriptor_write_image_layouts(&mut write, set_layout);
|
||||||
|
|
||||||
|
let binding = &set_layout.bindings()[&write.binding()];
|
||||||
|
|
||||||
(
|
(
|
||||||
write.to_vulkan_info(binding.descriptor_type),
|
write.to_vulkan_info(binding.descriptor_type),
|
||||||
@ -1227,28 +1247,28 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
if writes.is_empty() {
|
if writes_vk.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the info pointers separately.
|
// Set the info pointers separately.
|
||||||
for (info, write) in infos.iter().zip(writes.iter_mut()) {
|
for (info_vk, write_vk) in infos_vk.iter().zip(writes_vk.iter_mut()) {
|
||||||
match info {
|
match info_vk {
|
||||||
DescriptorWriteInfo::Image(info) => {
|
DescriptorWriteInfo::Image(info) => {
|
||||||
write.descriptor_count = info.len() as u32;
|
write_vk.descriptor_count = info.len() as u32;
|
||||||
write.p_image_info = info.as_ptr();
|
write_vk.p_image_info = info.as_ptr();
|
||||||
}
|
}
|
||||||
DescriptorWriteInfo::Buffer(info) => {
|
DescriptorWriteInfo::Buffer(info) => {
|
||||||
write.descriptor_count = info.len() as u32;
|
write_vk.descriptor_count = info.len() as u32;
|
||||||
write.p_buffer_info = info.as_ptr();
|
write_vk.p_buffer_info = info.as_ptr();
|
||||||
}
|
}
|
||||||
DescriptorWriteInfo::BufferView(info) => {
|
DescriptorWriteInfo::BufferView(info) => {
|
||||||
write.descriptor_count = info.len() as u32;
|
write_vk.descriptor_count = info.len() as u32;
|
||||||
write.p_texel_buffer_view = info.as_ptr();
|
write_vk.p_texel_buffer_view = info.as_ptr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(write.descriptor_count != 0);
|
debug_assert!(write_vk.descriptor_count != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let fns = self.device.fns();
|
let fns = self.device.fns();
|
||||||
@ -1258,8 +1278,8 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
pipeline_bind_point.into(),
|
pipeline_bind_point.into(),
|
||||||
pipeline_layout.handle(),
|
pipeline_layout.handle(),
|
||||||
set_num,
|
set_num,
|
||||||
writes.len() as u32,
|
writes_vk.len() as u32,
|
||||||
writes.as_ptr(),
|
writes_vk.as_ptr(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,15 @@ use crate::{
|
|||||||
AutoCommandBufferBuilder, DispatchIndirectCommand, DrawIndexedIndirectCommand,
|
AutoCommandBufferBuilder, DispatchIndirectCommand, DrawIndexedIndirectCommand,
|
||||||
DrawIndirectCommand, ResourceInCommand, ResourceUseRef, SubpassContents,
|
DrawIndirectCommand, ResourceInCommand, ResourceUseRef, SubpassContents,
|
||||||
},
|
},
|
||||||
descriptor_set::{layout::DescriptorType, DescriptorBindingResources},
|
descriptor_set::{
|
||||||
|
layout::DescriptorType, DescriptorBindingResources, DescriptorBufferInfo,
|
||||||
|
DescriptorImageViewInfo,
|
||||||
|
},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
format::{Format, FormatFeatures},
|
format::{Format, FormatFeatures},
|
||||||
image::{
|
image::{
|
||||||
view::ImageViewType, ImageAccess, ImageAspects, ImageSubresourceRange, ImageViewAbstract,
|
view::ImageViewType, ImageAccess, ImageAspects, ImageLayout, ImageSubresourceRange,
|
||||||
SampleCount,
|
ImageViewAbstract, SampleCount,
|
||||||
},
|
},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
graphics::{
|
graphics::{
|
||||||
@ -642,8 +645,7 @@ where
|
|||||||
let layout_binding =
|
let layout_binding =
|
||||||
&pipeline.layout().set_layouts()[set_num as usize].bindings()[&binding_num];
|
&pipeline.layout().set_layouts()[set_num as usize].bindings()[&binding_num];
|
||||||
|
|
||||||
let check_buffer =
|
let check_buffer = |_index: u32, _buffer_info: &DescriptorBufferInfo| Ok(());
|
||||||
|_index: u32, (_buffer, _range): &(Subbuffer<[u8]>, Range<DeviceSize>)| Ok(());
|
|
||||||
|
|
||||||
let check_buffer_view = |index: u32, buffer_view: &Arc<BufferView>| {
|
let check_buffer_view = |index: u32, buffer_view: &Arc<BufferView>| {
|
||||||
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter())
|
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter())
|
||||||
@ -840,7 +842,12 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let check_image_view = |index: u32, image_view: &Arc<dyn ImageViewAbstract>| {
|
let check_image_view = |index: u32, image_view_info: &DescriptorImageViewInfo| {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: _,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
check_image_view_common(index, image_view)?;
|
check_image_view_common(index, image_view)?;
|
||||||
|
|
||||||
if let Some(sampler) = layout_binding.immutable_samplers.get(index as usize) {
|
if let Some(sampler) = layout_binding.immutable_samplers.get(index as usize) {
|
||||||
@ -850,13 +857,21 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let check_image_view_sampler =
|
let check_image_view_sampler = |index: u32,
|
||||||
|index: u32, (image_view, sampler): &(Arc<dyn ImageViewAbstract>, Arc<Sampler>)| {
|
(image_view_info, sampler): &(
|
||||||
check_image_view_common(index, image_view)?;
|
DescriptorImageViewInfo,
|
||||||
check_sampler_common(index, sampler)?;
|
Arc<Sampler>,
|
||||||
|
)| {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: _,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
Ok(())
|
check_image_view_common(index, image_view)?;
|
||||||
};
|
check_sampler_common(index, sampler)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
let check_sampler = |index: u32, sampler: &Arc<Sampler>| {
|
let check_sampler = |index: u32, sampler: &Arc<Sampler>| {
|
||||||
check_sampler_common(index, sampler)?;
|
check_sampler_common(index, sampler)?;
|
||||||
@ -881,7 +896,12 @@ where
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
for (id, image_view) in iter {
|
for (id, image_view_info) in iter {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: _,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
if let Err(error) = sampler.check_can_sample(image_view.as_ref()) {
|
if let Err(error) = sampler.check_can_sample(image_view.as_ref()) {
|
||||||
return Err(
|
return Err(
|
||||||
DescriptorResourceInvalidError::SamplerImageViewIncompatible {
|
DescriptorResourceInvalidError::SamplerImageViewIncompatible {
|
||||||
@ -2101,16 +2121,12 @@ impl SyncCommandBufferBuilder {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let image_resource = |(index, image, subresource_range): (
|
let image_resource = |(index, image, layout, subresource_range): (
|
||||||
u32,
|
u32,
|
||||||
Arc<dyn ImageAccess>,
|
Arc<dyn ImageAccess>,
|
||||||
|
ImageLayout,
|
||||||
ImageSubresourceRange,
|
ImageSubresourceRange,
|
||||||
)| {
|
)| {
|
||||||
let layout = image
|
|
||||||
.descriptor_layouts()
|
|
||||||
.expect("descriptor_layouts must return Some when used in an image view")
|
|
||||||
.layout_for(descriptor_type);
|
|
||||||
|
|
||||||
memory_iter(index).map(move |memory| {
|
memory_iter(index).map(move |memory| {
|
||||||
(
|
(
|
||||||
ResourceUseRef {
|
ResourceUseRef {
|
||||||
@ -2147,7 +2163,9 @@ impl SyncCommandBufferBuilder {
|
|||||||
resources.extend(
|
resources.extend(
|
||||||
(elements.iter().enumerate())
|
(elements.iter().enumerate())
|
||||||
.filter_map(|(index, element)| {
|
.filter_map(|(index, element)| {
|
||||||
element.as_ref().map(|(buffer, range)| {
|
element.as_ref().map(|buffer_info| {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
let dynamic_offset = dynamic_offsets[index] as DeviceSize;
|
let dynamic_offset = dynamic_offsets[index] as DeviceSize;
|
||||||
|
|
||||||
(
|
(
|
||||||
@ -2164,7 +2182,8 @@ impl SyncCommandBufferBuilder {
|
|||||||
resources.extend(
|
resources.extend(
|
||||||
(elements.iter().enumerate())
|
(elements.iter().enumerate())
|
||||||
.filter_map(|(index, element)| {
|
.filter_map(|(index, element)| {
|
||||||
element.as_ref().map(|(buffer, range)| {
|
element.as_ref().map(|buffer_info| {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
(index as u32, buffer.clone(), range.clone())
|
(index as u32, buffer.clone(), range.clone())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -2191,10 +2210,16 @@ impl SyncCommandBufferBuilder {
|
|||||||
resources.extend(
|
resources.extend(
|
||||||
(elements.iter().enumerate())
|
(elements.iter().enumerate())
|
||||||
.filter_map(|(index, element)| {
|
.filter_map(|(index, element)| {
|
||||||
element.as_ref().map(|image_view| {
|
element.as_ref().map(|image_view_info| {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
(
|
(
|
||||||
index as u32,
|
index as u32,
|
||||||
image_view.image(),
|
image_view.image(),
|
||||||
|
image_layout,
|
||||||
image_view.subresource_range().clone(),
|
image_view.subresource_range().clone(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -2206,10 +2231,16 @@ impl SyncCommandBufferBuilder {
|
|||||||
resources.extend(
|
resources.extend(
|
||||||
(elements.iter().enumerate())
|
(elements.iter().enumerate())
|
||||||
.filter_map(|(index, element)| {
|
.filter_map(|(index, element)| {
|
||||||
element.as_ref().map(|(image_view, _)| {
|
element.as_ref().map(|(image_view_info, _sampler)| {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
(
|
(
|
||||||
index as u32,
|
index as u32,
|
||||||
image_view.image(),
|
image_view.image(),
|
||||||
|
image_layout,
|
||||||
image_view.subresource_range().clone(),
|
image_view.subresource_range().clone(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -12,9 +12,10 @@ use crate::{
|
|||||||
buffer::{BufferContents, BufferUsage, Subbuffer},
|
buffer::{BufferContents, BufferUsage, Subbuffer},
|
||||||
command_buffer::{allocator::CommandBufferAllocator, commands::bind_push::BindPushError},
|
command_buffer::{allocator::CommandBufferAllocator, commands::bind_push::BindPushError},
|
||||||
descriptor_set::{
|
descriptor_set::{
|
||||||
check_descriptor_write, layout::DescriptorType, DescriptorBindingResources,
|
layout::DescriptorType, set_descriptor_write_image_layouts, validate_descriptor_write,
|
||||||
DescriptorSetResources, DescriptorSetWithOffsets, DescriptorSetsCollection,
|
DescriptorBindingResources, DescriptorBufferInfo, DescriptorSetResources,
|
||||||
DescriptorWriteInfo, WriteDescriptorSet,
|
DescriptorSetWithOffsets, DescriptorSetsCollection, DescriptorWriteInfo,
|
||||||
|
WriteDescriptorSet,
|
||||||
},
|
},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
memory::is_aligned,
|
memory::is_aligned,
|
||||||
@ -172,7 +173,9 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((buffer, range)) = element {
|
if let Some(buffer_info) = element {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
// VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979
|
// VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979
|
||||||
if offset as DeviceSize + range.end > buffer.size() {
|
if offset as DeviceSize + range.end > buffer.size() {
|
||||||
return Err(BindPushError::DynamicOffsetOutOfBufferBounds {
|
return Err(BindPushError::DynamicOffsetOutOfBufferBounds {
|
||||||
@ -761,7 +764,15 @@ where
|
|||||||
set_num: u32,
|
set_num: u32,
|
||||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let descriptor_writes: SmallVec<[_; 8]> = descriptor_writes.into_iter().collect();
|
let mut descriptor_writes: SmallVec<[_; 8]> = descriptor_writes.into_iter().collect();
|
||||||
|
|
||||||
|
// Set the image layouts
|
||||||
|
if let Some(set_layout) = pipeline_layout.set_layouts().get(set_num as usize) {
|
||||||
|
for write in &mut descriptor_writes {
|
||||||
|
set_descriptor_write_image_layouts(write, set_layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.validate_push_descriptor_set(
|
self.validate_push_descriptor_set(
|
||||||
pipeline_bind_point,
|
pipeline_bind_point,
|
||||||
&pipeline_layout,
|
&pipeline_layout,
|
||||||
@ -842,7 +853,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
for write in descriptor_writes {
|
for write in descriptor_writes {
|
||||||
check_descriptor_write(write, descriptor_set_layout, 0)?;
|
validate_descriptor_write(write, descriptor_set_layout, 0)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -856,16 +867,17 @@ where
|
|||||||
set_num: u32,
|
set_num: u32,
|
||||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
let descriptor_writes: SmallVec<[WriteDescriptorSet; 8]> =
|
let mut descriptor_writes: SmallVec<[WriteDescriptorSet; 8]> =
|
||||||
descriptor_writes.into_iter().collect();
|
descriptor_writes.into_iter().collect();
|
||||||
|
|
||||||
debug_assert!(self.device().enabled_extensions().khr_push_descriptor);
|
debug_assert!(self.device().enabled_extensions().khr_push_descriptor);
|
||||||
|
let set_layout = &pipeline_layout.set_layouts()[set_num as usize];
|
||||||
|
|
||||||
let (infos, mut writes): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = descriptor_writes
|
let (infos_vk, mut writes_vk): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = descriptor_writes
|
||||||
.iter()
|
.iter_mut()
|
||||||
.map(|write| {
|
.map(|write| {
|
||||||
let binding =
|
set_descriptor_write_image_layouts(write, set_layout);
|
||||||
&pipeline_layout.set_layouts()[set_num as usize].bindings()[&write.binding()];
|
let binding = &set_layout.bindings()[&write.binding()];
|
||||||
|
|
||||||
(
|
(
|
||||||
write.to_vulkan_info(binding.descriptor_type),
|
write.to_vulkan_info(binding.descriptor_type),
|
||||||
@ -874,28 +886,28 @@ where
|
|||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
if writes.is_empty() {
|
if writes_vk.is_empty() {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the info pointers separately.
|
// Set the info pointers separately.
|
||||||
for (info, write) in infos.iter().zip(writes.iter_mut()) {
|
for (info_vk, write_vk) in infos_vk.iter().zip(writes_vk.iter_mut()) {
|
||||||
match info {
|
match info_vk {
|
||||||
DescriptorWriteInfo::Image(info) => {
|
DescriptorWriteInfo::Image(info) => {
|
||||||
write.descriptor_count = info.len() as u32;
|
write_vk.descriptor_count = info.len() as u32;
|
||||||
write.p_image_info = info.as_ptr();
|
write_vk.p_image_info = info.as_ptr();
|
||||||
}
|
}
|
||||||
DescriptorWriteInfo::Buffer(info) => {
|
DescriptorWriteInfo::Buffer(info) => {
|
||||||
write.descriptor_count = info.len() as u32;
|
write_vk.descriptor_count = info.len() as u32;
|
||||||
write.p_buffer_info = info.as_ptr();
|
write_vk.p_buffer_info = info.as_ptr();
|
||||||
}
|
}
|
||||||
DescriptorWriteInfo::BufferView(info) => {
|
DescriptorWriteInfo::BufferView(info) => {
|
||||||
write.descriptor_count = info.len() as u32;
|
write_vk.descriptor_count = info.len() as u32;
|
||||||
write.p_texel_buffer_view = info.as_ptr();
|
write_vk.p_texel_buffer_view = info.as_ptr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(write.descriptor_count != 0);
|
debug_assert!(write_vk.descriptor_count != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
@ -904,8 +916,8 @@ where
|
|||||||
pipeline_bind_point.into(),
|
pipeline_bind_point.into(),
|
||||||
pipeline_layout.handle(),
|
pipeline_layout.handle(),
|
||||||
set_num,
|
set_num,
|
||||||
writes.len() as u32,
|
writes_vk.len() as u32,
|
||||||
writes.as_ptr(),
|
writes_vk.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let state = self.builder_state.invalidate_descriptor_sets(
|
let state = self.builder_state.invalidate_descriptor_sets(
|
||||||
|
@ -18,7 +18,10 @@ use crate::{
|
|||||||
DispatchIndirectCommand, DrawIndexedIndirectCommand, DrawIndirectCommand,
|
DispatchIndirectCommand, DrawIndexedIndirectCommand, DrawIndirectCommand,
|
||||||
ResourceInCommand, ResourceUseRef, SubpassContents,
|
ResourceInCommand, ResourceUseRef, SubpassContents,
|
||||||
},
|
},
|
||||||
descriptor_set::{layout::DescriptorType, DescriptorBindingResources},
|
descriptor_set::{
|
||||||
|
layout::DescriptorType, DescriptorBindingResources, DescriptorBufferInfo,
|
||||||
|
DescriptorImageViewInfo,
|
||||||
|
},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
format::FormatFeatures,
|
format::FormatFeatures,
|
||||||
image::{ImageAccess, ImageAspects, ImageSubresourceRange, ImageViewAbstract, SampleCount},
|
image::{ImageAccess, ImageAspects, ImageSubresourceRange, ImageViewAbstract, SampleCount},
|
||||||
@ -40,7 +43,7 @@ use crate::{
|
|||||||
DeviceSize, RequiresOneOf, VulkanObject,
|
DeviceSize, RequiresOneOf, VulkanObject,
|
||||||
};
|
};
|
||||||
use ahash::HashMap;
|
use ahash::HashMap;
|
||||||
use std::{cmp::min, mem::size_of, ops::Range, sync::Arc};
|
use std::{cmp::min, mem::size_of, sync::Arc};
|
||||||
|
|
||||||
impl<L, A> CommandBufferBuilder<L, A>
|
impl<L, A> CommandBufferBuilder<L, A>
|
||||||
where
|
where
|
||||||
@ -991,8 +994,7 @@ where
|
|||||||
let layout_binding =
|
let layout_binding =
|
||||||
&pipeline.layout().set_layouts()[set_num as usize].bindings()[&binding_num];
|
&pipeline.layout().set_layouts()[set_num as usize].bindings()[&binding_num];
|
||||||
|
|
||||||
let check_buffer =
|
let check_buffer = |_index: u32, _info: &DescriptorBufferInfo| Ok(());
|
||||||
|_index: u32, (_buffer, _range): &(Subbuffer<[u8]>, Range<DeviceSize>)| Ok(());
|
|
||||||
|
|
||||||
let check_buffer_view = |index: u32, buffer_view: &Arc<BufferView>| {
|
let check_buffer_view = |index: u32, buffer_view: &Arc<BufferView>| {
|
||||||
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter())
|
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter())
|
||||||
@ -1189,7 +1191,12 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let check_image_view = |index: u32, image_view: &Arc<dyn ImageViewAbstract>| {
|
let check_image_view = |index: u32, image_view_info: &DescriptorImageViewInfo| {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: _,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
check_image_view_common(index, image_view)?;
|
check_image_view_common(index, image_view)?;
|
||||||
|
|
||||||
if let Some(sampler) = layout_binding.immutable_samplers.get(index as usize) {
|
if let Some(sampler) = layout_binding.immutable_samplers.get(index as usize) {
|
||||||
@ -1199,13 +1206,21 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let check_image_view_sampler =
|
let check_image_view_sampler = |index: u32,
|
||||||
|index: u32, (image_view, sampler): &(Arc<dyn ImageViewAbstract>, Arc<Sampler>)| {
|
(image_view_info, sampler): &(
|
||||||
check_image_view_common(index, image_view)?;
|
DescriptorImageViewInfo,
|
||||||
check_sampler_common(index, sampler)?;
|
Arc<Sampler>,
|
||||||
|
)| {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: _,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
Ok(())
|
check_image_view_common(index, image_view)?;
|
||||||
};
|
check_sampler_common(index, sampler)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
let check_sampler = |index: u32, sampler: &Arc<Sampler>| {
|
let check_sampler = |index: u32, sampler: &Arc<Sampler>| {
|
||||||
check_sampler_common(index, sampler)?;
|
check_sampler_common(index, sampler)?;
|
||||||
@ -1231,7 +1246,12 @@ where
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
for (id, image_view) in iter {
|
for (id, image_view_info) in iter {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: _,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
if let Err(error) = sampler.check_can_sample(image_view.as_ref()) {
|
if let Err(error) = sampler.check_can_sample(image_view.as_ref()) {
|
||||||
return Err(
|
return Err(
|
||||||
DescriptorResourceInvalidError::SamplerImageViewIncompatible {
|
DescriptorResourceInvalidError::SamplerImageViewIncompatible {
|
||||||
@ -2065,7 +2085,9 @@ fn record_descriptor_sets_access(
|
|||||||
let dynamic_offsets = descriptor_set_state.dynamic_offsets();
|
let dynamic_offsets = descriptor_set_state.dynamic_offsets();
|
||||||
|
|
||||||
for (index, element) in elements.iter().enumerate() {
|
for (index, element) in elements.iter().enumerate() {
|
||||||
if let Some((buffer, range)) = element {
|
if let Some(buffer_info) = element {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
let dynamic_offset = dynamic_offsets[index] as DeviceSize;
|
let dynamic_offset = dynamic_offsets[index] as DeviceSize;
|
||||||
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
@ -2085,7 +2107,9 @@ fn record_descriptor_sets_access(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (index, element) in elements.iter().enumerate() {
|
for (index, element) in elements.iter().enumerate() {
|
||||||
if let Some((buffer, range)) = element {
|
if let Some(buffer_info) = element {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
let mut range = range.clone();
|
let mut range = range.clone();
|
||||||
@ -2127,15 +2151,14 @@ fn record_descriptor_sets_access(
|
|||||||
}
|
}
|
||||||
DescriptorBindingResources::ImageView(elements) => {
|
DescriptorBindingResources::ImageView(elements) => {
|
||||||
for (index, element) in elements.iter().enumerate() {
|
for (index, element) in elements.iter().enumerate() {
|
||||||
if let Some(image_view) = element {
|
if let Some(image_view_info) = element {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
let image = image_view.image();
|
let image = image_view.image();
|
||||||
let image_inner = image.inner();
|
let image_inner = image.inner();
|
||||||
let layout = image
|
|
||||||
.descriptor_layouts()
|
|
||||||
.expect(
|
|
||||||
"descriptor_layouts must return Some when used in an image view",
|
|
||||||
)
|
|
||||||
.layout_for(descriptor_type);
|
|
||||||
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
for stage_access in stage_access_iter {
|
for stage_access in stage_access_iter {
|
||||||
@ -2144,7 +2167,7 @@ fn record_descriptor_sets_access(
|
|||||||
image_inner,
|
image_inner,
|
||||||
image_view.subresource_range().clone(),
|
image_view.subresource_range().clone(),
|
||||||
stage_access,
|
stage_access,
|
||||||
layout,
|
image_layout,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2152,15 +2175,14 @@ fn record_descriptor_sets_access(
|
|||||||
}
|
}
|
||||||
DescriptorBindingResources::ImageViewSampler(elements) => {
|
DescriptorBindingResources::ImageViewSampler(elements) => {
|
||||||
for (index, element) in elements.iter().enumerate() {
|
for (index, element) in elements.iter().enumerate() {
|
||||||
if let Some((image_view, _)) = element {
|
if let Some((image_view_info, _sampler)) = element {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
let image = image_view.image();
|
let image = image_view.image();
|
||||||
let image_inner = image.inner();
|
let image_inner = image.inner();
|
||||||
let layout = image
|
|
||||||
.descriptor_layouts()
|
|
||||||
.expect(
|
|
||||||
"descriptor_layouts must return Some when used in an image view",
|
|
||||||
)
|
|
||||||
.layout_for(descriptor_type);
|
|
||||||
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
for stage_access in stage_access_iter {
|
for stage_access in stage_access_iter {
|
||||||
@ -2169,7 +2191,7 @@ fn record_descriptor_sets_access(
|
|||||||
image_inner,
|
image_inner,
|
||||||
image_view.subresource_range().clone(),
|
image_view.subresource_range().clone(),
|
||||||
stage_access,
|
stage_access,
|
||||||
layout,
|
image_layout,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,20 +78,21 @@
|
|||||||
//! [`DescriptorSetAllocator`]: allocator::DescriptorSetAllocator
|
//! [`DescriptorSetAllocator`]: allocator::DescriptorSetAllocator
|
||||||
//! [`StandardDescriptorSetAllocator`]: allocator::StandardDescriptorSetAllocator
|
//! [`StandardDescriptorSetAllocator`]: allocator::StandardDescriptorSetAllocator
|
||||||
|
|
||||||
pub(crate) use self::update::{check_descriptor_write, DescriptorWriteInfo};
|
pub(crate) use self::update::{
|
||||||
|
set_descriptor_write_image_layouts, validate_descriptor_write, DescriptorWriteInfo,
|
||||||
|
};
|
||||||
pub use self::{
|
pub use self::{
|
||||||
collection::DescriptorSetsCollection,
|
collection::DescriptorSetsCollection,
|
||||||
persistent::PersistentDescriptorSet,
|
persistent::PersistentDescriptorSet,
|
||||||
update::{DescriptorSetUpdateError, WriteDescriptorSet, WriteDescriptorSetElements},
|
update::{
|
||||||
|
DescriptorBufferInfo, DescriptorImageViewInfo, DescriptorSetUpdateError,
|
||||||
|
WriteDescriptorSet, WriteDescriptorSetElements,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use self::{layout::DescriptorSetLayout, sys::UnsafeDescriptorSet};
|
use self::{layout::DescriptorSetLayout, sys::UnsafeDescriptorSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{view::BufferView, Subbuffer},
|
buffer::view::BufferView, descriptor_set::layout::DescriptorType, device::DeviceOwned,
|
||||||
descriptor_set::layout::DescriptorType,
|
sampler::Sampler, OomError, VulkanObject,
|
||||||
device::DeviceOwned,
|
|
||||||
image::view::ImageViewAbstract,
|
|
||||||
sampler::Sampler,
|
|
||||||
DeviceSize, OomError, VulkanObject,
|
|
||||||
};
|
};
|
||||||
use ahash::HashMap;
|
use ahash::HashMap;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
@ -99,7 +100,6 @@ use std::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Display, Error as FmtError, Formatter},
|
fmt::{Display, Error as FmtError, Formatter},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
ops::Range,
|
|
||||||
ptr,
|
ptr,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
@ -188,22 +188,24 @@ impl DescriptorSetInner {
|
|||||||
|
|
||||||
let descriptor_writes = descriptor_writes.into_iter();
|
let descriptor_writes = descriptor_writes.into_iter();
|
||||||
let (lower_size_bound, _) = descriptor_writes.size_hint();
|
let (lower_size_bound, _) = descriptor_writes.size_hint();
|
||||||
let mut descriptor_write_info: SmallVec<[_; 8]> = SmallVec::with_capacity(lower_size_bound);
|
let mut descriptor_write_infos_vk: SmallVec<[_; 8]> =
|
||||||
let mut write_descriptor_set: SmallVec<[_; 8]> = SmallVec::with_capacity(lower_size_bound);
|
SmallVec::with_capacity(lower_size_bound);
|
||||||
|
let mut descriptor_writes_vk: SmallVec<[_; 8]> = SmallVec::with_capacity(lower_size_bound);
|
||||||
|
|
||||||
for write in descriptor_writes {
|
for mut write in descriptor_writes {
|
||||||
|
set_descriptor_write_image_layouts(&mut write, &layout);
|
||||||
let layout_binding =
|
let layout_binding =
|
||||||
check_descriptor_write(&write, &layout, variable_descriptor_count)?;
|
validate_descriptor_write(&write, &layout, variable_descriptor_count)?;
|
||||||
|
|
||||||
resources.update(&write);
|
resources.update(&write);
|
||||||
descriptor_write_info.push(write.to_vulkan_info(layout_binding.descriptor_type));
|
descriptor_write_infos_vk.push(write.to_vulkan_info(layout_binding.descriptor_type));
|
||||||
write_descriptor_set.push(write.to_vulkan(handle, layout_binding.descriptor_type));
|
descriptor_writes_vk.push(write.to_vulkan(handle, layout_binding.descriptor_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !write_descriptor_set.is_empty() {
|
if !descriptor_writes_vk.is_empty() {
|
||||||
for (info, write) in descriptor_write_info
|
for (info, write) in descriptor_write_infos_vk
|
||||||
.iter()
|
.iter()
|
||||||
.zip(write_descriptor_set.iter_mut())
|
.zip(descriptor_writes_vk.iter_mut())
|
||||||
{
|
{
|
||||||
match info {
|
match info {
|
||||||
DescriptorWriteInfo::Image(info) => {
|
DescriptorWriteInfo::Image(info) => {
|
||||||
@ -227,8 +229,8 @@ impl DescriptorSetInner {
|
|||||||
|
|
||||||
(fns.v1_0.update_descriptor_sets)(
|
(fns.v1_0.update_descriptor_sets)(
|
||||||
layout.device().handle(),
|
layout.device().handle(),
|
||||||
write_descriptor_set.len() as u32,
|
descriptor_writes_vk.len() as u32,
|
||||||
write_descriptor_set.as_ptr(),
|
descriptor_writes_vk.as_ptr(),
|
||||||
0,
|
0,
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
);
|
);
|
||||||
@ -342,10 +344,10 @@ impl DescriptorSetResources {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum DescriptorBindingResources {
|
pub enum DescriptorBindingResources {
|
||||||
None(Elements<()>),
|
None(Elements<()>),
|
||||||
Buffer(Elements<(Subbuffer<[u8]>, Range<DeviceSize>)>),
|
Buffer(Elements<DescriptorBufferInfo>),
|
||||||
BufferView(Elements<Arc<BufferView>>),
|
BufferView(Elements<Arc<BufferView>>),
|
||||||
ImageView(Elements<Arc<dyn ImageViewAbstract>>),
|
ImageView(Elements<DescriptorImageViewInfo>),
|
||||||
ImageViewSampler(Elements<(Arc<dyn ImageViewAbstract>, Arc<Sampler>)>),
|
ImageViewSampler(Elements<(DescriptorImageViewInfo, Arc<Sampler>)>),
|
||||||
Sampler(Elements<Arc<Sampler>>),
|
Sampler(Elements<Arc<Sampler>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,9 @@ use super::layout::{DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorT
|
|||||||
use crate::{
|
use crate::{
|
||||||
buffer::{view::BufferView, BufferUsage, Subbuffer},
|
buffer::{view::BufferView, BufferUsage, Subbuffer},
|
||||||
device::DeviceOwned,
|
device::DeviceOwned,
|
||||||
image::{view::ImageViewType, ImageAspects, ImageType, ImageUsage, ImageViewAbstract},
|
image::{
|
||||||
|
view::ImageViewType, ImageAspects, ImageLayout, ImageType, ImageUsage, ImageViewAbstract,
|
||||||
|
},
|
||||||
sampler::{Sampler, SamplerImageViewIncompatibleError},
|
sampler::{Sampler, SamplerImageViewIncompatibleError},
|
||||||
DeviceSize, RequiresOneOf, VulkanObject,
|
DeviceSize, RequiresOneOf, VulkanObject,
|
||||||
};
|
};
|
||||||
@ -33,10 +35,11 @@ use std::{
|
|||||||
/// non-arrayed bindings, where `descriptor_count` in the descriptor set layout is 1.
|
/// non-arrayed bindings, where `descriptor_count` in the descriptor set layout is 1.
|
||||||
/// - The `_array` variant writes several elements and allows specifying the target array index.
|
/// - The `_array` variant writes several elements and allows specifying the target array index.
|
||||||
/// At least one element must be provided; a panic results if the provided iterator is empty.
|
/// At least one element must be provided; a panic results if the provided iterator is empty.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct WriteDescriptorSet {
|
pub struct WriteDescriptorSet {
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
elements: WriteDescriptorSetElements,
|
pub(crate) elements: WriteDescriptorSetElements, // public so that the image layouts can be changed
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteDescriptorSet {
|
impl WriteDescriptorSet {
|
||||||
@ -74,7 +77,14 @@ impl WriteDescriptorSet {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn buffer(binding: u32, buffer: Subbuffer<impl ?Sized>) -> Self {
|
pub fn buffer(binding: u32, buffer: Subbuffer<impl ?Sized>) -> Self {
|
||||||
let range = 0..buffer.size();
|
let range = 0..buffer.size();
|
||||||
Self::buffer_with_range_array(binding, 0, [(buffer, range)])
|
Self::buffer_with_range_array(
|
||||||
|
binding,
|
||||||
|
0,
|
||||||
|
[DescriptorBufferInfo {
|
||||||
|
buffer: buffer.into_bytes(),
|
||||||
|
range,
|
||||||
|
}],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive buffer elements.
|
/// Write a number of consecutive buffer elements.
|
||||||
@ -91,28 +101,18 @@ impl WriteDescriptorSet {
|
|||||||
first_array_element,
|
first_array_element,
|
||||||
elements.into_iter().map(|buffer| {
|
elements.into_iter().map(|buffer| {
|
||||||
let range = 0..buffer.size();
|
let range = 0..buffer.size();
|
||||||
(buffer, range)
|
DescriptorBufferInfo {
|
||||||
|
buffer: buffer.into_bytes(),
|
||||||
|
range,
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a single buffer to array element 0, specifying the range of the buffer to be bound.
|
/// Write a single buffer to array element 0, specifying the range of the buffer to be bound.
|
||||||
///
|
|
||||||
/// `range` is the slice of bytes in `buffer` that will be made available to the shader.
|
|
||||||
/// `range` must not be outside the range `buffer`.
|
|
||||||
///
|
|
||||||
/// For dynamic buffer bindings, `range` specifies the slice that is to be bound if the
|
|
||||||
/// dynamic offset were zero. When binding the descriptor set, the effective value of `range`
|
|
||||||
/// shifts forward by the offset that was provided. For example, if `range` is specified as
|
|
||||||
/// `0..8` when writing the descriptor set, and then when binding the descriptor set the
|
|
||||||
/// offset `16` is used, then the range of `buffer` that will actually be bound is `16..24`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn buffer_with_range(
|
pub fn buffer_with_range(binding: u32, buffer_info: DescriptorBufferInfo) -> Self {
|
||||||
binding: u32,
|
Self::buffer_with_range_array(binding, 0, [buffer_info])
|
||||||
buffer: Subbuffer<impl ?Sized>,
|
|
||||||
range: Range<DeviceSize>,
|
|
||||||
) -> Self {
|
|
||||||
Self::buffer_with_range_array(binding, 0, [(buffer, range)])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive buffer elements, specifying the ranges of the buffers to be
|
/// Write a number of consecutive buffer elements, specifying the ranges of the buffers to be
|
||||||
@ -122,12 +122,9 @@ impl WriteDescriptorSet {
|
|||||||
pub fn buffer_with_range_array(
|
pub fn buffer_with_range_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
elements: impl IntoIterator<Item = (Subbuffer<impl ?Sized>, Range<DeviceSize>)>,
|
elements: impl IntoIterator<Item = DescriptorBufferInfo>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let elements: SmallVec<_> = elements
|
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||||
.into_iter()
|
|
||||||
.map(|(buffer, range)| (buffer.into_bytes(), range))
|
|
||||||
.collect();
|
|
||||||
assert!(!elements.is_empty());
|
assert!(!elements.is_empty());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -151,6 +148,7 @@ impl WriteDescriptorSet {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||||
assert!(!elements.is_empty());
|
assert!(!elements.is_empty());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
binding,
|
binding,
|
||||||
first_array_element,
|
first_array_element,
|
||||||
@ -158,17 +156,53 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a single image view to array element 0.
|
/// Write a single image view to array element 0, using the `Undefined` image layout,
|
||||||
|
/// which will be automatically replaced with an appropriate default layout.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn image_view(binding: u32, image_view: Arc<dyn ImageViewAbstract>) -> Self {
|
pub fn image_view(binding: u32, image_view: Arc<dyn ImageViewAbstract>) -> Self {
|
||||||
Self::image_view_array(binding, 0, [image_view])
|
Self::image_view_with_layout_array(
|
||||||
|
binding,
|
||||||
|
0,
|
||||||
|
[DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: ImageLayout::Undefined,
|
||||||
|
}],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive image view elements.
|
/// Write a number of consecutive image view elements, using the `Undefined` image layout,
|
||||||
|
/// which will be automatically replaced with an appropriate default layout.
|
||||||
|
#[inline]
|
||||||
pub fn image_view_array(
|
pub fn image_view_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
elements: impl IntoIterator<Item = Arc<dyn ImageViewAbstract>>,
|
elements: impl IntoIterator<Item = Arc<dyn ImageViewAbstract>>,
|
||||||
|
) -> Self {
|
||||||
|
Self::image_view_with_layout_array(
|
||||||
|
binding,
|
||||||
|
first_array_element,
|
||||||
|
elements
|
||||||
|
.into_iter()
|
||||||
|
.map(|image_view| DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: ImageLayout::Undefined,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a single image view to array element 0, specifying the layout of the image to be
|
||||||
|
/// bound.
|
||||||
|
#[inline]
|
||||||
|
pub fn image_view_with_layout(binding: u32, image_view_info: DescriptorImageViewInfo) -> Self {
|
||||||
|
Self::image_view_with_layout_array(binding, 0, [image_view_info])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a number of consecutive image view elements, specifying the layouts of the images to
|
||||||
|
/// be bound.
|
||||||
|
pub fn image_view_with_layout_array(
|
||||||
|
binding: u32,
|
||||||
|
first_array_element: u32,
|
||||||
|
elements: impl IntoIterator<Item = DescriptorImageViewInfo>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||||
assert!(!elements.is_empty());
|
assert!(!elements.is_empty());
|
||||||
@ -179,24 +213,73 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a single image view and sampler to array element 0.
|
/// Write a single image view and sampler to array element 0,
|
||||||
|
/// using the `Undefined` image layout, which will be automatically replaced with
|
||||||
|
/// an appropriate default layout.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn image_view_sampler(
|
pub fn image_view_sampler(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
image_view: Arc<dyn ImageViewAbstract>,
|
image_view: Arc<dyn ImageViewAbstract>,
|
||||||
sampler: Arc<Sampler>,
|
sampler: Arc<Sampler>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::image_view_sampler_array(binding, 0, [(image_view, sampler)])
|
Self::image_view_with_layout_sampler_array(
|
||||||
|
binding,
|
||||||
|
0,
|
||||||
|
[(
|
||||||
|
DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: ImageLayout::Undefined,
|
||||||
|
},
|
||||||
|
sampler,
|
||||||
|
)],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive image view and sampler elements.
|
/// Write a number of consecutive image view and sampler elements,
|
||||||
|
/// using the `Undefined` image layout, which will be automatically replaced with
|
||||||
|
/// an appropriate default layout.
|
||||||
|
#[inline]
|
||||||
pub fn image_view_sampler_array(
|
pub fn image_view_sampler_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
elements: impl IntoIterator<Item = (Arc<dyn ImageViewAbstract>, Arc<Sampler>)>,
|
elements: impl IntoIterator<Item = (Arc<dyn ImageViewAbstract>, Arc<Sampler>)>,
|
||||||
|
) -> Self {
|
||||||
|
Self::image_view_with_layout_sampler_array(
|
||||||
|
binding,
|
||||||
|
first_array_element,
|
||||||
|
elements.into_iter().map(|(image_view, sampler)| {
|
||||||
|
(
|
||||||
|
DescriptorImageViewInfo {
|
||||||
|
image_view,
|
||||||
|
image_layout: ImageLayout::Undefined,
|
||||||
|
},
|
||||||
|
sampler,
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a single image view and sampler to array element 0, specifying the layout of the
|
||||||
|
/// image to be bound.
|
||||||
|
#[inline]
|
||||||
|
pub fn image_view_with_layout_sampler(
|
||||||
|
binding: u32,
|
||||||
|
image_view_info: DescriptorImageViewInfo,
|
||||||
|
sampler: Arc<Sampler>,
|
||||||
|
) -> Self {
|
||||||
|
Self::image_view_with_layout_sampler_array(binding, 0, [(image_view_info, sampler)])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a number of consecutive image view and sampler elements, specifying the layout of the
|
||||||
|
/// image to be bound.
|
||||||
|
pub fn image_view_with_layout_sampler_array(
|
||||||
|
binding: u32,
|
||||||
|
first_array_element: u32,
|
||||||
|
elements: impl IntoIterator<Item = (DescriptorImageViewInfo, Arc<Sampler>)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||||
assert!(!elements.is_empty());
|
assert!(!elements.is_empty());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
binding,
|
binding,
|
||||||
first_array_element,
|
first_array_element,
|
||||||
@ -218,6 +301,7 @@ impl WriteDescriptorSet {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||||
assert!(!elements.is_empty());
|
assert!(!elements.is_empty());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
binding,
|
binding,
|
||||||
first_array_element,
|
first_array_element,
|
||||||
@ -268,7 +352,9 @@ impl WriteDescriptorSet {
|
|||||||
DescriptorWriteInfo::Buffer(
|
DescriptorWriteInfo::Buffer(
|
||||||
elements
|
elements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(buffer, range)| {
|
.map(|buffer_info| {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
debug_assert!(!range.is_empty());
|
debug_assert!(!range.is_empty());
|
||||||
debug_assert!(range.end <= buffer.buffer().size());
|
debug_assert!(range.end <= buffer.buffer().size());
|
||||||
|
|
||||||
@ -305,14 +391,16 @@ impl WriteDescriptorSet {
|
|||||||
DescriptorWriteInfo::Image(
|
DescriptorWriteInfo::Image(
|
||||||
elements
|
elements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|image_view| {
|
.map(|image_view_info| {
|
||||||
let layouts = image_view.image().descriptor_layouts().expect(
|
let &DescriptorImageViewInfo {
|
||||||
"descriptor_layouts must return Some when used in an image view",
|
ref image_view,
|
||||||
);
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
ash::vk::DescriptorImageInfo {
|
ash::vk::DescriptorImageInfo {
|
||||||
sampler: ash::vk::Sampler::null(),
|
sampler: ash::vk::Sampler::null(),
|
||||||
image_view: image_view.handle(),
|
image_view: image_view.handle(),
|
||||||
image_layout: layouts.layout_for(descriptor_type).into(),
|
image_layout: image_layout.into(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -326,14 +414,16 @@ impl WriteDescriptorSet {
|
|||||||
DescriptorWriteInfo::Image(
|
DescriptorWriteInfo::Image(
|
||||||
elements
|
elements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(image_view, sampler)| {
|
.map(|(image_view_info, sampler)| {
|
||||||
let layouts = image_view.image().descriptor_layouts().expect(
|
let &DescriptorImageViewInfo {
|
||||||
"descriptor_layouts must return Some when used in an image view",
|
ref image_view,
|
||||||
);
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
ash::vk::DescriptorImageInfo {
|
ash::vk::DescriptorImageInfo {
|
||||||
sampler: sampler.handle(),
|
sampler: sampler.handle(),
|
||||||
image_view: image_view.handle(),
|
image_view: image_view.handle(),
|
||||||
image_layout: layouts.layout_for(descriptor_type).into(),
|
image_layout: image_layout.into(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -375,12 +465,13 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The elements held by a `WriteDescriptorSet`.
|
/// The elements held by a `WriteDescriptorSet`.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub enum WriteDescriptorSetElements {
|
pub enum WriteDescriptorSetElements {
|
||||||
None(u32),
|
None(u32),
|
||||||
Buffer(SmallVec<[(Subbuffer<[u8]>, Range<DeviceSize>); 1]>),
|
Buffer(SmallVec<[DescriptorBufferInfo; 1]>),
|
||||||
BufferView(SmallVec<[Arc<BufferView>; 1]>),
|
BufferView(SmallVec<[Arc<BufferView>; 1]>),
|
||||||
ImageView(SmallVec<[Arc<dyn ImageViewAbstract>; 1]>),
|
ImageView(SmallVec<[DescriptorImageViewInfo; 1]>),
|
||||||
ImageViewSampler(SmallVec<[(Arc<dyn ImageViewAbstract>, Arc<Sampler>); 1]>),
|
ImageViewSampler(SmallVec<[(DescriptorImageViewInfo, Arc<Sampler>); 1]>),
|
||||||
Sampler(SmallVec<[Arc<Sampler>; 1]>),
|
Sampler(SmallVec<[Arc<Sampler>; 1]>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +490,49 @@ impl WriteDescriptorSetElements {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parameters to write a buffer reference to a descriptor.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DescriptorBufferInfo {
|
||||||
|
/// The buffer to write to the descriptor.
|
||||||
|
pub buffer: Subbuffer<[u8]>,
|
||||||
|
|
||||||
|
/// The slice of bytes in `buffer` that will be made available to the shader.
|
||||||
|
/// `range` must not be outside the range `buffer`.
|
||||||
|
///
|
||||||
|
/// For dynamic buffer bindings, `range` specifies the slice that is to be bound if the
|
||||||
|
/// dynamic offset were zero. When binding the descriptor set, the effective value of `range`
|
||||||
|
/// shifts forward by the offset that was provided. For example, if `range` is specified as
|
||||||
|
/// `0..8` when writing the descriptor set, and then when binding the descriptor set the
|
||||||
|
/// offset `16` is used, then the range of `buffer` that will actually be bound is `16..24`.
|
||||||
|
pub range: Range<DeviceSize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parameters to write an image view reference to a descriptor.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DescriptorImageViewInfo {
|
||||||
|
/// The image view to write to the descriptor.
|
||||||
|
pub image_view: Arc<dyn ImageViewAbstract>,
|
||||||
|
|
||||||
|
/// The layout that the image is expected to be in when it's accessed in the shader.
|
||||||
|
///
|
||||||
|
/// Only certain layouts are allowed, depending on the type of descriptor.
|
||||||
|
///
|
||||||
|
/// For `SampledImage`, `CombinedImageSampler` and `InputAttachment`:
|
||||||
|
/// - `General`
|
||||||
|
/// - `ShaderReadOnlyOptimal`
|
||||||
|
/// - `DepthStencilReadOnlyOptimal`
|
||||||
|
/// - `DepthReadOnlyStencilAttachmentOptimal`
|
||||||
|
/// - `DepthAttachmentStencilReadOnlyOptimal`
|
||||||
|
///
|
||||||
|
/// For `StorageImage`:
|
||||||
|
/// - `General`
|
||||||
|
///
|
||||||
|
/// If the `Undefined` layout is provided, then it will be automatically replaced with
|
||||||
|
/// `General` for `StorageImage` descriptors, and with `ShaderReadOnlyOptimal` for any other
|
||||||
|
/// descriptor type.
|
||||||
|
pub image_layout: ImageLayout,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) enum DescriptorWriteInfo {
|
pub(crate) enum DescriptorWriteInfo {
|
||||||
Image(SmallVec<[ash::vk::DescriptorImageInfo; 1]>),
|
Image(SmallVec<[ash::vk::DescriptorImageInfo; 1]>),
|
||||||
@ -406,7 +540,52 @@ pub(crate) enum DescriptorWriteInfo {
|
|||||||
BufferView(SmallVec<[ash::vk::BufferView; 1]>),
|
BufferView(SmallVec<[ash::vk::BufferView; 1]>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn check_descriptor_write<'a>(
|
pub(crate) fn set_descriptor_write_image_layouts(
|
||||||
|
write: &mut WriteDescriptorSet,
|
||||||
|
layout: &DescriptorSetLayout,
|
||||||
|
) {
|
||||||
|
let default_layout = if let Some(layout_binding) = layout.bindings().get(&write.binding()) {
|
||||||
|
match layout_binding.descriptor_type {
|
||||||
|
DescriptorType::CombinedImageSampler
|
||||||
|
| DescriptorType::SampledImage
|
||||||
|
| DescriptorType::InputAttachment => ImageLayout::ShaderReadOnlyOptimal,
|
||||||
|
DescriptorType::StorageImage => ImageLayout::General,
|
||||||
|
_ => return,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
match &mut write.elements {
|
||||||
|
WriteDescriptorSetElements::ImageView(elements) => {
|
||||||
|
for image_view_info in elements {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view: _,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
|
if *image_layout == ImageLayout::Undefined {
|
||||||
|
*image_layout = default_layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteDescriptorSetElements::ImageViewSampler(elements) => {
|
||||||
|
for (image_view_info, _sampler) in elements {
|
||||||
|
let DescriptorImageViewInfo {
|
||||||
|
image_view: _,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
|
if *image_layout == ImageLayout::Undefined {
|
||||||
|
*image_layout = default_layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate_descriptor_write<'a>(
|
||||||
write: &WriteDescriptorSet,
|
write: &WriteDescriptorSet,
|
||||||
layout: &'a DescriptorSetLayout,
|
layout: &'a DescriptorSetLayout,
|
||||||
variable_descriptor_count: u32,
|
variable_descriptor_count: u32,
|
||||||
@ -512,7 +691,12 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, (image_view, sampler)) in elements.iter().enumerate() {
|
for (index, (image_view_info, sampler)) in elements.iter().enumerate() {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
assert_eq!(device, image_view.device());
|
assert_eq!(device, image_view.device());
|
||||||
assert_eq!(device, sampler.device());
|
assert_eq!(device, sampler.device());
|
||||||
|
|
||||||
@ -549,6 +733,21 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VUID-VkWriteDescriptorSet-descriptorType-04150
|
||||||
|
if !matches!(
|
||||||
|
image_layout,
|
||||||
|
ImageLayout::DepthStencilReadOnlyOptimal
|
||||||
|
| ImageLayout::ShaderReadOnlyOptimal
|
||||||
|
| ImageLayout::General
|
||||||
|
| ImageLayout::DepthReadOnlyStencilAttachmentOptimal
|
||||||
|
| ImageLayout::DepthAttachmentStencilReadOnlyOptimal,
|
||||||
|
) {
|
||||||
|
return Err(DescriptorSetUpdateError::ImageLayoutInvalid {
|
||||||
|
binding: write.binding(),
|
||||||
|
index: descriptor_range_start + index as u32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450
|
// VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450
|
||||||
if device.enabled_extensions().khr_portability_subset
|
if device.enabled_extensions().khr_portability_subset
|
||||||
&& !device.enabled_features().mutable_comparison_samplers
|
&& !device.enabled_features().mutable_comparison_samplers
|
||||||
@ -604,9 +803,14 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
let immutable_samplers = &layout_binding.immutable_samplers
|
let immutable_samplers = &layout_binding.immutable_samplers
|
||||||
[descriptor_range_start as usize..descriptor_range_end as usize];
|
[descriptor_range_start as usize..descriptor_range_end as usize];
|
||||||
|
|
||||||
for (index, (image_view, sampler)) in
|
for (index, (image_view_info, sampler)) in
|
||||||
elements.iter().zip(immutable_samplers).enumerate()
|
elements.iter().zip(immutable_samplers).enumerate()
|
||||||
{
|
{
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
assert_eq!(device, image_view.device());
|
assert_eq!(device, image_view.device());
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-00337
|
// VUID-VkWriteDescriptorSet-descriptorType-00337
|
||||||
@ -642,6 +846,21 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VUID-VkWriteDescriptorSet-descriptorType-04150
|
||||||
|
if !matches!(
|
||||||
|
image_layout,
|
||||||
|
ImageLayout::DepthStencilReadOnlyOptimal
|
||||||
|
| ImageLayout::ShaderReadOnlyOptimal
|
||||||
|
| ImageLayout::General
|
||||||
|
| ImageLayout::DepthReadOnlyStencilAttachmentOptimal
|
||||||
|
| ImageLayout::DepthAttachmentStencilReadOnlyOptimal,
|
||||||
|
) {
|
||||||
|
return Err(DescriptorSetUpdateError::ImageLayoutInvalid {
|
||||||
|
binding: write.binding(),
|
||||||
|
index: descriptor_range_start + index as u32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if let Err(error) = sampler.check_can_sample(image_view.as_ref()) {
|
if let Err(error) = sampler.check_can_sample(image_view.as_ref()) {
|
||||||
return Err(DescriptorSetUpdateError::ImageViewIncompatibleSampler {
|
return Err(DescriptorSetUpdateError::ImageViewIncompatibleSampler {
|
||||||
binding: write.binding(),
|
binding: write.binding(),
|
||||||
@ -664,7 +883,12 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, image_view) in elements.iter().enumerate() {
|
for (index, image_view_info) in elements.iter().enumerate() {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
assert_eq!(device, image_view.device());
|
assert_eq!(device, image_view.device());
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-00337
|
// VUID-VkWriteDescriptorSet-descriptorType-00337
|
||||||
@ -700,6 +924,21 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VUID-VkWriteDescriptorSet-descriptorType-04149
|
||||||
|
if !matches!(
|
||||||
|
image_layout,
|
||||||
|
ImageLayout::DepthStencilReadOnlyOptimal
|
||||||
|
| ImageLayout::ShaderReadOnlyOptimal
|
||||||
|
| ImageLayout::General
|
||||||
|
| ImageLayout::DepthReadOnlyStencilAttachmentOptimal
|
||||||
|
| ImageLayout::DepthAttachmentStencilReadOnlyOptimal,
|
||||||
|
) {
|
||||||
|
return Err(DescriptorSetUpdateError::ImageLayoutInvalid {
|
||||||
|
binding: write.binding(),
|
||||||
|
index: descriptor_range_start + index as u32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-01946
|
// VUID-VkWriteDescriptorSet-descriptorType-01946
|
||||||
if image_view.sampler_ycbcr_conversion().is_some() {
|
if image_view.sampler_ycbcr_conversion().is_some() {
|
||||||
return Err(
|
return Err(
|
||||||
@ -723,7 +962,12 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, image_view) in elements.iter().enumerate() {
|
for (index, image_view_info) in elements.iter().enumerate() {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
assert_eq!(device, image_view.device());
|
assert_eq!(device, image_view.device());
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-00339
|
// VUID-VkWriteDescriptorSet-descriptorType-00339
|
||||||
@ -759,6 +1003,14 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VUID-VkWriteDescriptorSet-descriptorType-04152
|
||||||
|
if !matches!(image_layout, ImageLayout::General) {
|
||||||
|
return Err(DescriptorSetUpdateError::ImageLayoutInvalid {
|
||||||
|
binding: write.binding(),
|
||||||
|
index: descriptor_range_start + index as u32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-00336
|
// VUID-VkWriteDescriptorSet-descriptorType-00336
|
||||||
if !image_view.component_mapping().is_identity() {
|
if !image_view.component_mapping().is_identity() {
|
||||||
return Err(DescriptorSetUpdateError::ImageViewNotIdentitySwizzled {
|
return Err(DescriptorSetUpdateError::ImageViewNotIdentitySwizzled {
|
||||||
@ -849,7 +1101,9 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, (buffer, range)) in elements.iter().enumerate() {
|
for (index, buffer_info) in elements.iter().enumerate() {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
assert_eq!(device, buffer.device());
|
assert_eq!(device, buffer.device());
|
||||||
|
|
||||||
if !buffer
|
if !buffer
|
||||||
@ -888,7 +1142,9 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, (buffer, range)) in elements.iter().enumerate() {
|
for (index, buffer_info) in elements.iter().enumerate() {
|
||||||
|
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||||
|
|
||||||
assert_eq!(device, buffer.device());
|
assert_eq!(device, buffer.device());
|
||||||
|
|
||||||
if !buffer
|
if !buffer
|
||||||
@ -927,7 +1183,12 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, image_view) in elements.iter().enumerate() {
|
for (index, image_view_info) in elements.iter().enumerate() {
|
||||||
|
let &DescriptorImageViewInfo {
|
||||||
|
ref image_view,
|
||||||
|
image_layout,
|
||||||
|
} = image_view_info;
|
||||||
|
|
||||||
assert_eq!(device, image_view.device());
|
assert_eq!(device, image_view.device());
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-00338
|
// VUID-VkWriteDescriptorSet-descriptorType-00338
|
||||||
@ -963,6 +1224,21 @@ pub(crate) fn check_descriptor_write<'a>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VUID-VkWriteDescriptorSet-descriptorType-04151
|
||||||
|
if !matches!(
|
||||||
|
image_layout,
|
||||||
|
ImageLayout::DepthStencilReadOnlyOptimal
|
||||||
|
| ImageLayout::ShaderReadOnlyOptimal
|
||||||
|
| ImageLayout::General
|
||||||
|
| ImageLayout::DepthReadOnlyStencilAttachmentOptimal
|
||||||
|
| ImageLayout::DepthAttachmentStencilReadOnlyOptimal,
|
||||||
|
) {
|
||||||
|
return Err(DescriptorSetUpdateError::ImageLayoutInvalid {
|
||||||
|
binding: write.binding(),
|
||||||
|
index: descriptor_range_start + index as u32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// VUID-VkWriteDescriptorSet-descriptorType-00336
|
// VUID-VkWriteDescriptorSet-descriptorType-00336
|
||||||
if !image_view.component_mapping().is_identity() {
|
if !image_view.component_mapping().is_identity() {
|
||||||
return Err(DescriptorSetUpdateError::ImageViewNotIdentitySwizzled {
|
return Err(DescriptorSetUpdateError::ImageViewNotIdentitySwizzled {
|
||||||
@ -1014,19 +1290,36 @@ pub enum DescriptorSetUpdateError {
|
|||||||
written_count: u32,
|
written_count: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ImageLayoutInvalid {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// Tried to write an image view with a 2D type and a 3D underlying image.
|
/// Tried to write an image view with a 2D type and a 3D underlying image.
|
||||||
ImageView2dFrom3d { binding: u32, index: u32 },
|
ImageView2dFrom3d {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// Tried to write an image view that has both the `depth` and `stencil` aspects.
|
/// Tried to write an image view that has both the `depth` and `stencil` aspects.
|
||||||
ImageViewDepthAndStencil { binding: u32, index: u32 },
|
ImageViewDepthAndStencil {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// Tried to write an image view with an attached sampler YCbCr conversion to a binding that
|
/// Tried to write an image view with an attached sampler YCbCr conversion to a binding that
|
||||||
/// does not support it.
|
/// does not support it.
|
||||||
ImageViewHasSamplerYcbcrConversion { binding: u32, index: u32 },
|
ImageViewHasSamplerYcbcrConversion {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// Tried to write an image view of an arrayed type to a descriptor type that does not support
|
/// Tried to write an image view of an arrayed type to a descriptor type that does not support
|
||||||
/// it.
|
/// it.
|
||||||
ImageViewIsArrayed { binding: u32, index: u32 },
|
ImageViewIsArrayed {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// Tried to write an image view that was not compatible with the sampler that was provided as
|
/// Tried to write an image view that was not compatible with the sampler that was provided as
|
||||||
/// part of the update or immutably in the layout.
|
/// part of the update or immutably in the layout.
|
||||||
@ -1038,7 +1331,10 @@ pub enum DescriptorSetUpdateError {
|
|||||||
|
|
||||||
/// Tried to write an image view to a descriptor type that requires it to be identity swizzled,
|
/// Tried to write an image view to a descriptor type that requires it to be identity swizzled,
|
||||||
/// but it was not.
|
/// but it was not.
|
||||||
ImageViewNotIdentitySwizzled { binding: u32, index: u32 },
|
ImageViewNotIdentitySwizzled {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// Tried to write an element type that was not compatible with the descriptor type in the
|
/// Tried to write an element type that was not compatible with the descriptor type in the
|
||||||
/// layout.
|
/// layout.
|
||||||
@ -1049,7 +1345,9 @@ pub enum DescriptorSetUpdateError {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/// Tried to write to a nonexistent binding.
|
/// Tried to write to a nonexistent binding.
|
||||||
InvalidBinding { binding: u32 },
|
InvalidBinding {
|
||||||
|
binding: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// A resource was missing a usage flag that was required.
|
/// A resource was missing a usage flag that was required.
|
||||||
MissingUsage {
|
MissingUsage {
|
||||||
@ -1067,7 +1365,10 @@ pub enum DescriptorSetUpdateError {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/// Tried to write a sampler that has an attached sampler YCbCr conversion.
|
/// Tried to write a sampler that has an attached sampler YCbCr conversion.
|
||||||
SamplerHasSamplerYcbcrConversion { binding: u32, index: u32 },
|
SamplerHasSamplerYcbcrConversion {
|
||||||
|
binding: u32,
|
||||||
|
index: u32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for DescriptorSetUpdateError {
|
impl Error for DescriptorSetUpdateError {
|
||||||
@ -1103,6 +1404,12 @@ impl Display for DescriptorSetUpdateError {
|
|||||||
available",
|
available",
|
||||||
written_count, binding, available_count,
|
written_count, binding, available_count,
|
||||||
),
|
),
|
||||||
|
Self::ImageLayoutInvalid { binding, index } => write!(
|
||||||
|
f,
|
||||||
|
"tried to write an image view to binding {} index {} with an image layout that is \
|
||||||
|
not valid for that descriptor type",
|
||||||
|
binding, index,
|
||||||
|
),
|
||||||
Self::ImageView2dFrom3d { binding, index } => write!(
|
Self::ImageView2dFrom3d { binding, index } => write!(
|
||||||
f,
|
f,
|
||||||
"tried to write an image view to binding {} index {} with a 2D type and a 3D \
|
"tried to write an image view to binding {} index {} with a 2D type and a 3D \
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
sys::{Image, ImageMemory, RawImage},
|
sys::{Image, ImageMemory, RawImage},
|
||||||
traits::ImageContent,
|
traits::ImageContent,
|
||||||
ImageAccess, ImageAspects, ImageDescriptorLayouts, ImageError, ImageLayout, ImageUsage,
|
ImageAccess, ImageAspects, ImageError, ImageLayout, ImageUsage, SampleCount,
|
||||||
SampleCount,
|
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
@ -603,16 +602,6 @@ unsafe impl ImageAccess for AttachmentImage {
|
|||||||
self.attachment_layout
|
self.attachment_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
Some(ImageDescriptorLayouts {
|
|
||||||
storage_image: ImageLayout::General,
|
|
||||||
combined_image_sampler: ImageLayout::ShaderReadOnlyOptimal,
|
|
||||||
sampled_image: ImageLayout::ShaderReadOnlyOptimal,
|
|
||||||
input_attachment: ImageLayout::ShaderReadOnlyOptimal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn layout_initialized(&self) {
|
unsafe fn layout_initialized(&self) {
|
||||||
self.layout_initialized.store(true, Ordering::SeqCst);
|
self.layout_initialized.store(true, Ordering::SeqCst);
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
use super::{
|
use super::{
|
||||||
sys::{Image, RawImage},
|
sys::{Image, RawImage},
|
||||||
traits::ImageContent,
|
traits::ImageContent,
|
||||||
ImageAccess, ImageCreateFlags, ImageDescriptorLayouts, ImageDimensions, ImageError,
|
ImageAccess, ImageCreateFlags, ImageDimensions, ImageError, ImageLayout,
|
||||||
ImageLayout, ImageSubresourceLayers, ImageUsage, MipmapsCount,
|
ImageSubresourceLayers, ImageUsage, MipmapsCount,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{Buffer, BufferContents, BufferCreateInfo, BufferError, BufferUsage, Subbuffer},
|
buffer::{Buffer, BufferContents, BufferCreateInfo, BufferError, BufferUsage, Subbuffer},
|
||||||
@ -331,16 +331,6 @@ unsafe impl ImageAccess for ImmutableImage {
|
|||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
Some(ImageDescriptorLayouts {
|
|
||||||
storage_image: ImageLayout::General,
|
|
||||||
combined_image_sampler: self.layout,
|
|
||||||
sampled_image: self.layout,
|
|
||||||
input_attachment: self.layout,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<P> ImageContent<P> for ImmutableImage {
|
unsafe impl<P> ImageContent<P> for ImmutableImage {
|
||||||
@ -391,11 +381,6 @@ unsafe impl ImageAccess for ImmutableImageInitialization {
|
|||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.image.layout
|
self.image.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for ImmutableImageInitialization {
|
impl PartialEq for ImmutableImageInitialization {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
// notice may not be copied, modified, or distributed except
|
// notice may not be copied, modified, or distributed except
|
||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use crate::{descriptor_set::layout::DescriptorType, macros::vulkan_enum};
|
use crate::macros::vulkan_enum;
|
||||||
|
|
||||||
vulkan_enum! {
|
vulkan_enum! {
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
@ -205,31 +205,3 @@ impl Default for ImageLayout {
|
|||||||
ImageLayout::Undefined
|
ImageLayout::Undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The set of layouts to use for an image when used in descriptor of various kinds.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub struct ImageDescriptorLayouts {
|
|
||||||
/// The image layout to use in a descriptor as a storage image.
|
|
||||||
pub storage_image: ImageLayout,
|
|
||||||
/// The image layout to use in a descriptor as a combined image sampler.
|
|
||||||
pub combined_image_sampler: ImageLayout,
|
|
||||||
/// The image layout to use in a descriptor as a sampled image.
|
|
||||||
pub sampled_image: ImageLayout,
|
|
||||||
/// The image layout to use in a descriptor as an input attachment.
|
|
||||||
pub input_attachment: ImageLayout,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ImageDescriptorLayouts {
|
|
||||||
/// Returns the layout for the given descriptor type. Panics if `descriptor_type` is not an
|
|
||||||
/// image descriptor type.
|
|
||||||
#[inline]
|
|
||||||
pub fn layout_for(&self, descriptor_type: DescriptorType) -> ImageLayout {
|
|
||||||
match descriptor_type {
|
|
||||||
DescriptorType::CombinedImageSampler => self.combined_image_sampler,
|
|
||||||
DescriptorType::SampledImage => self.sampled_image,
|
|
||||||
DescriptorType::StorageImage => self.storage_image,
|
|
||||||
DescriptorType::InputAttachment => self.input_attachment,
|
|
||||||
_ => panic!("{:?} is not an image descriptor type", descriptor_type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -50,7 +50,7 @@ pub use self::{
|
|||||||
aspect::{ImageAspect, ImageAspects},
|
aspect::{ImageAspect, ImageAspects},
|
||||||
attachment::AttachmentImage,
|
attachment::AttachmentImage,
|
||||||
immutable::ImmutableImage,
|
immutable::ImmutableImage,
|
||||||
layout::{ImageDescriptorLayouts, ImageLayout},
|
layout::ImageLayout,
|
||||||
storage::StorageImage,
|
storage::StorageImage,
|
||||||
swapchain::SwapchainImage,
|
swapchain::SwapchainImage,
|
||||||
sys::ImageError,
|
sys::ImageError,
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
use super::{
|
use super::{
|
||||||
sys::{Image, ImageMemory, RawImage},
|
sys::{Image, ImageMemory, RawImage},
|
||||||
traits::ImageContent,
|
traits::ImageContent,
|
||||||
ImageAccess, ImageAspects, ImageCreateFlags, ImageDescriptorLayouts, ImageDimensions,
|
ImageAccess, ImageAspects, ImageCreateFlags, ImageDimensions, ImageError, ImageLayout,
|
||||||
ImageError, ImageLayout, ImageUsage,
|
ImageUsage,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{Device, DeviceOwned, Queue},
|
device::{Device, DeviceOwned, Queue},
|
||||||
@ -491,16 +491,6 @@ unsafe impl ImageAccess for StorageImage {
|
|||||||
fn is_layout_initialized(&self) -> bool {
|
fn is_layout_initialized(&self) -> bool {
|
||||||
self.layout_initialized.load(Ordering::Relaxed)
|
self.layout_initialized.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
Some(ImageDescriptorLayouts {
|
|
||||||
storage_image: ImageLayout::General,
|
|
||||||
combined_image_sampler: ImageLayout::General,
|
|
||||||
sampled_image: ImageLayout::General,
|
|
||||||
input_attachment: ImageLayout::General,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<P> ImageContent<P> for StorageImage {
|
unsafe impl<P> ImageContent<P> for StorageImage {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
sys::{Image, ImageMemory},
|
sys::{Image, ImageMemory},
|
||||||
traits::ImageContent,
|
traits::ImageContent,
|
||||||
ImageAccess, ImageDescriptorLayouts, ImageLayout,
|
ImageAccess, ImageLayout,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
@ -82,15 +82,6 @@ unsafe impl ImageAccess for SwapchainImage {
|
|||||||
ImageLayout::PresentSrc
|
ImageLayout::PresentSrc
|
||||||
}
|
}
|
||||||
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
Some(ImageDescriptorLayouts {
|
|
||||||
storage_image: ImageLayout::General,
|
|
||||||
combined_image_sampler: ImageLayout::ShaderReadOnlyOptimal,
|
|
||||||
sampled_image: ImageLayout::ShaderReadOnlyOptimal,
|
|
||||||
input_attachment: ImageLayout::ShaderReadOnlyOptimal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn layout_initialized(&self) {
|
unsafe fn layout_initialized(&self) {
|
||||||
match self.inner.memory() {
|
match self.inner.memory() {
|
||||||
&ImageMemory::Swapchain {
|
&ImageMemory::Swapchain {
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
sys::Image, ImageAspects, ImageDescriptorLayouts, ImageDimensions, ImageLayout,
|
sys::Image, ImageAspects, ImageDimensions, ImageLayout, ImageSubresourceLayers,
|
||||||
ImageSubresourceLayers, ImageSubresourceRange, ImageUsage, SampleCount,
|
ImageSubresourceRange, ImageUsage, SampleCount,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
@ -149,12 +149,6 @@ pub unsafe trait ImageAccess: DeviceOwned + Send + Sync {
|
|||||||
preinitialized,
|
preinitialized,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an [`ImageDescriptorLayouts`] structure specifying the image layout to use
|
|
||||||
/// in descriptors of various kinds.
|
|
||||||
///
|
|
||||||
/// This must return `Some` if the image is to be used to create an image view.
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for dyn ImageAccess {
|
impl Debug for dyn ImageAccess {
|
||||||
@ -216,10 +210,6 @@ where
|
|||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.image.final_layout_requirement()
|
self.image.final_layout_requirement()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
self.image.descriptor_layouts()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> PartialEq for ImageAccessFromUndefinedLayout<I>
|
impl<I> PartialEq for ImageAccessFromUndefinedLayout<I>
|
||||||
@ -264,10 +254,6 @@ where
|
|||||||
(**self).final_layout_requirement()
|
(**self).final_layout_requirement()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
|
||||||
(**self).descriptor_layouts()
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn layout_initialized(&self) {
|
unsafe fn layout_initialized(&self) {
|
||||||
(**self).layout_initialized();
|
(**self).layout_initialized();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user