mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
Sampler improvements (#1787)
* Sampler improvements * Check Filter::Cubic for blits as well * Small doc fix * Better checks for blits * Doc fix * can_be_sampled > can_sample
This commit is contained in:
parent
6c111df9a7
commit
4c7cdb44fe
@ -34,7 +34,7 @@ use vulkano::{
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
},
|
||||
render_pass::{Framebuffer, RenderPass, Subpass},
|
||||
sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode},
|
||||
swapchain::{AcquireError, Swapchain, SwapchainCreationError},
|
||||
sync::{now, FlushError, GpuFuture, PipelineStages, Semaphore},
|
||||
Version,
|
||||
@ -493,20 +493,11 @@ fn vk_setup(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let sampler = Sampler::new(
|
||||
device.clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Nearest,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(device.clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
|
||||
|
@ -26,7 +26,7 @@ use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
|
||||
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
|
||||
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
|
||||
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
|
||||
use vulkano::sync::{self, FlushError, GpuFuture};
|
||||
use vulkano::Version;
|
||||
@ -243,20 +243,11 @@ fn main() {
|
||||
)
|
||||
};
|
||||
|
||||
let sampler = Sampler::new(
|
||||
device.clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Nearest,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(device.clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
|
@ -27,7 +27,7 @@ use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
|
||||
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
|
||||
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
|
||||
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
|
||||
use vulkano::sync::{self, FlushError, GpuFuture};
|
||||
use vulkano::Version;
|
||||
@ -177,20 +177,11 @@ fn main() {
|
||||
(ImageView::new(image).unwrap(), future)
|
||||
};
|
||||
|
||||
let sampler = Sampler::new(
|
||||
device.clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Nearest,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(device.clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
|
@ -36,7 +36,7 @@ use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
|
||||
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
|
||||
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
|
||||
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
|
||||
use vulkano::sync::{self, FlushError, GpuFuture};
|
||||
use vulkano::Version;
|
||||
@ -183,20 +183,11 @@ fn main() {
|
||||
(ImageView::new(image).unwrap(), future)
|
||||
};
|
||||
|
||||
let sampler = Sampler::new(
|
||||
device.clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Nearest,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(device.clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
|
@ -20,7 +20,7 @@ use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
|
||||
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
|
||||
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
|
||||
use vulkano::render_pass::Subpass;
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode, SamplerMipmapMode};
|
||||
|
||||
/// Vertex for textured quads
|
||||
#[repr(C)]
|
||||
@ -112,20 +112,13 @@ impl PixelsDrawPipeline {
|
||||
.descriptor_set_layouts()
|
||||
.get(0)
|
||||
.unwrap();
|
||||
let sampler = Sampler::new(
|
||||
self.gfx_queue.device().clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Linear,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(self.gfx_queue.device().clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.mipmap_mode(SamplerMipmapMode::Linear)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
PersistentDescriptorSet::new(
|
||||
layout.clone(),
|
||||
[WriteDescriptorSet::image_view_sampler(
|
||||
|
@ -27,7 +27,7 @@ use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
|
||||
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
|
||||
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
|
||||
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
|
||||
use vulkano::sync::{self, FlushError, GpuFuture};
|
||||
use vulkano::Version;
|
||||
@ -175,20 +175,11 @@ fn main() {
|
||||
(ImageView::new(image).unwrap(), future)
|
||||
};
|
||||
|
||||
let sampler = Sampler::new(
|
||||
device.clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Nearest,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(device.clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
|
@ -30,7 +30,7 @@ use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
|
||||
use vulkano::pipeline::layout::PipelineLayout;
|
||||
use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint};
|
||||
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
|
||||
use vulkano::sync::{self, FlushError, GpuFuture};
|
||||
use vulkano::Version;
|
||||
@ -266,20 +266,11 @@ fn main() {
|
||||
ImageView::new(image).unwrap()
|
||||
};
|
||||
|
||||
let sampler = Sampler::new(
|
||||
device.clone(),
|
||||
Filter::Linear,
|
||||
Filter::Linear,
|
||||
MipmapMode::Nearest,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
)
|
||||
.unwrap();
|
||||
let sampler = Sampler::start(device.clone())
|
||||
.filter(Filter::Linear)
|
||||
.address_mode(SamplerAddressMode::Repeat)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let pipeline_layout = {
|
||||
let mut descriptor_set_descs: Vec<_> = DescriptorSetDesc::from_requirements(
|
||||
|
@ -687,7 +687,7 @@ mod tests {
|
||||
set_layout.clone(),
|
||||
[WriteDescriptorSet::sampler(
|
||||
0,
|
||||
Sampler::simple_repeat_linear(device.clone()),
|
||||
Sampler::simple_repeat_linear(device.clone()).unwrap(),
|
||||
)],
|
||||
)
|
||||
.unwrap();
|
||||
@ -740,7 +740,7 @@ mod tests {
|
||||
set_layout.clone(),
|
||||
[WriteDescriptorSet::sampler(
|
||||
0,
|
||||
Sampler::simple_repeat_linear(device.clone()),
|
||||
Sampler::simple_repeat_linear(device.clone()).unwrap(),
|
||||
)],
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -265,12 +265,54 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
match filter {
|
||||
Filter::Nearest => (),
|
||||
Filter::Linear => {
|
||||
if !source_inner
|
||||
.image
|
||||
.format_features()
|
||||
.sampled_image_filter_linear
|
||||
{
|
||||
return Err(CheckBlitImageError::FilterFormatNotSupported);
|
||||
}
|
||||
}
|
||||
Filter::Cubic => {
|
||||
if !device.enabled_extensions().ext_filter_cubic {
|
||||
return Err(CheckBlitImageError::ExtensionNotEnabled {
|
||||
extension: "ext_filter_cubic",
|
||||
reason: "the specified filter was Cubic",
|
||||
});
|
||||
}
|
||||
|
||||
if !source_inner
|
||||
.image
|
||||
.format_features()
|
||||
.img_sampled_image_filter_cubic
|
||||
{
|
||||
return Err(CheckBlitImageError::FilterFormatNotSupported);
|
||||
}
|
||||
|
||||
if !matches!(source.dimensions(), ImageDimensions::Dim2d { .. }) {
|
||||
return Err(CheckBlitImageError::FilterDimensionalityNotSupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Error that can happen from `check_clear_color_image`.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum CheckBlitImageError {
|
||||
ExtensionNotEnabled {
|
||||
extension: &'static str,
|
||||
reason: &'static str,
|
||||
},
|
||||
|
||||
/// The chosen filter type does not support the dimensionality of the source image.
|
||||
FilterDimensionalityNotSupported,
|
||||
/// The chosen filter type does not support the format of the source image.
|
||||
FilterFormatNotSupported,
|
||||
/// The source is missing the transfer source usage.
|
||||
MissingTransferSourceUsage,
|
||||
/// The destination is missing the transfer destination usage.
|
||||
@ -305,50 +347,71 @@ impl error::Error for CheckBlitImageError {}
|
||||
impl fmt::Display for CheckBlitImageError {
|
||||
#[inline]
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(
|
||||
fmt,
|
||||
"{}",
|
||||
match *self {
|
||||
CheckBlitImageError::MissingTransferSourceUsage => {
|
||||
"the source is missing the transfer source usage"
|
||||
}
|
||||
CheckBlitImageError::MissingTransferDestinationUsage => {
|
||||
"the destination is missing the transfer destination usage"
|
||||
}
|
||||
CheckBlitImageError::SourceFormatNotSupported => {
|
||||
"the format of the source image doesn't support blit operations"
|
||||
}
|
||||
CheckBlitImageError::DestinationFormatNotSupported => {
|
||||
"the format of the destination image doesn't support blit operations"
|
||||
}
|
||||
CheckBlitImageError::DepthStencilNearestMandatory => {
|
||||
"you must use the nearest filter when blitting depth/stencil images"
|
||||
}
|
||||
CheckBlitImageError::DepthStencilFormatMismatch => {
|
||||
"the format of the source and destination must be equal when blitting \
|
||||
depth/stencil images"
|
||||
}
|
||||
CheckBlitImageError::IncompatibleFormatTypes { .. } => {
|
||||
"the types of the source format and the destination format aren't compatible"
|
||||
}
|
||||
CheckBlitImageError::UnexpectedMultisampled => {
|
||||
"blitting between multisampled images is forbidden"
|
||||
}
|
||||
CheckBlitImageError::SourceCoordinatesOutOfRange => {
|
||||
"the offsets, array layers and/or mipmap levels are out of range in the source \
|
||||
image"
|
||||
}
|
||||
CheckBlitImageError::DestinationCoordinatesOutOfRange => {
|
||||
"the offsets, array layers and/or mipmap levels are out of range in the \
|
||||
destination image"
|
||||
}
|
||||
CheckBlitImageError::IncompatibleRangeForImageType => {
|
||||
"the top-left and/or bottom-right coordinates are incompatible with the image type"
|
||||
}
|
||||
CheckBlitImageError::OverlappingRegions => {
|
||||
"the source and destination regions are overlapping"
|
||||
}
|
||||
match *self {
|
||||
Self::ExtensionNotEnabled { extension, reason } => write!(
|
||||
fmt,
|
||||
"the extension {} must be enabled: {}",
|
||||
extension, reason
|
||||
),
|
||||
Self::FilterDimensionalityNotSupported => write!(
|
||||
fmt,
|
||||
"the chosen filter type does not support the dimensionality of the source image"
|
||||
),
|
||||
Self::FilterFormatNotSupported => write!(
|
||||
fmt,
|
||||
"the chosen filter type does not support the format of the source image"
|
||||
),
|
||||
Self::MissingTransferSourceUsage => {
|
||||
write!(fmt, "the source is missing the transfer source usage")
|
||||
}
|
||||
)
|
||||
Self::MissingTransferDestinationUsage => {
|
||||
write!(
|
||||
fmt,
|
||||
"the destination is missing the transfer destination usage"
|
||||
)
|
||||
}
|
||||
Self::SourceFormatNotSupported => {
|
||||
write!(
|
||||
fmt,
|
||||
"the format of the source image doesn't support blit operations"
|
||||
)
|
||||
}
|
||||
Self::DestinationFormatNotSupported => {
|
||||
write!(
|
||||
fmt,
|
||||
"the format of the destination image doesn't support blit operations"
|
||||
)
|
||||
}
|
||||
Self::DepthStencilNearestMandatory => {
|
||||
write!(
|
||||
fmt,
|
||||
"you must use the nearest filter when blitting depth/stencil images"
|
||||
)
|
||||
}
|
||||
Self::DepthStencilFormatMismatch => {
|
||||
write!(fmt, "the format of the source and destination must be equal when blitting depth/stencil images")
|
||||
}
|
||||
Self::IncompatibleFormatTypes { .. } => {
|
||||
write!(
|
||||
fmt,
|
||||
"the types of the source format and the destination format aren't compatible"
|
||||
)
|
||||
}
|
||||
Self::UnexpectedMultisampled => {
|
||||
write!(fmt, "blitting between multisampled images is forbidden")
|
||||
}
|
||||
Self::SourceCoordinatesOutOfRange => {
|
||||
write!(fmt, "the offsets, array layers and/or mipmap levels are out of range in the source image")
|
||||
}
|
||||
Self::DestinationCoordinatesOutOfRange => {
|
||||
write!(fmt, "the offsets, array layers and/or mipmap levels are out of range in the destination image")
|
||||
}
|
||||
Self::IncompatibleRangeForImageType => {
|
||||
write!(fmt, "the top-left and/or bottom-right coordinates are incompatible with the image type")
|
||||
}
|
||||
Self::OverlappingRegions => {
|
||||
write!(fmt, "the source and destination regions are overlapping")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ pub(crate) fn check_descriptor_write<'a>(
|
||||
});
|
||||
}
|
||||
|
||||
if !image_view.can_be_sampled(sampler) {
|
||||
if !sampler.can_sample(image_view.as_ref()) {
|
||||
return Err(DescriptorSetUpdateError::ImageViewIncompatibleSampler {
|
||||
binding: write.binding(),
|
||||
index: descriptor_range_start + index as u32,
|
||||
@ -681,7 +681,7 @@ pub(crate) fn check_descriptor_write<'a>(
|
||||
});
|
||||
}
|
||||
|
||||
if !image_view.can_be_sampled(&sampler) {
|
||||
if !sampler.can_sample(image_view.as_ref()) {
|
||||
return Err(DescriptorSetUpdateError::ImageViewIncompatibleSampler {
|
||||
binding: write.binding(),
|
||||
index: descriptor_range_start + index as u32,
|
||||
|
@ -21,7 +21,6 @@ use crate::image::sys::UnsafeImage;
|
||||
use crate::image::ImageAccess;
|
||||
use crate::image::ImageDimensions;
|
||||
use crate::memory::DeviceMemoryAllocError;
|
||||
use crate::sampler::Sampler;
|
||||
use crate::OomError;
|
||||
use crate::VulkanObject;
|
||||
use std::error;
|
||||
@ -615,15 +614,6 @@ pub unsafe trait ImageViewAbstract: DeviceOwned + Send + Sync {
|
||||
|
||||
/// Returns the [`ImageViewType`] of this image view.
|
||||
fn ty(&self) -> ImageViewType;
|
||||
|
||||
/// Returns true if the given sampler can be used with this image view.
|
||||
///
|
||||
/// This method should check whether the sampler's configuration can be used with the format
|
||||
/// of the view.
|
||||
// TODO: return a Result and propagate it when binding to a descriptor set
|
||||
fn can_be_sampled(&self, _sampler: &Sampler) -> bool {
|
||||
true /* FIXME */
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I> ImageViewAbstract for ImageView<I>
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user