Image Sampler Improvements (#10254)

# Objective

- Build on the changes in https://github.com/bevyengine/bevy/pull/9982
- Use `ImageSamplerDescriptor` as the "public image sampler descriptor"
interface in all places (for consistency)
- Make it possible to configure textures to use the "default" sampler
(as configured in the `DefaultImageSampler` resource)
- Fix a bug introduced in #9982 that prevents configured samplers from
being used in Basis, KTX2, and DDS textures

---

## Migration Guide

- When using the `Image` API, use `ImageSamplerDescriptor` instead of
`wgpu::SamplerDescriptor`
- If writing custom wgpu renderer features that work with `Image`, call
`&image_sampler.as_wgpu()` to convert to a wgpu descriptor.
This commit is contained in:
Carter Anderson 2023-10-26 16:30:09 -07:00 committed by GitHub
parent bfca4384cc
commit 134750d18e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 110 additions and 110 deletions

View File

@ -346,16 +346,18 @@ pub fn get_lut_bind_group_layout_entries(bindings: [u32; 2]) -> [BindGroupLayout
// allow(dead_code) so it doesn't complain when the tonemapping_luts feature is disabled // allow(dead_code) so it doesn't complain when the tonemapping_luts feature is disabled
#[allow(dead_code)] #[allow(dead_code)]
fn setup_tonemapping_lut_image(bytes: &[u8], image_type: ImageType) -> Image { fn setup_tonemapping_lut_image(bytes: &[u8], image_type: ImageType) -> Image {
let image_sampler = bevy_render::texture::ImageSampler::Descriptor(SamplerDescriptor { let image_sampler = bevy_render::texture::ImageSampler::Descriptor(
label: Some("Tonemapping LUT sampler"), bevy_render::texture::ImageSamplerDescriptor {
address_mode_u: AddressMode::ClampToEdge, label: Some("Tonemapping LUT sampler".to_string()),
address_mode_v: AddressMode::ClampToEdge, address_mode_u: bevy_render::texture::ImageAddressMode::ClampToEdge,
address_mode_w: AddressMode::ClampToEdge, address_mode_v: bevy_render::texture::ImageAddressMode::ClampToEdge,
mag_filter: FilterMode::Linear, address_mode_w: bevy_render::texture::ImageAddressMode::ClampToEdge,
min_filter: FilterMode::Linear, mag_filter: bevy_render::texture::ImageFilterMode::Linear,
mipmap_filter: FilterMode::Linear, min_filter: bevy_render::texture::ImageFilterMode::Linear,
..default() mipmap_filter: bevy_render::texture::ImageFilterMode::Linear,
}); ..default()
},
);
Image::from_buffer( Image::from_buffer(
bytes, bytes,
image_type, image_type,
@ -385,7 +387,7 @@ pub fn lut_placeholder() -> Image {
usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
view_formats: &[], view_formats: &[],
}, },
sampler_descriptor: ImageSampler::Default, sampler: ImageSampler::Default,
texture_view_descriptor: None, texture_view_descriptor: None,
} }
} }

View File

@ -264,7 +264,7 @@ async fn load_gltf<'a, 'b, 'c>(
} => { } => {
load_context.load_with_settings(path, move |settings: &mut ImageLoaderSettings| { load_context.load_with_settings(path, move |settings: &mut ImageLoaderSettings| {
settings.is_srgb = is_srgb; settings.is_srgb = is_srgb;
settings.sampler_descriptor = sampler_descriptor; settings.sampler = ImageSampler::Descriptor(sampler_descriptor.clone());
}) })
} }
}; };
@ -684,7 +684,7 @@ async fn load_image<'a, 'b>(
ImageType::MimeType(mime_type), ImageType::MimeType(mime_type),
supported_compressed_formats, supported_compressed_formats,
is_srgb, is_srgb,
ImageSampler::Descriptor(sampler_descriptor.into()), ImageSampler::Descriptor(sampler_descriptor),
)?; )?;
Ok(ImageOrPath::Image { Ok(ImageOrPath::Image {
image, image,
@ -705,7 +705,7 @@ async fn load_image<'a, 'b>(
mime_type.map(ImageType::MimeType).unwrap_or(image_type), mime_type.map(ImageType::MimeType).unwrap_or(image_type),
supported_compressed_formats, supported_compressed_formats,
is_srgb, is_srgb,
ImageSampler::Descriptor(sampler_descriptor.into()), ImageSampler::Descriptor(sampler_descriptor),
)?, )?,
label: texture_label(&gltf_texture), label: texture_label(&gltf_texture),
}) })

