Skip to main content

vulkayes_core/descriptor/set/
update.rs

1use std::{num::NonZeroU64, ops::DerefMut};
2
3use ash::vk;
4
5use crate::prelude::{Buffer, HasHandle, ImageView, SafeHandle, Sampler, Transparent};
6
7use super::super::error::{
8	DescriptorImageInfoError,
9	DescriptorInlineUniformBlockInfoError,
10	DescriptorSetWriteError
11};
12
13vk_builder_wrap! {
14	/// Transparent wrapper struct over `DescriptorImageInfoBuilder`.
15	pub struct DescriptorImageInfo ['a] {
16		builder: vk::DescriptorImageInfoBuilder<'a> => vk::DescriptorImageInfo
17	}
18	impl ['a] {
19		pub fn new(
20			sampler: &'a Sampler,
21			image_view: &'a ImageView,
22			image_layout: vk::ImageLayout
23		) -> Result<Self, DescriptorImageInfoError> {
24			#[cfg(feature = "runtime_implicit_validations")]
25			{
26				if sampler.device() != image_view.image().device() {
27					return Err(DescriptorImageInfoError::SamplerImageViewDeviceMismatch)
28				}
29			}
30
31			Ok(Self {
32				builder: vk::DescriptorImageInfo::builder()
33					.sampler(sampler.handle())
34					.image_view(image_view.handle())
35					.image_layout(image_layout)
36			})
37		}
38
39		pub fn with_immutable_sampler(
40			image_view: &'a ImageView,
41			image_layout: vk::ImageLayout
42		) -> Self {
43			Self {
44				builder: vk::DescriptorImageInfo::builder()
45					.image_view(image_view.handle())
46					.image_layout(image_layout)
47			}
48		}
49	}
50}
51vk_enum_subset! {
52	pub enum DescriptorTypeImage {
53		SAMPLER,
54		COMBINED_IMAGE_SAMPLER,
55		SAMPLED_IMAGE,
56		STORAGE_IMAGE,
57		INPUT_ATTACHMENT
58	} impl Into<vk::DescriptorType>
59}
60
61vk_builder_wrap! {
62	/// Transparent wrapper struct over `DescriptorBufferInfoBuilder`.
63	pub struct DescriptorBufferInfo ['a] {
64		builder: vk::DescriptorBufferInfoBuilder<'a> => vk::DescriptorBufferInfo
65	}
66	impl ['a] {
67		pub fn new(buffer: &'a Buffer, offset: vk::DeviceSize, range: NonZeroU64) -> Self {
68			DescriptorBufferInfo {
69				builder: vk::DescriptorBufferInfo::builder()
70					.buffer(buffer.handle())
71					.offset(offset)
72					.range(range.get())
73			}
74		}
75	}
76}
77vk_enum_subset! {
78	pub enum DescriptorTypeBuffer {
79		UNIFORM_BUFFER,
80		STORAGE_BUFFER,
81		UNIFORM_BUFFER_DYNAMIC,
82		STORAGE_BUFFER_DYNAMIC
83	} impl Into<vk::DescriptorType>
84}
85
86vk_enum_subset! {
87	pub enum DescriptorTypeTexelBuffer {
88		UNIFORM_TEXEL_BUFFER,
89		STORAGE_TEXEL_BUFFER
90	} impl Into<vk::DescriptorType>
91}
92
93vk_builder_wrap! {
94	/// Transparent wrapper struct over `WriteDescriptorSetInlineUniformBlockEXT`.
95	pub struct DescriptorInlineUniformBlockInfo ['a] {
96		builder: vk::WriteDescriptorSetInlineUniformBlockEXTBuilder<'a> => vk::WriteDescriptorSetInlineUniformBlockEXT
97	}
98	impl ['a] {
99		pub fn new(data: &'a [u8]) -> Result<Self, DescriptorInlineUniformBlockInfoError> {
100			#[cfg(feature = "runtime_implicit_validations")]
101			{
102				if data.len() == 0 {
103					return Err(DescriptorInlineUniformBlockInfoError::DataEmpty)
104				}
105
106				if data.len() % 4 != 0 {
107					return Err(DescriptorInlineUniformBlockInfoError::SizeNotMultipleOfFour)
108				}
109			}
110
111			Ok(DescriptorInlineUniformBlockInfo {
112				builder: vk::WriteDescriptorSetInlineUniformBlockEXT::builder().data(data)
113			})
114		}
115	}
116}
117/// This is a hack. Waiting on `const_mut_refs` but it works like this on stable.
118pub struct DescriptorInlineUniformBlockInfoRefMut<'a>(
119	pub &'a mut DescriptorInlineUniformBlockInfo<'a>
120);
121
122unsafe_enum_variants! {
123	enum DescriptorSetWriteDataInner ['a] {
124		pub Image {
125			descriptor_type: DescriptorTypeImage,
126			image_infos: &'a [DescriptorImageInfo<'a>]
127		} => {
128			vk::WriteDescriptorSet::builder()
129				.descriptor_type(descriptor_type.into())
130				.image_info(
131					Transparent::transmute_slice_twice(image_infos)
132				)
133		},
134
135		pub Buffer {
136			descriptor_type: DescriptorTypeBuffer,
137			buffer_infos: &'a [DescriptorBufferInfo<'a>]
138		} => {
139			vk::WriteDescriptorSet::builder()
140				.descriptor_type(descriptor_type.into())
141				.buffer_info(
142					Transparent::transmute_slice_twice(buffer_infos)
143				)
144		},
145
146		pub TexelBuffer {
147			descriptor_type: DescriptorTypeTexelBuffer,
148			texel_buffer_views: &'a [SafeHandle<'a, vk::BufferView>]
149		} => {
150			vk::WriteDescriptorSet::builder()
151				.descriptor_type(descriptor_type.into())
152				.texel_buffer_view(
153					Transparent::transmute_slice(texel_buffer_views)
154				)
155		},
156
157		pub InlineUniformBlock {
158			info: DescriptorInlineUniformBlockInfoRefMut<'a>
159		} => {
160			let mut builder = vk::WriteDescriptorSet::builder()
161				.descriptor_type(vk::DescriptorType::INLINE_UNIFORM_BLOCK_EXT)
162			;
163			builder.descriptor_count = info.0.data_size;
164
165			builder.push_next(
166				info.0.deref_mut()
167			)
168		}
169	} as pub DescriptorSetWriteData ['a] impl Into<vk::WriteDescriptorSetBuilder<'a>>
170}
171
172vk_builder_wrap! {
173	/// Wrapper struct that is transparent `vk::WriteDescriptorSetBuilder`.
174	pub struct DescriptorSetWrite ['a] {
175		builder: vk::WriteDescriptorSetBuilder<'a> => vk::WriteDescriptorSet
176	}
177	impl ['a] {
178		pub fn new(
179			descriptor_set: SafeHandle<'a, vk::DescriptorSet>,
180			binding: u32,
181			array_element: u32,
182			data: DescriptorSetWriteData<'a>
183		) -> Result<Self, DescriptorSetWriteError> {
184			let builder = Into::<vk::WriteDescriptorSetBuilder>::into(data)
185				.dst_set(descriptor_set.into_handle())
186				.dst_binding(binding)
187				.dst_array_element(array_element);
188
189			#[cfg(feature = "runtime_implicit_validations")]
190			{
191				if builder.descriptor_count == 0 {
192					return Err(DescriptorSetWriteError::ZeroCount)
193				}
194			}
195
196			Ok(DescriptorSetWrite { builder })
197		}
198	}
199}
200
201vk_builder_wrap! {
202	/// Wrapper struct that is transparent `vk::WriteDescriptorSetBuilder`.
203	pub struct DescriptorSetCopy ['a] {
204		builder: vk::CopyDescriptorSetBuilder<'a> => vk::CopyDescriptorSet
205	}
206	impl ['a] {
207		pub fn new(
208			source_set: SafeHandle<'a, vk::DescriptorSet>,
209			source_binding: u32,
210			source_array_element: u32,
211			destination_set: SafeHandle<'a, vk::DescriptorSet>,
212			destination_binding: u32,
213			destination_array_element: u32,
214			count: u32
215		) -> Self {
216			DescriptorSetCopy {
217				builder: vk::CopyDescriptorSet::builder()
218					.src_set(source_set.into_handle())
219					.src_binding(source_binding)
220					.src_array_element(source_array_element)
221					.dst_set(destination_set.into_handle())
222					.dst_binding(destination_binding)
223					.dst_array_element(destination_array_element)
224					.descriptor_count(count)
225			}
226		}
227	}
228}