mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +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,
|
||||
},
|
||||
descriptor_set::{
|
||||
allocator::StandardDescriptorSetAllocator, layout::DescriptorType, DescriptorSet,
|
||||
PersistentDescriptorSet, WriteDescriptorSet,
|
||||
allocator::StandardDescriptorSetAllocator, layout::DescriptorType, DescriptorBufferInfo,
|
||||
DescriptorSet, PersistentDescriptorSet, WriteDescriptorSet,
|
||||
},
|
||||
device::{
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
@ -226,8 +226,10 @@ fn main() {
|
||||
// this range.
|
||||
WriteDescriptorSet::buffer_with_range(
|
||||
0,
|
||||
input_buffer,
|
||||
0..size_of::<cs::InData>() as DeviceSize,
|
||||
DescriptorBufferInfo {
|
||||
buffer: input_buffer,
|
||||
range: 0..size_of::<cs::InData>() as DeviceSize,
|
||||
},
|
||||
),
|
||||
WriteDescriptorSet::buffer(1, output_buffer.clone()),
|
||||
],
|
||||
|
@ -17,10 +17,10 @@ use crate::{
|
||||
AutoCommandBufferBuilder,
|
||||
},
|
||||
descriptor_set::{
|
||||
check_descriptor_write, layout::DescriptorType, sys::UnsafeDescriptorSet,
|
||||
DescriptorBindingResources, DescriptorSetResources, DescriptorSetUpdateError,
|
||||
DescriptorSetWithOffsets, DescriptorSetsCollection, DescriptorWriteInfo,
|
||||
WriteDescriptorSet,
|
||||
layout::DescriptorType, set_descriptor_write_image_layouts, sys::UnsafeDescriptorSet,
|
||||
validate_descriptor_write, DescriptorBindingResources, DescriptorBufferInfo,
|
||||
DescriptorSetResources, DescriptorSetUpdateError, DescriptorSetWithOffsets,
|
||||
DescriptorSetsCollection, DescriptorWriteInfo, WriteDescriptorSet,
|
||||
},
|
||||
device::{DeviceOwned, QueueFlags},
|
||||
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
|
||||
if offset as DeviceSize + range.end > buffer.size() {
|
||||
return Err(BindPushError::DynamicOffsetOutOfBufferBounds {
|
||||
@ -623,7 +625,15 @@ where
|
||||
set_num: u32,
|
||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||
) -> &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(
|
||||
pipeline_bind_point,
|
||||
&pipeline_layout,
|
||||
@ -706,7 +716,7 @@ where
|
||||
}
|
||||
|
||||
for write in descriptor_writes {
|
||||
check_descriptor_write(write, descriptor_set_layout, 0)?;
|
||||
validate_descriptor_write(write, descriptor_set_layout, 0)?;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// 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(
|
||||
pipeline_bind_point,
|
||||
pipeline_layout.clone(),
|
||||
@ -1213,12 +1230,15 @@ impl UnsafeCommandBufferBuilder {
|
||||
descriptor_writes: impl IntoIterator<Item = &'a WriteDescriptorSet>,
|
||||
) {
|
||||
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()
|
||||
.map(|write| {
|
||||
let binding =
|
||||
&pipeline_layout.set_layouts()[set_num as usize].bindings()[&write.binding()];
|
||||
let mut write = write.clone(); // Ew!
|
||||
set_descriptor_write_image_layouts(&mut write, set_layout);
|
||||
|
||||
let binding = &set_layout.bindings()[&write.binding()];
|
||||
|
||||
(
|
||||
write.to_vulkan_info(binding.descriptor_type),
|
||||
@ -1227,28 +1247,28 @@ impl UnsafeCommandBufferBuilder {
|
||||
})
|
||||
.unzip();
|
||||
|
||||
if writes.is_empty() {
|
||||
if writes_vk.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the info pointers separately.
|
||||
for (info, write) in infos.iter().zip(writes.iter_mut()) {
|
||||
match info {
|
||||
for (info_vk, write_vk) in infos_vk.iter().zip(writes_vk.iter_mut()) {
|
||||
match info_vk {
|
||||
DescriptorWriteInfo::Image(info) => {
|
||||
write.descriptor_count = info.len() as u32;
|
||||
write.p_image_info = info.as_ptr();
|
||||
write_vk.descriptor_count = info.len() as u32;
|
||||
write_vk.p_image_info = info.as_ptr();
|
||||
}
|
||||
DescriptorWriteInfo::Buffer(info) => {
|
||||
write.descriptor_count = info.len() as u32;
|
||||
write.p_buffer_info = info.as_ptr();
|
||||
write_vk.descriptor_count = info.len() as u32;
|
||||
write_vk.p_buffer_info = info.as_ptr();
|
||||
}
|
||||
DescriptorWriteInfo::BufferView(info) => {
|
||||
write.descriptor_count = info.len() as u32;
|
||||
write.p_texel_buffer_view = info.as_ptr();
|
||||
write_vk.descriptor_count = info.len() as u32;
|
||||
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();
|
||||
@ -1258,8 +1278,8 @@ impl UnsafeCommandBufferBuilder {
|
||||
pipeline_bind_point.into(),
|
||||
pipeline_layout.handle(),
|
||||
set_num,
|
||||
writes.len() as u32,
|
||||
writes.as_ptr(),
|
||||
writes_vk.len() as u32,
|
||||
writes_vk.as_ptr(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,15 @@ use crate::{
|
||||
AutoCommandBufferBuilder, DispatchIndirectCommand, DrawIndexedIndirectCommand,
|
||||
DrawIndirectCommand, ResourceInCommand, ResourceUseRef, SubpassContents,
|
||||
},
|
||||
descriptor_set::{layout::DescriptorType, DescriptorBindingResources},
|
||||
descriptor_set::{
|
||||
layout::DescriptorType, DescriptorBindingResources, DescriptorBufferInfo,
|
||||
DescriptorImageViewInfo,
|
||||
},
|
||||
device::{DeviceOwned, QueueFlags},
|
||||
format::{Format, FormatFeatures},
|
||||
image::{
|
||||
view::ImageViewType, ImageAccess, ImageAspects, ImageSubresourceRange, ImageViewAbstract,
|
||||
SampleCount,
|
||||
view::ImageViewType, ImageAccess, ImageAspects, ImageLayout, ImageSubresourceRange,
|
||||
ImageViewAbstract, SampleCount,
|
||||
},
|
||||
pipeline::{
|
||||
graphics::{
|
||||
@ -642,8 +645,7 @@ where
|
||||
let layout_binding =
|
||||
&pipeline.layout().set_layouts()[set_num as usize].bindings()[&binding_num];
|
||||
|
||||
let check_buffer =
|
||||
|_index: u32, (_buffer, _range): &(Subbuffer<[u8]>, Range<DeviceSize>)| Ok(());
|
||||
let check_buffer = |_index: u32, _buffer_info: &DescriptorBufferInfo| Ok(());
|
||||
|
||||
let check_buffer_view = |index: u32, buffer_view: &Arc<BufferView>| {
|
||||
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter())
|
||||
@ -840,7 +842,12 @@ where
|
||||
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)?;
|
||||
|
||||
if let Some(sampler) = layout_binding.immutable_samplers.get(index as usize) {
|
||||
@ -850,13 +857,21 @@ where
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let check_image_view_sampler =
|
||||
|index: u32, (image_view, sampler): &(Arc<dyn ImageViewAbstract>, Arc<Sampler>)| {
|
||||
check_image_view_common(index, image_view)?;
|
||||
check_sampler_common(index, sampler)?;
|
||||
let check_image_view_sampler = |index: u32,
|
||||
(image_view_info, sampler): &(
|
||||
DescriptorImageViewInfo,
|
||||
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>| {
|
||||
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()) {
|
||||
return Err(
|
||||
DescriptorResourceInvalidError::SamplerImageViewIncompatible {
|
||||
@ -2101,16 +2121,12 @@ impl SyncCommandBufferBuilder {
|
||||
)
|
||||
})
|
||||
};
|
||||
let image_resource = |(index, image, subresource_range): (
|
||||
let image_resource = |(index, image, layout, subresource_range): (
|
||||
u32,
|
||||
Arc<dyn ImageAccess>,
|
||||
ImageLayout,
|
||||
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| {
|
||||
(
|
||||
ResourceUseRef {
|
||||
@ -2147,7 +2163,9 @@ impl SyncCommandBufferBuilder {
|
||||
resources.extend(
|
||||
(elements.iter().enumerate())
|
||||
.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;
|
||||
|
||||
(
|
||||
@ -2164,7 +2182,8 @@ impl SyncCommandBufferBuilder {
|
||||
resources.extend(
|
||||
(elements.iter().enumerate())
|
||||
.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())
|
||||
})
|
||||
})
|
||||
@ -2191,10 +2210,16 @@ impl SyncCommandBufferBuilder {
|
||||
resources.extend(
|
||||
(elements.iter().enumerate())
|
||||
.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,
|
||||
image_view.image(),
|
||||
image_layout,
|
||||
image_view.subresource_range().clone(),
|
||||
)
|
||||
})
|
||||
@ -2206,10 +2231,16 @@ impl SyncCommandBufferBuilder {
|
||||
resources.extend(
|
||||
(elements.iter().enumerate())
|
||||
.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,
|
||||
image_view.image(),
|
||||
image_layout,
|
||||
image_view.subresource_range().clone(),
|
||||
)
|
||||
})
|
||||
|
@ -12,9 +12,10 @@ use crate::{
|
||||
buffer::{BufferContents, BufferUsage, Subbuffer},
|
||||
command_buffer::{allocator::CommandBufferAllocator, commands::bind_push::BindPushError},
|
||||
descriptor_set::{
|
||||
check_descriptor_write, layout::DescriptorType, DescriptorBindingResources,
|
||||
DescriptorSetResources, DescriptorSetWithOffsets, DescriptorSetsCollection,
|
||||
DescriptorWriteInfo, WriteDescriptorSet,
|
||||
layout::DescriptorType, set_descriptor_write_image_layouts, validate_descriptor_write,
|
||||
DescriptorBindingResources, DescriptorBufferInfo, DescriptorSetResources,
|
||||
DescriptorSetWithOffsets, DescriptorSetsCollection, DescriptorWriteInfo,
|
||||
WriteDescriptorSet,
|
||||
},
|
||||
device::{DeviceOwned, QueueFlags},
|
||||
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
|
||||
if offset as DeviceSize + range.end > buffer.size() {
|
||||
return Err(BindPushError::DynamicOffsetOutOfBufferBounds {
|
||||
@ -761,7 +764,15 @@ where
|
||||
set_num: u32,
|
||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||
) -> &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(
|
||||
pipeline_bind_point,
|
||||
&pipeline_layout,
|
||||
@ -842,7 +853,7 @@ where
|
||||
}
|
||||
|
||||
for write in descriptor_writes {
|
||||
check_descriptor_write(write, descriptor_set_layout, 0)?;
|
||||
validate_descriptor_write(write, descriptor_set_layout, 0)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -856,16 +867,17 @@ where
|
||||
set_num: u32,
|
||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||
) -> &mut Self {
|
||||
let descriptor_writes: SmallVec<[WriteDescriptorSet; 8]> =
|
||||
let mut descriptor_writes: SmallVec<[WriteDescriptorSet; 8]> =
|
||||
descriptor_writes.into_iter().collect();
|
||||
|
||||
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
|
||||
.iter()
|
||||
let (infos_vk, mut writes_vk): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = descriptor_writes
|
||||
.iter_mut()
|
||||
.map(|write| {
|
||||
let binding =
|
||||
&pipeline_layout.set_layouts()[set_num as usize].bindings()[&write.binding()];
|
||||
set_descriptor_write_image_layouts(write, set_layout);
|
||||
let binding = &set_layout.bindings()[&write.binding()];
|
||||
|
||||
(
|
||||
write.to_vulkan_info(binding.descriptor_type),
|
||||
@ -874,28 +886,28 @@ where
|
||||
})
|
||||
.unzip();
|
||||
|
||||
if writes.is_empty() {
|
||||
if writes_vk.is_empty() {
|
||||
return self;
|
||||
}
|
||||
|
||||
// Set the info pointers separately.
|
||||
for (info, write) in infos.iter().zip(writes.iter_mut()) {
|
||||
match info {
|
||||
for (info_vk, write_vk) in infos_vk.iter().zip(writes_vk.iter_mut()) {
|
||||
match info_vk {
|
||||
DescriptorWriteInfo::Image(info) => {
|
||||
write.descriptor_count = info.len() as u32;
|
||||
write.p_image_info = info.as_ptr();
|
||||
write_vk.descriptor_count = info.len() as u32;
|
||||
write_vk.p_image_info = info.as_ptr();
|
||||
}
|
||||
DescriptorWriteInfo::Buffer(info) => {
|
||||
write.descriptor_count = info.len() as u32;
|
||||
write.p_buffer_info = info.as_ptr();
|
||||
write_vk.descriptor_count = info.len() as u32;
|
||||
write_vk.p_buffer_info = info.as_ptr();
|
||||
}
|
||||
DescriptorWriteInfo::BufferView(info) => {
|
||||
write.descriptor_count = info.len() as u32;
|
||||
write.p_texel_buffer_view = info.as_ptr();
|
||||
write_vk.descriptor_count = info.len() as u32;
|
||||
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();
|
||||
@ -904,8 +916,8 @@ where
|
||||
pipeline_bind_point.into(),
|
||||
pipeline_layout.handle(),
|
||||
set_num,
|
||||
writes.len() as u32,
|
||||
writes.as_ptr(),
|
||||
writes_vk.len() as u32,
|
||||
writes_vk.as_ptr(),
|
||||
);
|
||||
|
||||
let state = self.builder_state.invalidate_descriptor_sets(
|
||||
|
@ -18,7 +18,10 @@ use crate::{
|
||||
DispatchIndirectCommand, DrawIndexedIndirectCommand, DrawIndirectCommand,
|
||||
ResourceInCommand, ResourceUseRef, SubpassContents,
|
||||
},
|
||||
descriptor_set::{layout::DescriptorType, DescriptorBindingResources},
|
||||
descriptor_set::{
|
||||
layout::DescriptorType, DescriptorBindingResources, DescriptorBufferInfo,
|
||||
DescriptorImageViewInfo,
|
||||
},
|
||||
device::{DeviceOwned, QueueFlags},
|
||||
format::FormatFeatures,
|
||||
image::{ImageAccess, ImageAspects, ImageSubresourceRange, ImageViewAbstract, SampleCount},
|
||||
@ -40,7 +43,7 @@ use crate::{
|
||||
DeviceSize, RequiresOneOf, VulkanObject,
|
||||
};
|
||||
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>
|
||||
where
|
||||
@ -991,8 +994,7 @@ where
|
||||
let layout_binding =
|
||||
&pipeline.layout().set_layouts()[set_num as usize].bindings()[&binding_num];
|
||||
|
||||
let check_buffer =
|
||||
|_index: u32, (_buffer, _range): &(Subbuffer<[u8]>, Range<DeviceSize>)| Ok(());
|
||||
let check_buffer = |_index: u32, _info: &DescriptorBufferInfo| Ok(());
|
||||
|
||||
let check_buffer_view = |index: u32, buffer_view: &Arc<BufferView>| {
|
||||
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter())
|
||||
@ -1189,7 +1191,12 @@ where
|
||||
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)?;
|
||||
|
||||
if let Some(sampler) = layout_binding.immutable_samplers.get(index as usize) {
|
||||
@ -1199,13 +1206,21 @@ where
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let check_image_view_sampler =
|
||||
|index: u32, (image_view, sampler): &(Arc<dyn ImageViewAbstract>, Arc<Sampler>)| {
|
||||
check_image_view_common(index, image_view)?;
|
||||
check_sampler_common(index, sampler)?;
|
||||
let check_image_view_sampler = |index: u32,
|
||||
(image_view_info, sampler): &(
|
||||
DescriptorImageViewInfo,
|
||||
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>| {
|
||||
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()) {
|
||||
return Err(
|
||||
DescriptorResourceInvalidError::SamplerImageViewIncompatible {
|
||||
@ -2065,7 +2085,9 @@ fn record_descriptor_sets_access(
|
||||
let dynamic_offsets = descriptor_set_state.dynamic_offsets();
|
||||
|
||||
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 (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||
|
||||
@ -2085,7 +2107,9 @@ fn record_descriptor_sets_access(
|
||||
}
|
||||
} else {
|
||||
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 mut range = range.clone();
|
||||
@ -2127,15 +2151,14 @@ fn record_descriptor_sets_access(
|
||||
}
|
||||
DescriptorBindingResources::ImageView(elements) => {
|
||||
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_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);
|
||||
|
||||
for stage_access in stage_access_iter {
|
||||
@ -2144,7 +2167,7 @@ fn record_descriptor_sets_access(
|
||||
image_inner,
|
||||
image_view.subresource_range().clone(),
|
||||
stage_access,
|
||||
layout,
|
||||
image_layout,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2152,15 +2175,14 @@ fn record_descriptor_sets_access(
|
||||
}
|
||||
DescriptorBindingResources::ImageViewSampler(elements) => {
|
||||
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_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);
|
||||
|
||||
for stage_access in stage_access_iter {
|
||||
@ -2169,7 +2191,7 @@ fn record_descriptor_sets_access(
|
||||
image_inner,
|
||||
image_view.subresource_range().clone(),
|
||||
stage_access,
|
||||
layout,
|
||||
image_layout,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -78,20 +78,21 @@
|
||||
//! [`DescriptorSetAllocator`]: allocator::DescriptorSetAllocator
|
||||
//! [`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::{
|
||||
collection::DescriptorSetsCollection,
|
||||
persistent::PersistentDescriptorSet,
|
||||
update::{DescriptorSetUpdateError, WriteDescriptorSet, WriteDescriptorSetElements},
|
||||
update::{
|
||||
DescriptorBufferInfo, DescriptorImageViewInfo, DescriptorSetUpdateError,
|
||||
WriteDescriptorSet, WriteDescriptorSetElements,
|
||||
},
|
||||
};
|
||||
use self::{layout::DescriptorSetLayout, sys::UnsafeDescriptorSet};
|
||||
use crate::{
|
||||
buffer::{view::BufferView, Subbuffer},
|
||||
descriptor_set::layout::DescriptorType,
|
||||
device::DeviceOwned,
|
||||
image::view::ImageViewAbstract,
|
||||
sampler::Sampler,
|
||||
DeviceSize, OomError, VulkanObject,
|
||||
buffer::view::BufferView, descriptor_set::layout::DescriptorType, device::DeviceOwned,
|
||||
sampler::Sampler, OomError, VulkanObject,
|
||||
};
|
||||
use ahash::HashMap;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@ -99,7 +100,6 @@ use std::{
|
||||
error::Error,
|
||||
fmt::{Display, Error as FmtError, Formatter},
|
||||
hash::{Hash, Hasher},
|
||||
ops::Range,
|
||||
ptr,
|
||||
sync::Arc,
|
||||
};
|
||||
@ -188,22 +188,24 @@ impl DescriptorSetInner {
|
||||
|
||||
let descriptor_writes = descriptor_writes.into_iter();
|
||||
let (lower_size_bound, _) = descriptor_writes.size_hint();
|
||||
let mut descriptor_write_info: SmallVec<[_; 8]> = SmallVec::with_capacity(lower_size_bound);
|
||||
let mut write_descriptor_set: SmallVec<[_; 8]> = SmallVec::with_capacity(lower_size_bound);
|
||||
let mut descriptor_write_infos_vk: SmallVec<[_; 8]> =
|
||||
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 =
|
||||
check_descriptor_write(&write, &layout, variable_descriptor_count)?;
|
||||
validate_descriptor_write(&write, &layout, variable_descriptor_count)?;
|
||||
|
||||
resources.update(&write);
|
||||
descriptor_write_info.push(write.to_vulkan_info(layout_binding.descriptor_type));
|
||||
write_descriptor_set.push(write.to_vulkan(handle, layout_binding.descriptor_type));
|
||||
descriptor_write_infos_vk.push(write.to_vulkan_info(layout_binding.descriptor_type));
|
||||
descriptor_writes_vk.push(write.to_vulkan(handle, layout_binding.descriptor_type));
|
||||
}
|
||||
|
||||
if !write_descriptor_set.is_empty() {
|
||||
for (info, write) in descriptor_write_info
|
||||
if !descriptor_writes_vk.is_empty() {
|
||||
for (info, write) in descriptor_write_infos_vk
|
||||
.iter()
|
||||
.zip(write_descriptor_set.iter_mut())
|
||||
.zip(descriptor_writes_vk.iter_mut())
|
||||
{
|
||||
match info {
|
||||
DescriptorWriteInfo::Image(info) => {
|
||||
@ -227,8 +229,8 @@ impl DescriptorSetInner {
|
||||
|
||||
(fns.v1_0.update_descriptor_sets)(
|
||||
layout.device().handle(),
|
||||
write_descriptor_set.len() as u32,
|
||||
write_descriptor_set.as_ptr(),
|
||||
descriptor_writes_vk.len() as u32,
|
||||
descriptor_writes_vk.as_ptr(),
|
||||
0,
|
||||
ptr::null(),
|
||||
);
|
||||
@ -342,10 +344,10 @@ impl DescriptorSetResources {
|
||||
#[derive(Clone)]
|
||||
pub enum DescriptorBindingResources {
|
||||
None(Elements<()>),
|
||||
Buffer(Elements<(Subbuffer<[u8]>, Range<DeviceSize>)>),
|
||||
Buffer(Elements<DescriptorBufferInfo>),
|
||||
BufferView(Elements<Arc<BufferView>>),
|
||||
ImageView(Elements<Arc<dyn ImageViewAbstract>>),
|
||||
ImageViewSampler(Elements<(Arc<dyn ImageViewAbstract>, Arc<Sampler>)>),
|
||||
ImageView(Elements<DescriptorImageViewInfo>),
|
||||
ImageViewSampler(Elements<(DescriptorImageViewInfo, Arc<Sampler>)>),
|
||||
Sampler(Elements<Arc<Sampler>>),
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,9 @@ use super::layout::{DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorT
|
||||
use crate::{
|
||||
buffer::{view::BufferView, BufferUsage, Subbuffer},
|
||||
device::DeviceOwned,
|
||||
image::{view::ImageViewType, ImageAspects, ImageType, ImageUsage, ImageViewAbstract},
|
||||
image::{
|
||||
view::ImageViewType, ImageAspects, ImageLayout, ImageType, ImageUsage, ImageViewAbstract,
|
||||
},
|
||||
sampler::{Sampler, SamplerImageViewIncompatibleError},
|
||||
DeviceSize, RequiresOneOf, VulkanObject,
|
||||
};
|
||||
@ -33,10 +35,11 @@ use std::{
|
||||
/// 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.
|
||||
/// At least one element must be provided; a panic results if the provided iterator is empty.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WriteDescriptorSet {
|
||||
binding: u32,
|
||||
first_array_element: u32,
|
||||
elements: WriteDescriptorSetElements,
|
||||
pub(crate) elements: WriteDescriptorSetElements, // public so that the image layouts can be changed
|
||||
}
|
||||
|
||||
impl WriteDescriptorSet {
|
||||
@ -74,7 +77,14 @@ impl WriteDescriptorSet {
|
||||
#[inline]
|
||||
pub fn buffer(binding: u32, buffer: Subbuffer<impl ?Sized>) -> Self {
|
||||
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.
|
||||
@ -91,28 +101,18 @@ impl WriteDescriptorSet {
|
||||
first_array_element,
|
||||
elements.into_iter().map(|buffer| {
|
||||
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.
|
||||
///
|
||||
/// `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]
|
||||
pub fn buffer_with_range(
|
||||
binding: u32,
|
||||
buffer: Subbuffer<impl ?Sized>,
|
||||
range: Range<DeviceSize>,
|
||||
) -> Self {
|
||||
Self::buffer_with_range_array(binding, 0, [(buffer, range)])
|
||||
pub fn buffer_with_range(binding: u32, buffer_info: DescriptorBufferInfo) -> Self {
|
||||
Self::buffer_with_range_array(binding, 0, [buffer_info])
|
||||
}
|
||||
|
||||
/// 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(
|
||||
binding: u32,
|
||||
first_array_element: u32,
|
||||
elements: impl IntoIterator<Item = (Subbuffer<impl ?Sized>, Range<DeviceSize>)>,
|
||||
elements: impl IntoIterator<Item = DescriptorBufferInfo>,
|
||||
) -> Self {
|
||||
let elements: SmallVec<_> = elements
|
||||
.into_iter()
|
||||
.map(|(buffer, range)| (buffer.into_bytes(), range))
|
||||
.collect();
|
||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||
assert!(!elements.is_empty());
|
||||
|
||||
Self {
|
||||
@ -151,6 +148,7 @@ impl WriteDescriptorSet {
|
||||
) -> Self {
|
||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||
assert!(!elements.is_empty());
|
||||
|
||||
Self {
|
||||
binding,
|
||||
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]
|
||||
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(
|
||||
binding: u32,
|
||||
first_array_element: u32,
|
||||
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 {
|
||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||
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]
|
||||
pub fn image_view_sampler(
|
||||
binding: u32,
|
||||
image_view: Arc<dyn ImageViewAbstract>,
|
||||
sampler: Arc<Sampler>,
|
||||
) -> 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(
|
||||
binding: u32,
|
||||
first_array_element: u32,
|
||||
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 {
|
||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||
assert!(!elements.is_empty());
|
||||
|
||||
Self {
|
||||
binding,
|
||||
first_array_element,
|
||||
@ -218,6 +301,7 @@ impl WriteDescriptorSet {
|
||||
) -> Self {
|
||||
let elements: SmallVec<_> = elements.into_iter().collect();
|
||||
assert!(!elements.is_empty());
|
||||
|
||||
Self {
|
||||
binding,
|
||||
first_array_element,
|
||||
@ -268,7 +352,9 @@ impl WriteDescriptorSet {
|
||||
DescriptorWriteInfo::Buffer(
|
||||
elements
|
||||
.iter()
|
||||
.map(|(buffer, range)| {
|
||||
.map(|buffer_info| {
|
||||
let DescriptorBufferInfo { buffer, range } = buffer_info;
|
||||
|
||||
debug_assert!(!range.is_empty());
|
||||
debug_assert!(range.end <= buffer.buffer().size());
|
||||
|
||||
@ -305,14 +391,16 @@ impl WriteDescriptorSet {
|
||||
DescriptorWriteInfo::Image(
|
||||
elements
|
||||
.iter()
|
||||
.map(|image_view| {
|
||||
let layouts = image_view.image().descriptor_layouts().expect(
|
||||
"descriptor_layouts must return Some when used in an image view",
|
||||
);
|
||||
.map(|image_view_info| {
|
||||
let &DescriptorImageViewInfo {
|
||||
ref image_view,
|
||||
image_layout,
|
||||
} = image_view_info;
|
||||
|
||||
ash::vk::DescriptorImageInfo {
|
||||
sampler: ash::vk::Sampler::null(),
|
||||
image_view: image_view.handle(),
|
||||
image_layout: layouts.layout_for(descriptor_type).into(),
|
||||
image_layout: image_layout.into(),
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
@ -326,14 +414,16 @@ impl WriteDescriptorSet {
|
||||
DescriptorWriteInfo::Image(
|
||||
elements
|
||||
.iter()
|
||||
.map(|(image_view, sampler)| {
|
||||
let layouts = image_view.image().descriptor_layouts().expect(
|
||||
"descriptor_layouts must return Some when used in an image view",
|
||||
);
|
||||
.map(|(image_view_info, sampler)| {
|
||||
let &DescriptorImageViewInfo {
|
||||
ref image_view,
|
||||
image_layout,
|
||||
} = image_view_info;
|
||||
|
||||
ash::vk::DescriptorImageInfo {
|
||||
sampler: sampler.handle(),
|
||||
image_view: image_view.handle(),
|
||||
image_layout: layouts.layout_for(descriptor_type).into(),
|
||||
image_layout: image_layout.into(),
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
@ -375,12 +465,13 @@ impl WriteDescriptorSet {
|
||||
}
|
||||
|
||||
/// The elements held by a `WriteDescriptorSet`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum WriteDescriptorSetElements {
|
||||
None(u32),
|
||||
Buffer(SmallVec<[(Subbuffer<[u8]>, Range<DeviceSize>); 1]>),
|
||||
Buffer(SmallVec<[DescriptorBufferInfo; 1]>),
|
||||
BufferView(SmallVec<[Arc<BufferView>; 1]>),
|
||||
ImageView(SmallVec<[Arc<dyn ImageViewAbstract>; 1]>),
|
||||
ImageViewSampler(SmallVec<[(Arc<dyn ImageViewAbstract>, Arc<Sampler>); 1]>),
|
||||
ImageView(SmallVec<[DescriptorImageViewInfo; 1]>),
|
||||
ImageViewSampler(SmallVec<[(DescriptorImageViewInfo, 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)]
|
||||
pub(crate) enum DescriptorWriteInfo {
|
||||
Image(SmallVec<[ash::vk::DescriptorImageInfo; 1]>),
|
||||
@ -406,7 +540,52 @@ pub(crate) enum DescriptorWriteInfo {
|
||||
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,
|
||||
layout: &'a DescriptorSetLayout,
|
||||
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, 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
|
||||
if device.enabled_extensions().khr_portability_subset
|
||||
&& !device.enabled_features().mutable_comparison_samplers
|
||||
@ -604,9 +803,14 @@ pub(crate) fn check_descriptor_write<'a>(
|
||||
let immutable_samplers = &layout_binding.immutable_samplers
|
||||
[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()
|
||||
{
|
||||
let &DescriptorImageViewInfo {
|
||||
ref image_view,
|
||||
image_layout,
|
||||
} = image_view_info;
|
||||
|
||||
assert_eq!(device, image_view.device());
|
||||
|
||||
// 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()) {
|
||||
return Err(DescriptorSetUpdateError::ImageViewIncompatibleSampler {
|
||||
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());
|
||||
|
||||
// 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
|
||||
if image_view.sampler_ycbcr_conversion().is_some() {
|
||||
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());
|
||||
|
||||
// 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
|
||||
if !image_view.component_mapping().is_identity() {
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
// 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
|
||||
if !image_view.component_mapping().is_identity() {
|
||||
return Err(DescriptorSetUpdateError::ImageViewNotIdentitySwizzled {
|
||||
@ -1014,19 +1290,36 @@ pub enum DescriptorSetUpdateError {
|
||||
written_count: u32,
|
||||
},
|
||||
|
||||
ImageLayoutInvalid {
|
||||
binding: u32,
|
||||
index: u32,
|
||||
},
|
||||
|
||||
/// 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.
|
||||
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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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,
|
||||
/// 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
|
||||
/// layout.
|
||||
@ -1049,7 +1345,9 @@ pub enum DescriptorSetUpdateError {
|
||||
},
|
||||
|
||||
/// Tried to write to a nonexistent binding.
|
||||
InvalidBinding { binding: u32 },
|
||||
InvalidBinding {
|
||||
binding: u32,
|
||||
},
|
||||
|
||||
/// A resource was missing a usage flag that was required.
|
||||
MissingUsage {
|
||||
@ -1067,7 +1365,10 @@ pub enum DescriptorSetUpdateError {
|
||||
},
|
||||
|
||||
/// 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 {
|
||||
@ -1103,6 +1404,12 @@ impl Display for DescriptorSetUpdateError {
|
||||
available",
|
||||
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!(
|
||||
f,
|
||||
"tried to write an image view to binding {} index {} with a 2D type and a 3D \
|
||||
|
@ -10,8 +10,7 @@
|
||||
use super::{
|
||||
sys::{Image, ImageMemory, RawImage},
|
||||
traits::ImageContent,
|
||||
ImageAccess, ImageAspects, ImageDescriptorLayouts, ImageError, ImageLayout, ImageUsage,
|
||||
SampleCount,
|
||||
ImageAccess, ImageAspects, ImageError, ImageLayout, ImageUsage, SampleCount,
|
||||
};
|
||||
use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
@ -603,16 +602,6 @@ unsafe impl ImageAccess for AttachmentImage {
|
||||
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]
|
||||
unsafe fn layout_initialized(&self) {
|
||||
self.layout_initialized.store(true, Ordering::SeqCst);
|
||||
|
@ -10,8 +10,8 @@
|
||||
use super::{
|
||||
sys::{Image, RawImage},
|
||||
traits::ImageContent,
|
||||
ImageAccess, ImageCreateFlags, ImageDescriptorLayouts, ImageDimensions, ImageError,
|
||||
ImageLayout, ImageSubresourceLayers, ImageUsage, MipmapsCount,
|
||||
ImageAccess, ImageCreateFlags, ImageDimensions, ImageError, ImageLayout,
|
||||
ImageSubresourceLayers, ImageUsage, MipmapsCount,
|
||||
};
|
||||
use crate::{
|
||||
buffer::{Buffer, BufferContents, BufferCreateInfo, BufferError, BufferUsage, Subbuffer},
|
||||
@ -331,16 +331,6 @@ unsafe impl ImageAccess for ImmutableImage {
|
||||
fn final_layout_requirement(&self) -> ImageLayout {
|
||||
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 {
|
||||
@ -391,11 +381,6 @@ unsafe impl ImageAccess for ImmutableImageInitialization {
|
||||
fn final_layout_requirement(&self) -> ImageLayout {
|
||||
self.image.layout
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ImmutableImageInitialization {
|
||||
|
@ -7,7 +7,7 @@
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use crate::{descriptor_set::layout::DescriptorType, macros::vulkan_enum};
|
||||
use crate::macros::vulkan_enum;
|
||||
|
||||
vulkan_enum! {
|
||||
#[non_exhaustive]
|
||||
@ -205,31 +205,3 @@ impl Default for ImageLayout {
|
||||
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},
|
||||
attachment::AttachmentImage,
|
||||
immutable::ImmutableImage,
|
||||
layout::{ImageDescriptorLayouts, ImageLayout},
|
||||
layout::ImageLayout,
|
||||
storage::StorageImage,
|
||||
swapchain::SwapchainImage,
|
||||
sys::ImageError,
|
||||
|
@ -10,8 +10,8 @@
|
||||
use super::{
|
||||
sys::{Image, ImageMemory, RawImage},
|
||||
traits::ImageContent,
|
||||
ImageAccess, ImageAspects, ImageCreateFlags, ImageDescriptorLayouts, ImageDimensions,
|
||||
ImageError, ImageLayout, ImageUsage,
|
||||
ImageAccess, ImageAspects, ImageCreateFlags, ImageDimensions, ImageError, ImageLayout,
|
||||
ImageUsage,
|
||||
};
|
||||
use crate::{
|
||||
device::{Device, DeviceOwned, Queue},
|
||||
@ -491,16 +491,6 @@ unsafe impl ImageAccess for StorageImage {
|
||||
fn is_layout_initialized(&self) -> bool {
|
||||
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 {
|
||||
|
@ -10,7 +10,7 @@
|
||||
use super::{
|
||||
sys::{Image, ImageMemory},
|
||||
traits::ImageContent,
|
||||
ImageAccess, ImageDescriptorLayouts, ImageLayout,
|
||||
ImageAccess, ImageLayout,
|
||||
};
|
||||
use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
@ -82,15 +82,6 @@ unsafe impl ImageAccess for SwapchainImage {
|
||||
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) {
|
||||
match self.inner.memory() {
|
||||
&ImageMemory::Swapchain {
|
||||
|
@ -8,8 +8,8 @@
|
||||
// according to those terms.
|
||||
|
||||
use super::{
|
||||
sys::Image, ImageAspects, ImageDescriptorLayouts, ImageDimensions, ImageLayout,
|
||||
ImageSubresourceLayers, ImageSubresourceRange, ImageUsage, SampleCount,
|
||||
sys::Image, ImageAspects, ImageDimensions, ImageLayout, ImageSubresourceLayers,
|
||||
ImageSubresourceRange, ImageUsage, SampleCount,
|
||||
};
|
||||
use crate::{
|
||||
device::{Device, DeviceOwned},
|
||||
@ -149,12 +149,6 @@ pub unsafe trait ImageAccess: DeviceOwned + Send + Sync {
|
||||
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 {
|
||||
@ -216,10 +210,6 @@ where
|
||||
fn final_layout_requirement(&self) -> ImageLayout {
|
||||
self.image.final_layout_requirement()
|
||||
}
|
||||
|
||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||
self.image.descriptor_layouts()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> PartialEq for ImageAccessFromUndefinedLayout<I>
|
||||
@ -264,10 +254,6 @@ where
|
||||
(**self).final_layout_requirement()
|
||||
}
|
||||
|
||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||
(**self).descriptor_layouts()
|
||||
}
|
||||
|
||||
unsafe fn layout_initialized(&self) {
|
||||
(**self).layout_initialized();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user