View File

@ -267,7 +267,7 @@ pub struct StandardMaterial {
/// Use the [`parallax_mapping_method`] and [`max_parallax_layer_count`] fields /// Use the [`parallax_mapping_method`] and [`max_parallax_layer_count`] fields
/// to tweak the shader, trading graphical quality for performance. /// to tweak the shader, trading graphical quality for performance.
/// ///
/// To improve performance, set your `depth_map`'s [`Image::sampler_descriptor`] /// To improve performance, set your `depth_map`'s [`Image::sampler`]
/// filter mode to `FilterMode::Nearest`, as [this paper] indicates, it improves /// filter mode to `FilterMode::Nearest`, as [this paper] indicates, it improves
/// performance a bit. /// performance a bit.
/// ///

View File

@ -361,10 +361,10 @@ impl FromWorld for MeshPipeline {
let dummy_white_gpu_image = { let dummy_white_gpu_image = {
let image = Image::default(); let image = Image::default();
let texture = render_device.create_texture(&image.texture_descriptor); let texture = render_device.create_texture(&image.texture_descriptor);
let sampler = match image.sampler_descriptor { let sampler = match image.sampler {
ImageSampler::Default => (**default_sampler).clone(), ImageSampler::Default => (**default_sampler).clone(),
ImageSampler::Descriptor(ref descriptor) => { ImageSampler::Descriptor(ref descriptor) => {
render_device.create_sampler(descriptor) render_device.create_sampler(&descriptor.as_wgpu())
} }
}; };

View File

@ -1,7 +1,4 @@
use crate::texture::{ use crate::texture::{Image, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderSettings};
Image, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderSettings, ImageSampler,
ImageSamplerDescriptor,
};
use bevy_asset::saver::{AssetSaver, SavedAsset}; use bevy_asset::saver::{AssetSaver, SavedAsset};
use futures_lite::{AsyncWriteExt, FutureExt}; use futures_lite::{AsyncWriteExt, FutureExt};
use thiserror::Error; use thiserror::Error;
@ -33,10 +30,6 @@ impl AssetSaver for CompressedImageSaver {
compressor_params.set_basis_format(basis_universal::BasisTextureFormat::UASTC4x4); compressor_params.set_basis_format(basis_universal::BasisTextureFormat::UASTC4x4);
compressor_params.set_generate_mipmaps(true); compressor_params.set_generate_mipmaps(true);
let is_srgb = image.texture_descriptor.format.is_srgb(); let is_srgb = image.texture_descriptor.format.is_srgb();
let sampler_descriptor = match &image.sampler_descriptor {
ImageSampler::Default => ImageSamplerDescriptor::default(),
ImageSampler::Descriptor(sampler_descriptor) => sampler_descriptor.clone().into(),
};
let color_space = if is_srgb { let color_space = if is_srgb {
basis_universal::ColorSpace::Srgb basis_universal::ColorSpace::Srgb
} else { } else {
@ -62,7 +55,7 @@ impl AssetSaver for CompressedImageSaver {
Ok(ImageLoaderSettings { Ok(ImageLoaderSettings {
format: ImageFormatSetting::Format(ImageFormat::Basis), format: ImageFormatSetting::Format(ImageFormat::Basis),
is_srgb, is_srgb,
sampler_descriptor, sampler: image.sampler.clone(),
}) })
} }
.boxed() .boxed()

View File

@ -100,9 +100,11 @@ fn fallback_image_new(
array_layer_count: Some(extents.depth_or_array_layers), array_layer_count: Some(extents.depth_or_array_layers),
..TextureViewDescriptor::default() ..TextureViewDescriptor::default()
}); });
let sampler = match image.sampler_descriptor { let sampler = match image.sampler {
ImageSampler::Default => (**default_sampler).clone(), ImageSampler::Default => (**default_sampler).clone(),
ImageSampler::Descriptor(ref descriptor) => render_device.create_sampler(descriptor), ImageSampler::Descriptor(ref descriptor) => {
render_device.create_sampler(&descriptor.as_wgpu())
}
}; };
GpuImage { GpuImage {
texture, texture,

View File

@ -108,55 +108,33 @@ pub struct Image {
// TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors // TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
pub texture_descriptor: wgpu::TextureDescriptor<'static>, pub texture_descriptor: wgpu::TextureDescriptor<'static>,
/// The [`ImageSampler`] to use during rendering. /// The [`ImageSampler`] to use during rendering.
pub sampler_descriptor: ImageSampler, pub sampler: ImageSampler,
pub texture_view_descriptor: Option<wgpu::TextureViewDescriptor<'static>>, pub texture_view_descriptor: Option<wgpu::TextureViewDescriptor<'static>>,
} }
/// Used in [`Image`], this determines what image sampler to use when rendering. The default setting, /// Used in [`Image`], this determines what image sampler to use when rendering. The default setting,
/// [`ImageSampler::Default`], will read the sampler from the [`ImagePlugin`](super::ImagePlugin) at setup. /// [`ImageSampler::Default`], will read the sampler from the [`ImagePlugin`](super::ImagePlugin) at setup.
/// Setting this to [`ImageSampler::Descriptor`] will override the global default descriptor for this [`Image`]. /// Setting this to [`ImageSampler::Descriptor`] will override the global default descriptor for this [`Image`].
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub enum ImageSampler { pub enum ImageSampler {
/// Default image sampler, derived from the [`ImagePlugin`](super::ImagePlugin) setup. /// Default image sampler, derived from the [`ImagePlugin`](super::ImagePlugin) setup.
#[default] #[default]
Default, Default,
/// Custom sampler for this image which will override global default. /// Custom sampler for this image which will override global default.
Descriptor(wgpu::SamplerDescriptor<'static>), Descriptor(ImageSamplerDescriptor),
} }
impl ImageSampler { impl ImageSampler {
/// Returns an image sampler with [`Linear`](crate::render_resource::FilterMode::Linear) min and mag filters /// Returns an image sampler with [`ImageFilterMode::Linear`] min and mag filters
#[inline] #[inline]
pub fn linear() -> ImageSampler { pub fn linear() -> ImageSampler {
ImageSampler::Descriptor(Self::linear_descriptor()) ImageSampler::Descriptor(ImageSamplerDescriptor::linear())
} }
/// Returns an image sampler with [`Nearest`](crate::render_resource::FilterMode::Nearest) min and mag filters /// Returns an image sampler with [`ImageFilterMode::Nearest`] min and mag filters
#[inline] #[inline]
pub fn nearest() -> ImageSampler { pub fn nearest() -> ImageSampler {
ImageSampler::Descriptor(Self::nearest_descriptor()) ImageSampler::Descriptor(ImageSamplerDescriptor::nearest())
}
/// Returns a sampler descriptor with [`Linear`](crate::render_resource::FilterMode::Linear) min and mag filters
#[inline]
pub fn linear_descriptor() -> wgpu::SamplerDescriptor<'static> {
wgpu::SamplerDescriptor {
mag_filter: wgpu::FilterMode::Linear,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Linear,
..Default::default()
}
}
/// Returns a sampler descriptor with [`Nearest`](crate::render_resource::FilterMode::Nearest) min and mag filters
#[inline]
pub fn nearest_descriptor() -> wgpu::SamplerDescriptor<'static> {
wgpu::SamplerDescriptor {
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
}
} }
} }
@ -265,8 +243,9 @@ pub enum ImageSamplerBorderColor {
/// a breaking change. /// a breaking change.
/// ///
/// This types mirrors [`wgpu::SamplerDescriptor`], but that might change in future versions. /// This types mirrors [`wgpu::SamplerDescriptor`], but that might change in future versions.
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ImageSamplerDescriptor { pub struct ImageSamplerDescriptor {
pub label: Option<String>,
/// How to deal with out of bounds accesses in the u (i.e. x) direction. /// How to deal with out of bounds accesses in the u (i.e. x) direction.
pub address_mode_u: ImageAddressMode, pub address_mode_u: ImageAddressMode,
/// How to deal with out of bounds accesses in the v (i.e. y) direction. /// How to deal with out of bounds accesses in the v (i.e. y) direction.
@ -305,6 +284,48 @@ impl Default for ImageSamplerDescriptor {
compare: None, compare: None,
anisotropy_clamp: 1, anisotropy_clamp: 1,
border_color: None, border_color: None,
label: None,
}
}
}
impl ImageSamplerDescriptor {
/// Returns a sampler descriptor with [`Linear`](crate::render_resource::FilterMode::Linear) min and mag filters
#[inline]
pub fn linear() -> ImageSamplerDescriptor {
ImageSamplerDescriptor {
mag_filter: ImageFilterMode::Linear,
min_filter: ImageFilterMode::Linear,
mipmap_filter: ImageFilterMode::Linear,
..Default::default()
}
}
/// Returns a sampler descriptor with [`Nearest`](crate::render_resource::FilterMode::Nearest) min and mag filters
#[inline]
pub fn nearest() -> ImageSamplerDescriptor {
ImageSamplerDescriptor {
mag_filter: ImageFilterMode::Nearest,
min_filter: ImageFilterMode::Nearest,
mipmap_filter: ImageFilterMode::Nearest,
..Default::default()
}
}
pub fn as_wgpu(&self) -> wgpu::SamplerDescriptor {
wgpu::SamplerDescriptor {
label: self.label.as_deref(),
address_mode_u: self.address_mode_u.into(),
address_mode_v: self.address_mode_v.into(),
address_mode_w: self.address_mode_w.into(),
mag_filter: self.mag_filter.into(),
min_filter: self.min_filter.into(),
mipmap_filter: self.mipmap_filter.into(),
lod_min_clamp: self.lod_min_clamp,
lod_max_clamp: self.lod_max_clamp,
compare: self.compare.map(Into::into),
anisotropy_clamp: self.anisotropy_clamp,
border_color: self.border_color.map(Into::into),
} }
} }
} }
@ -355,25 +376,6 @@ impl From<ImageSamplerBorderColor> for wgpu::SamplerBorderColor {
} }
} }
impl From<ImageSamplerDescriptor> for wgpu::SamplerDescriptor<'static> {
fn from(value: ImageSamplerDescriptor) -> Self {
wgpu::SamplerDescriptor {
label: None,
address_mode_u: value.address_mode_u.into(),
address_mode_v: value.address_mode_v.into(),
address_mode_w: value.address_mode_w.into(),
mag_filter: value.mag_filter.into(),
min_filter: value.min_filter.into(),
mipmap_filter: value.mipmap_filter.into(),
lod_min_clamp: value.lod_min_clamp,
lod_max_clamp: value.lod_max_clamp,
compare: value.compare.map(Into::into),
anisotropy_clamp: value.anisotropy_clamp,
border_color: value.border_color.map(Into::into),
}
}
}
impl From<wgpu::AddressMode> for ImageAddressMode { impl From<wgpu::AddressMode> for ImageAddressMode {
fn from(value: wgpu::AddressMode) -> Self { fn from(value: wgpu::AddressMode) -> Self {
match value { match value {
@ -423,6 +425,7 @@ impl From<wgpu::SamplerBorderColor> for ImageSamplerBorderColor {
impl<'a> From<wgpu::SamplerDescriptor<'a>> for ImageSamplerDescriptor { impl<'a> From<wgpu::SamplerDescriptor<'a>> for ImageSamplerDescriptor {
fn from(value: wgpu::SamplerDescriptor) -> Self { fn from(value: wgpu::SamplerDescriptor) -> Self {
ImageSamplerDescriptor { ImageSamplerDescriptor {
label: value.label.map(|l| l.to_string()),
address_mode_u: value.address_mode_u.into(), address_mode_u: value.address_mode_u.into(),
address_mode_v: value.address_mode_v.into(), address_mode_v: value.address_mode_v.into(),
address_mode_w: value.address_mode_w.into(), address_mode_w: value.address_mode_w.into(),
@ -459,7 +462,7 @@ impl Default for Image {
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[], view_formats: &[],
}, },
sampler_descriptor: ImageSampler::Default, sampler: ImageSampler::Default,
texture_view_descriptor: None, texture_view_descriptor: None,
} }
} }
@ -645,16 +648,16 @@ impl Image {
// needs to be added, so the image data needs to be converted in those // needs to be added, so the image data needs to be converted in those
// cases. // cases.
match format { let mut image = match format {
#[cfg(feature = "basis-universal")] #[cfg(feature = "basis-universal")]
ImageFormat::Basis => { ImageFormat::Basis => {
basis_buffer_to_image(buffer, supported_compressed_formats, is_srgb) basis_buffer_to_image(buffer, supported_compressed_formats, is_srgb)?
} }
#[cfg(feature = "dds")] #[cfg(feature = "dds")]
ImageFormat::Dds => dds_buffer_to_image(buffer, supported_compressed_formats, is_srgb), ImageFormat::Dds => dds_buffer_to_image(buffer, supported_compressed_formats, is_srgb)?,
#[cfg(feature = "ktx2")] #[cfg(feature = "ktx2")]
ImageFormat::Ktx2 => { ImageFormat::Ktx2 => {
ktx2_buffer_to_image(buffer, supported_compressed_formats, is_srgb) ktx2_buffer_to_image(buffer, supported_compressed_formats, is_srgb)?
} }
_ => { _ => {
let image_crate_format = format let image_crate_format = format
@ -664,11 +667,11 @@ impl Image {
reader.set_format(image_crate_format); reader.set_format(image_crate_format);
reader.no_limits(); reader.no_limits();
let dyn_img = reader.decode()?; let dyn_img = reader.decode()?;
let mut img = Self::from_dynamic(dyn_img, is_srgb); Self::from_dynamic(dyn_img, is_srgb)
img.sampler_descriptor = image_sampler;
Ok(img)
} }
} };
image.sampler = image_sampler;
Ok(image)
} }
/// Whether the texture format is compressed or uncompressed /// Whether the texture format is compressed or uncompressed
@ -832,9 +835,11 @@ impl RenderAsset for Image {
image.texture_descriptor.size.width as f32, image.texture_descriptor.size.width as f32,
image.texture_descriptor.size.height as f32, image.texture_descriptor.size.height as f32,
); );
let sampler = match image.sampler_descriptor { let sampler = match image.sampler {
ImageSampler::Default => (***default_sampler).clone(), ImageSampler::Default => (***default_sampler).clone(),
ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor), ImageSampler::Descriptor(descriptor) => {
render_device.create_sampler(&descriptor.as_wgpu())
}
}; };
Ok(GpuImage { Ok(GpuImage {

View File

@ -7,7 +7,7 @@ use crate::{
texture::{Image, ImageFormat, ImageType, TextureError}, texture::{Image, ImageFormat, ImageType, TextureError},
}; };
use super::{CompressedImageFormats, ImageSampler, ImageSamplerDescriptor}; use super::{CompressedImageFormats, ImageSampler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Loader for images that can be read by the `image` crate. /// Loader for images that can be read by the `image` crate.
@ -45,18 +45,18 @@ pub(crate) const IMG_FILE_EXTENSIONS: &[&str] = &[
"ppm", "ppm",
]; ];
#[derive(Serialize, Deserialize, Default)] #[derive(Serialize, Deserialize, Default, Debug)]
pub enum ImageFormatSetting { pub enum ImageFormatSetting {
#[default] #[default]
FromExtension, FromExtension,
Format(ImageFormat), Format(ImageFormat),
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug)]
pub struct ImageLoaderSettings { pub struct ImageLoaderSettings {
pub format: ImageFormatSetting, pub format: ImageFormatSetting,
pub is_srgb: bool, pub is_srgb: bool,
pub sampler_descriptor: ImageSamplerDescriptor, pub sampler: ImageSampler,
} }
impl Default for ImageLoaderSettings { impl Default for ImageLoaderSettings {
@ -64,7 +64,7 @@ impl Default for ImageLoaderSettings {
Self { Self {
format: ImageFormatSetting::default(), format: ImageFormatSetting::default(),
is_srgb: true, is_srgb: true,
sampler_descriptor: ImageSamplerDescriptor::default(), sampler: ImageSampler::Default,
} }
} }
} }
@ -103,7 +103,7 @@ impl AssetLoader for ImageLoader {
image_type, image_type,
self.supported_compressed_formats, self.supported_compressed_formats,
settings.is_srgb, settings.is_srgb,
ImageSampler::Descriptor(settings.sampler_descriptor.into()), settings.sampler.clone(),
) )
.map_err(|err| FileTextureError { .map_err(|err| FileTextureError {
error: err, error: err,

View File

@ -45,7 +45,7 @@ use bevy_ecs::prelude::*;
/// Adds the [`Image`] as an asset and makes sure that they are extracted and prepared for the GPU. /// Adds the [`Image`] as an asset and makes sure that they are extracted and prepared for the GPU.
pub struct ImagePlugin { pub struct ImagePlugin {
/// The default image sampler to use when [`ImageSampler`] is set to `Default`. /// The default image sampler to use when [`ImageSampler`] is set to `Default`.
pub default_sampler: wgpu::SamplerDescriptor<'static>, pub default_sampler: ImageSamplerDescriptor,
} }
impl Default for ImagePlugin { impl Default for ImagePlugin {
@ -58,14 +58,14 @@ impl ImagePlugin {
/// Creates image settings with linear sampling by default. /// Creates image settings with linear sampling by default.
pub fn default_linear() -> ImagePlugin { pub fn default_linear() -> ImagePlugin {
ImagePlugin { ImagePlugin {
default_sampler: ImageSampler::linear_descriptor(), default_sampler: ImageSamplerDescriptor::linear(),
} }
} }
/// Creates image settings with nearest sampling by default. /// Creates image settings with nearest sampling by default.
pub fn default_nearest() -> ImagePlugin { pub fn default_nearest() -> ImagePlugin {
ImagePlugin { ImagePlugin {
default_sampler: ImageSampler::nearest_descriptor(), default_sampler: ImageSamplerDescriptor::nearest(),
} }
} }
} }
@ -137,7 +137,7 @@ impl Plugin for ImagePlugin {
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
let default_sampler = { let default_sampler = {
let device = render_app.world.resource::<RenderDevice>(); let device = render_app.world.resource::<RenderDevice>();
device.create_sampler(&self.default_sampler.clone()) device.create_sampler(&self.default_sampler.as_wgpu())
}; };
render_app render_app
.insert_resource(DefaultImageSampler(default_sampler)) .insert_resource(DefaultImageSampler(default_sampler))

View File

@ -295,10 +295,10 @@ impl FromWorld for Mesh2dPipeline {
let dummy_white_gpu_image = { let dummy_white_gpu_image = {
let image = Image::default(); let image = Image::default();
let texture = render_device.create_texture(&image.texture_descriptor); let texture = render_device.create_texture(&image.texture_descriptor);
let sampler = match image.sampler_descriptor { let sampler = match image.sampler {
ImageSampler::Default => (**default_sampler).clone(), ImageSampler::Default => (**default_sampler).clone(),
ImageSampler::Descriptor(ref descriptor) => { ImageSampler::Descriptor(ref descriptor) => {
render_device.create_sampler(descriptor) render_device.create_sampler(&descriptor.as_wgpu())
} }
}; };

View File

@ -91,10 +91,10 @@ impl FromWorld for SpritePipeline {
let dummy_white_gpu_image = { let dummy_white_gpu_image = {
let image = Image::default(); let image = Image::default();
let texture = render_device.create_texture(&image.texture_descriptor); let texture = render_device.create_texture(&image.texture_descriptor);
let sampler = match image.sampler_descriptor { let sampler = match image.sampler {
ImageSampler::Default => (**default_sampler).clone(), ImageSampler::Default => (**default_sampler).clone(),
ImageSampler::Descriptor(ref descriptor) => { ImageSampler::Descriptor(ref descriptor) => {
render_device.create_sampler(descriptor) render_device.create_sampler(&descriptor.as_wgpu())
} }
}; };

View File

@ -17,8 +17,8 @@ use bevy::{
pbr::CascadeShadowConfigBuilder, pbr::CascadeShadowConfigBuilder,
prelude::*, prelude::*,
render::{ render::{
render_resource::{Extent3d, SamplerDescriptor, TextureDimension, TextureFormat}, render_resource::{Extent3d, TextureDimension, TextureFormat},
texture::ImageSampler, texture::{ImageSampler, ImageSamplerDescriptor},
}, },
}; };
@ -371,6 +371,6 @@ fn uv_debug_texture() -> Image {
&texture_data, &texture_data,
TextureFormat::Rgba8UnormSrgb, TextureFormat::Rgba8UnormSrgb,
); );
img.sampler_descriptor = ImageSampler::Descriptor(SamplerDescriptor::default()); img.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor::default());
img img
} }

View File

@ -7,10 +7,8 @@ use bevy::{
prelude::*, prelude::*,
reflect::TypePath, reflect::TypePath,
render::{ render::{
render_resource::{ render_resource::{AsBindGroup, Extent3d, ShaderRef, TextureDimension, TextureFormat},
AsBindGroup, Extent3d, SamplerDescriptor, ShaderRef, TextureDimension, TextureFormat, texture::{ImageSampler, ImageSamplerDescriptor},
},
texture::ImageSampler,
view::ColorGrading, view::ColorGrading,
}, },
utils::HashMap, utils::HashMap,
@ -681,7 +679,7 @@ fn uv_debug_texture() -> Image {
&texture_data, &texture_data,
TextureFormat::Rgba8UnormSrgb, TextureFormat::Rgba8UnormSrgb,
); );
img.sampler_descriptor = ImageSampler::Descriptor(SamplerDescriptor::default()); img.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor::default());
img img
} }