diff --git a/examples/src/bin/async-update.rs b/examples/src/bin/async-update.rs index 1df714b9..b5072d34 100644 --- a/examples/src/bin/async-update.rs +++ b/examples/src/bin/async-update.rs @@ -399,10 +399,11 @@ fn main() { layout(location = 0) in vec2 tex_coords; layout(location = 0) out vec4 f_color; - layout(set = 1, binding = 0) uniform sampler2D tex; + layout(set = 1, binding = 0) uniform sampler s; + layout(set = 1, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, tex_coords); + f_color = texture(sampler2D(tex, s), tex_coords); } ", } @@ -505,11 +506,10 @@ fn main() { PersistentDescriptorSet::new( &descriptor_set_allocator, pipeline.layout().set_layouts()[1].clone(), - [WriteDescriptorSet::image_view_sampler( - 0, - ImageView::new_default(texture).unwrap(), - sampler.clone(), - )], + [ + WriteDescriptorSet::sampler(0, sampler.clone()), + WriteDescriptorSet::image_view(1, ImageView::new_default(texture).unwrap()), + ], [], ) .unwrap() diff --git a/examples/src/bin/gl-interop.rs b/examples/src/bin/gl-interop.rs index 45d88b1d..6d1bdee1 100644 --- a/examples/src/bin/gl-interop.rs +++ b/examples/src/bin/gl-interop.rs @@ -270,9 +270,10 @@ mod linux { let set = PersistentDescriptorSet::new( &descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view_sampler( - 0, image_view, sampler, - )], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view(1, image_view), + ], [], ) .unwrap(); @@ -798,9 +799,12 @@ mod linux { #version 450 layout(location = 0) in vec2 tex_coords; layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; + void main() { - f_color = texture(tex, tex_coords); + f_color = texture(sampler2D(tex, s), tex_coords); } ", } diff --git a/examples/src/bin/image-self-copy-blit/main.rs b/examples/src/bin/image-self-copy-blit/main.rs index 2dbff95e..dee126a6 100644 --- a/examples/src/bin/image-self-copy-blit/main.rs +++ b/examples/src/bin/image-self-copy-blit/main.rs @@ -389,7 +389,10 @@ fn main() { let set = PersistentDescriptorSet::new( &descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view_sampler(0, texture, sampler)], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view(1, texture), + ], [], ) .unwrap(); @@ -578,10 +581,11 @@ mod fs { layout(location = 0) in vec2 tex_coords; layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, tex_coords); + f_color = texture(sampler2D(tex, s), tex_coords); } ", } diff --git a/examples/src/bin/image/main.rs b/examples/src/bin/image/main.rs index 10d3fba7..7ef8b6a6 100644 --- a/examples/src/bin/image/main.rs +++ b/examples/src/bin/image/main.rs @@ -337,7 +337,10 @@ fn main() { let set = PersistentDescriptorSet::new( &descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view_sampler(0, texture, sampler)], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view(1, texture), + ], [], ) .unwrap(); @@ -526,10 +529,11 @@ mod fs { layout(location = 0) in vec2 tex_coords; layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, tex_coords); + f_color = texture(sampler2D(tex, s), tex_coords); } ", } diff --git a/examples/src/bin/immutable-sampler/main.rs b/examples/src/bin/immutable-sampler/main.rs index 3ea590d8..6cb54880 100644 --- a/examples/src/bin/immutable-sampler/main.rs +++ b/examples/src/bin/immutable-sampler/main.rs @@ -358,7 +358,7 @@ fn main() { let set = PersistentDescriptorSet::new( &descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view(0, texture)], + [WriteDescriptorSet::image_view(1, texture)], [], ) .unwrap(); @@ -547,10 +547,11 @@ mod fs { layout(location = 0) in vec2 tex_coords; layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, tex_coords); + f_color = texture(sampler2D(tex, s), tex_coords); } ", } diff --git a/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs b/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs index 4fdc5595..139c0329 100644 --- a/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs +++ b/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs @@ -198,7 +198,10 @@ impl PixelsDrawPipeline { PersistentDescriptorSet::new( &self.descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view_sampler(0, image, sampler)], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view(1, image), + ], [], ) .unwrap() @@ -279,10 +282,11 @@ mod fs { layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, v_tex_coords); + f_color = texture(sampler2D(tex, s), v_tex_coords); } ", } diff --git a/examples/src/bin/multi_window_game_of_life/pixels_draw.rs b/examples/src/bin/multi_window_game_of_life/pixels_draw.rs index 08280b18..16445c5b 100644 --- a/examples/src/bin/multi_window_game_of_life/pixels_draw.rs +++ b/examples/src/bin/multi_window_game_of_life/pixels_draw.rs @@ -194,7 +194,10 @@ impl PixelsDrawPipeline { PersistentDescriptorSet::new( &self.descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view_sampler(0, image, sampler)], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view(1, image), + ], [], ) .unwrap() @@ -275,10 +278,11 @@ mod fs { layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, v_tex_coords); + f_color = texture(sampler2D(tex, s), v_tex_coords); } ", } diff --git a/examples/src/bin/push-descriptors/main.rs b/examples/src/bin/push-descriptors/main.rs index 33142067..b1e05eac 100644 --- a/examples/src/bin/push-descriptors/main.rs +++ b/examples/src/bin/push-descriptors/main.rs @@ -428,9 +428,14 @@ fn main() { PipelineBindPoint::Graphics, pipeline.layout().clone(), 0, - [WriteDescriptorSet::image_view(0, texture.clone())] - .into_iter() - .collect(), + [ + // If the binding is an immutable sampler, using push descriptors + // you must write a dummy value to the binding. + WriteDescriptorSet::none(0), + WriteDescriptorSet::image_view(1, texture.clone()), + ] + .into_iter() + .collect(), ) .unwrap() .bind_vertex_buffers(0, vertex_buffer.clone()) @@ -522,10 +527,11 @@ mod fs { layout(location = 0) in vec2 tex_coords; layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex; void main() { - f_color = texture(tex, tex_coords); + f_color = texture(sampler2D(tex, s), tex_coords); } ", } diff --git a/examples/src/bin/runtime_array/main.rs b/examples/src/bin/runtime_array/main.rs index 45743f63..0e367280 100644 --- a/examples/src/bin/runtime_array/main.rs +++ b/examples/src/bin/runtime_array/main.rs @@ -410,10 +410,10 @@ fn main() { let mut layout_create_info = PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages); - // Adjust the info for set 0, binding 0 to make it variable with 2 descriptors. + // Adjust the info for set 0, binding 1 to make it variable with 2 descriptors. let binding = layout_create_info.set_layouts[0] .bindings - .get_mut(&0) + .get_mut(&1) .unwrap(); binding.binding_flags |= DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT; binding.descriptor_count = 2; @@ -458,14 +458,10 @@ fn main() { &descriptor_set_allocator, layout.clone(), 2, - [WriteDescriptorSet::image_view_sampler_array( - 0, - 0, - [ - (mascot_texture as _, sampler.clone()), - (vulkano_texture as _, sampler), - ], - )], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view_array(1, 0, [mascot_texture as _, vulkano_texture as _]), + ], [], ) .unwrap(); @@ -667,10 +663,11 @@ mod fs { layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2D tex[]; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2D tex[]; void main() { - f_color = texture(nonuniformEXT(tex[tex_i]), coords); + f_color = texture(nonuniformEXT(sampler2D(tex[tex_i], s)), coords); } ", } diff --git a/examples/src/bin/texture_array/main.rs b/examples/src/bin/texture_array/main.rs index 9f836f08..e85c42e8 100644 --- a/examples/src/bin/texture_array/main.rs +++ b/examples/src/bin/texture_array/main.rs @@ -348,7 +348,10 @@ fn main() { let set = PersistentDescriptorSet::new( &descriptor_set_allocator, layout.clone(), - [WriteDescriptorSet::image_view_sampler(0, texture, sampler)], + [ + WriteDescriptorSet::sampler(0, sampler), + WriteDescriptorSet::image_view(1, texture), + ], [], ) .unwrap(); @@ -543,10 +546,11 @@ mod fs { layout(location = 1) flat in uint layer; layout(location = 0) out vec4 f_color; - layout(set = 0, binding = 0) uniform sampler2DArray tex; + layout(set = 0, binding = 0) uniform sampler s; + layout(set = 0, binding = 1) uniform texture2DArray tex; void main() { - f_color = texture(tex, vec3(tex_coords, layer)); + f_color = texture(sampler2DArray(tex, s), vec3(tex_coords, layer)); } ", } diff --git a/vulkano/src/descriptor_set/update.rs b/vulkano/src/descriptor_set/update.rs index 8838f138..e6b9ebb8 100644 --- a/vulkano/src/descriptor_set/update.rs +++ b/vulkano/src/descriptor_set/update.rs @@ -413,17 +413,6 @@ impl WriteDescriptorSet { let array_element_count = elements.len(); debug_assert!(array_element_count != 0); - // VUID-VkWriteDescriptorSet-dstArrayElement-00321 - if first_array_element + array_element_count > max_descriptor_count { - return Err(Box::new(ValidationError { - problem: "`first_array_element` + the number of provided elements is greater than \ - the number of descriptors in the descriptor set binding" - .into(), - vuids: &["VUID-VkWriteDescriptorSet-dstArrayElement-00321"], - ..Default::default() - })); - } - let validate_image_view = |image_view: &ImageView, index: usize| -> Result<(), Box> { if image_view.image().image_type() == ImageType::Dim3d { @@ -530,86 +519,88 @@ impl WriteDescriptorSet { match layout_binding.descriptor_type { DescriptorType::Sampler => { - if !layout_binding.immutable_samplers.is_empty() { - if layout - .flags() - .intersects(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR) - { - // For push descriptors, we must write a dummy element. - if let WriteDescriptorSetElements::None(_) = elements { - // Do nothing - } else { + if layout_binding.immutable_samplers.is_empty() { + let elements = if let WriteDescriptorSetElements::Sampler(elements) = elements { + elements + } else { + return Err(Box::new(ValidationError { + context: "elements".into(), + problem: format!( + "contains `{}` elements, but descriptor set binding {} \ + requires `sampler` elements", + provided_element_type(elements), + binding, + ) + .into(), + // vuids? + ..Default::default() + })); + }; + + for (index, sampler) in elements.iter().enumerate() { + assert_eq!(device, sampler.device()); + + if sampler.sampler_ycbcr_conversion().is_some() { return Err(Box::new(ValidationError { - context: "elements".into(), - problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `none` elements", - provided_element_type(elements) - ) - .into(), + context: format!("elements[{}]", index).into(), + problem: "the descriptor type is not \ + `DescriptorType::CombinedImageSampler`, and the sampler has a \ + sampler YCbCr conversion" + .into(), // vuids? ..Default::default() })); } + + if device.enabled_extensions().khr_portability_subset + && !device.enabled_features().mutable_comparison_samplers + && sampler.compare().is_some() + { + return Err(Box::new(ValidationError { + context: format!("elements[{}]", index).into(), + problem: "this device is a portability subset device, and \ + the sampler has depth comparison enabled" + .into(), + requires_one_of: RequiresOneOf(&[RequiresAllOf(&[ + Requires::Feature("mutable_comparison_samplers"), + ])]), + vuids: &[ + "VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450", + ], + })); + } + } + } else if layout + .flags() + .intersects(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR) + { + // For push descriptors, we must write a dummy element. + if let WriteDescriptorSetElements::None(_) = elements { + // Do nothing } else { - // For regular descriptors, no element must be written. return Err(Box::new(ValidationError { - context: "binding".into(), - problem: "no descriptors must be written to this \ - descriptor set binding" - .into(), + context: "elements".into(), + problem: format!( + "contains `{}` elements, but descriptor set binding {} \ + requires `none` elements", + provided_element_type(elements), + binding, + ) + .into(), // vuids? ..Default::default() })); } - } - - let elements = if let WriteDescriptorSetElements::Sampler(elements) = elements { - elements } else { + // For regular descriptors, no element must be written. return Err(Box::new(ValidationError { - context: "elements".into(), - problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `sampler` elements", - provided_element_type(elements) - ) - .into(), + context: "binding".into(), + problem: "no descriptors must be written to this \ + descriptor set binding" + .into(), // vuids? ..Default::default() })); - }; - - for (index, sampler) in elements.iter().enumerate() { - assert_eq!(device, sampler.device()); - - if sampler.sampler_ycbcr_conversion().is_some() { - return Err(Box::new(ValidationError { - context: format!("elements[{}]", index).into(), - problem: "the descriptor type is not \ - `DescriptorType::CombinedImageSampler`, and the sampler has a \ - sampler YCbCr conversion" - .into(), - // vuids? - ..Default::default() - })); - } - - if device.enabled_extensions().khr_portability_subset - && !device.enabled_features().mutable_comparison_samplers - && sampler.compare().is_some() - { - return Err(Box::new(ValidationError { - context: format!("elements[{}]", index).into(), - problem: "this device is a portability subset device, and \ - the sampler has depth comparison enabled" - .into(), - requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature( - "mutable_comparison_samplers", - )])]), - vuids: &["VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450"], - })); - } } } @@ -622,9 +613,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `image_view_sampler` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `image_view_sampler` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -731,9 +723,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `image_view` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `image_view` elements", + provided_element_type(elements), + binding, ) .into(), ..Default::default() @@ -807,9 +800,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `image_view` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `image_view` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -885,9 +879,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `image_view` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `image_view` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -963,9 +958,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `buffer_view` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `buffer_view` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -1002,9 +998,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `buffer_view` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `buffer_view` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -1042,9 +1039,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `buffer` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `buffer` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -1094,9 +1092,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `buffer` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `buffer` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -1146,9 +1145,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `image_view` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `image_view` elements", + provided_element_type(elements), + binding, ) .into(), // vuids? @@ -1235,9 +1235,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `inline_uniform_block` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `inline_uniform_block` elements", + provided_element_type(elements), + binding, ) .into(), ..Default::default() @@ -1286,9 +1287,10 @@ impl WriteDescriptorSet { return Err(Box::new(ValidationError { context: "elements".into(), problem: format!( - "contains `{}` elements, but the descriptor set \ - binding requires `acceleration_structure` elements", - provided_element_type(elements) + "contains `{}` elements, but descriptor set binding {} \ + requires `acceleration_structure` elements", + provided_element_type(elements), + binding, ) .into(), ..Default::default() @@ -1316,6 +1318,17 @@ impl WriteDescriptorSet { } } + // VUID-VkWriteDescriptorSet-dstArrayElement-00321 + if first_array_element + array_element_count > max_descriptor_count { + return Err(Box::new(ValidationError { + problem: "`first_array_element` + the number of provided elements is greater than \ + the number of descriptors in the descriptor set binding" + .into(), + vuids: &["VUID-VkWriteDescriptorSet-dstArrayElement-00321"], + ..Default::default() + })); + } + Ok(()) }