mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
Update multi-planar texture API (#4837)
This commit is contained in:
parent
411c1e5b21
commit
0cbabcf229
@ -124,7 +124,6 @@ pub fn op_webgpu_create_texture_view(
|
|||||||
format: args.format,
|
format: args.format,
|
||||||
dimension: args.dimension,
|
dimension: args.dimension,
|
||||||
range: args.range,
|
range: args.range,
|
||||||
plane: None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gfx_put!(texture => instance.texture_create_view(
|
gfx_put!(texture => instance.texture_create_view(
|
||||||
|
@ -133,7 +133,6 @@ impl Example {
|
|||||||
mip_level_count: Some(1),
|
mip_level_count: Some(1),
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
array_layer_count: None,
|
array_layer_count: None,
|
||||||
..Default::default()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -398,7 +398,6 @@ impl crate::framework::Example for Example {
|
|||||||
mip_level_count: None,
|
mip_level_count: None,
|
||||||
base_array_layer: i as u32,
|
base_array_layer: i as u32,
|
||||||
array_layer_count: Some(1),
|
array_layer_count: Some(1),
|
||||||
..Default::default()
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -49,7 +49,6 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
|
|||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
mip_level_count: Some(1),
|
mip_level_count: Some(1),
|
||||||
array_layer_count: Some(1),
|
array_layer_count: Some(1),
|
||||||
..Default::default()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let readback_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
let readback_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
@ -49,16 +49,16 @@ static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfigurati
|
|||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
|
view_formats: &[],
|
||||||
});
|
});
|
||||||
let y_view = tex.create_view(&wgpu::TextureViewDescriptor {
|
let y_view = tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
format: Some(wgpu::TextureFormat::R8Unorm),
|
format: Some(wgpu::TextureFormat::R8Unorm),
|
||||||
plane: Some(0),
|
aspect: wgpu::TextureAspect::Plane0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
let uv_view = tex.create_view(&wgpu::TextureViewDescriptor {
|
let uv_view = tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
format: Some(wgpu::TextureFormat::Rg8Unorm),
|
format: Some(wgpu::TextureFormat::Rg8Unorm),
|
||||||
plane: Some(1),
|
aspect: wgpu::TextureAspect::Plane1,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
let sampler = ctx.device.create_sampler(&wgpu::SamplerDescriptor {
|
let sampler = ctx.device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
@ -118,29 +118,6 @@ static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfigurati
|
|||||||
ctx.queue.submit(Some(encoder.finish()));
|
ctx.queue.submit(Some(encoder.finish()));
|
||||||
});
|
});
|
||||||
|
|
||||||
#[gpu_test]
|
|
||||||
static NV12_TEXTURE_CREATION_BAD_VIEW_FORMATS: GpuTestConfiguration = GpuTestConfiguration::new()
|
|
||||||
.parameters(TestParameters::default().features(wgpu::Features::TEXTURE_FORMAT_NV12))
|
|
||||||
.run_sync(|ctx| {
|
|
||||||
let size = wgpu::Extent3d {
|
|
||||||
width: 256,
|
|
||||||
height: 256,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
};
|
|
||||||
fail(&ctx.device, || {
|
|
||||||
let _ = ctx.device.create_texture(&wgpu::TextureDescriptor {
|
|
||||||
label: None,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
size,
|
|
||||||
format: wgpu::TextureFormat::NV12,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
view_formats: &[wgpu::TextureFormat::Rgba8Unorm],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
#[gpu_test]
|
#[gpu_test]
|
||||||
static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration =
|
static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration =
|
||||||
GpuTestConfiguration::new()
|
GpuTestConfiguration::new()
|
||||||
@ -163,7 +140,7 @@ static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration =
|
|||||||
});
|
});
|
||||||
fail(&ctx.device, || {
|
fail(&ctx.device, || {
|
||||||
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
|
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
plane: Some(0),
|
aspect: wgpu::TextureAspect::Plane0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -186,12 +163,12 @@ static NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS: GpuTestConfiguration = GpuTestConf
|
|||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
|
view_formats: &[],
|
||||||
});
|
});
|
||||||
fail(&ctx.device, || {
|
fail(&ctx.device, || {
|
||||||
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
|
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
format: Some(wgpu::TextureFormat::R8Unorm),
|
format: Some(wgpu::TextureFormat::R8Unorm),
|
||||||
plane: Some(2),
|
aspect: wgpu::TextureAspect::Plane2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -214,12 +191,12 @@ static NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE: GpuTestConfiguration = GpuTestConfigu
|
|||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
|
view_formats: &[],
|
||||||
});
|
});
|
||||||
fail(&ctx.device, || {
|
fail(&ctx.device, || {
|
||||||
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
|
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
format: Some(wgpu::TextureFormat::Rg8Unorm),
|
format: Some(wgpu::TextureFormat::Rg8Unorm),
|
||||||
plane: Some(0),
|
aspect: wgpu::TextureAspect::Plane0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -244,7 +221,7 @@ static NV12_TEXTURE_BAD_SIZE: GpuTestConfiguration = GpuTestConfiguration::new()
|
|||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
|
view_formats: &[],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -332,10 +332,7 @@ fn clear_texture_via_buffer_copies<A: HalApi>(
|
|||||||
encoder: &mut A::CommandEncoder,
|
encoder: &mut A::CommandEncoder,
|
||||||
dst_raw: &A::Texture,
|
dst_raw: &A::Texture,
|
||||||
) {
|
) {
|
||||||
assert_eq!(
|
assert!(!texture_desc.format.is_depth_stencil_format());
|
||||||
hal::FormatAspects::from(texture_desc.format),
|
|
||||||
hal::FormatAspects::COLOR
|
|
||||||
);
|
|
||||||
|
|
||||||
if texture_desc.format == wgt::TextureFormat::NV12 {
|
if texture_desc.format == wgt::TextureFormat::NV12 {
|
||||||
// TODO: Currently COPY_DST for NV12 textures is unsupported.
|
// TODO: Currently COPY_DST for NV12 textures is unsupported.
|
||||||
|
@ -666,6 +666,30 @@ impl<A: HalApi> Device<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let (width_multiple, height_multiple) = desc.format.size_multiple_requirement();
|
||||||
|
|
||||||
|
if desc.size.width % width_multiple != 0 {
|
||||||
|
return Err(CreateTextureError::InvalidDimension(
|
||||||
|
TextureDimensionError::WidthNotMultipleOf {
|
||||||
|
width: desc.size.width,
|
||||||
|
multiple: width_multiple,
|
||||||
|
format: desc.format,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if desc.size.height % height_multiple != 0 {
|
||||||
|
return Err(CreateTextureError::InvalidDimension(
|
||||||
|
TextureDimensionError::HeightNotMultipleOf {
|
||||||
|
height: desc.size.height,
|
||||||
|
multiple: height_multiple,
|
||||||
|
format: desc.format,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let format_features = self
|
let format_features = self
|
||||||
.describe_format_features(adapter, desc.format)
|
.describe_format_features(adapter, desc.format)
|
||||||
.map_err(|error| CreateTextureError::MissingFeatures(desc.format, error))?;
|
.map_err(|error| CreateTextureError::MissingFeatures(desc.format, error))?;
|
||||||
@ -751,8 +775,7 @@ impl<A: HalApi> Device<A> {
|
|||||||
if desc.format == *format {
|
if desc.format == *format {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if desc.format.remove_srgb_suffix() != format.remove_srgb_suffix() {
|
||||||
if !check_texture_view_format_compatible(desc.format, *format) {
|
|
||||||
return Err(CreateTextureError::InvalidViewFormat(*format, desc.format));
|
return Err(CreateTextureError::InvalidViewFormat(*format, desc.format));
|
||||||
}
|
}
|
||||||
hal_view_formats.push(*format);
|
hal_view_formats.push(*format);
|
||||||
@ -806,20 +829,19 @@ impl<A: HalApi> Device<A> {
|
|||||||
for mip_level in 0..desc.mip_level_count {
|
for mip_level in 0..desc.mip_level_count {
|
||||||
for array_layer in 0..desc.size.depth_or_array_layers {
|
for array_layer in 0..desc.size.depth_or_array_layers {
|
||||||
macro_rules! push_clear_view {
|
macro_rules! push_clear_view {
|
||||||
($format:expr, $plane:expr) => {
|
($format:expr, $aspect:expr) => {
|
||||||
let desc = hal::TextureViewDescriptor {
|
let desc = hal::TextureViewDescriptor {
|
||||||
label: clear_label,
|
label: clear_label,
|
||||||
format: $format,
|
format: $format,
|
||||||
dimension,
|
dimension,
|
||||||
usage,
|
usage,
|
||||||
range: wgt::ImageSubresourceRange {
|
range: wgt::ImageSubresourceRange {
|
||||||
aspect: wgt::TextureAspect::All,
|
aspect: $aspect,
|
||||||
base_mip_level: mip_level,
|
base_mip_level: mip_level,
|
||||||
mip_level_count: Some(1),
|
mip_level_count: Some(1),
|
||||||
base_array_layer: array_layer,
|
base_array_layer: array_layer,
|
||||||
array_layer_count: Some(1),
|
array_layer_count: Some(1),
|
||||||
},
|
},
|
||||||
plane: $plane,
|
|
||||||
};
|
};
|
||||||
clear_views.push(Some(
|
clear_views.push(Some(
|
||||||
unsafe { self.raw().create_texture_view(&raw_texture, &desc) }
|
unsafe { self.raw().create_texture_view(&raw_texture, &desc) }
|
||||||
@ -828,11 +850,14 @@ impl<A: HalApi> Device<A> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc.format == wgt::TextureFormat::NV12 {
|
if let Some(planes) = desc.format.planes() {
|
||||||
push_clear_view!(wgt::TextureFormat::R8Unorm, Some(0));
|
for plane in 0..planes {
|
||||||
push_clear_view!(wgt::TextureFormat::Rg8Unorm, Some(1));
|
let aspect = wgt::TextureAspect::from_plane(plane).unwrap();
|
||||||
|
let format = desc.format.aspect_specific_format(aspect).unwrap();
|
||||||
|
push_clear_view!(format, aspect);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
push_clear_view!(desc.format, None);
|
push_clear_view!(desc.format, wgt::TextureAspect::All);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1028,8 +1053,6 @@ impl<A: HalApi> Device<A> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
validate_texture_view_plane(texture.desc.format, resolved_format, desc.plane)?;
|
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/#abstract-opdef-renderable-texture-view
|
// https://gpuweb.github.io/gpuweb/#abstract-opdef-renderable-texture-view
|
||||||
let render_extent = 'b: loop {
|
let render_extent = 'b: loop {
|
||||||
if !texture
|
if !texture
|
||||||
@ -1121,7 +1144,6 @@ impl<A: HalApi> Device<A> {
|
|||||||
dimension: resolved_dimension,
|
dimension: resolved_dimension,
|
||||||
usage,
|
usage,
|
||||||
range: resolved_range,
|
range: resolved_range,
|
||||||
plane: desc.plane,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw = unsafe {
|
let raw = unsafe {
|
||||||
@ -1142,6 +1164,7 @@ impl<A: HalApi> Device<A> {
|
|||||||
parent: RwLock::new(Some(texture.clone())),
|
parent: RwLock::new(Some(texture.clone())),
|
||||||
device: self.clone(),
|
device: self.clone(),
|
||||||
desc: resource::HalTextureViewDescriptor {
|
desc: resource::HalTextureViewDescriptor {
|
||||||
|
texture_format: texture.desc.format,
|
||||||
format: resolved_format,
|
format: resolved_format,
|
||||||
dimension: resolved_dimension,
|
dimension: resolved_dimension,
|
||||||
range: resolved_range,
|
range: resolved_range,
|
||||||
@ -3383,39 +3406,3 @@ impl<A: HalApi> Resource<DeviceId> for Device<A> {
|
|||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_texture_view_format_compatible(
|
|
||||||
texture_format: TextureFormat,
|
|
||||||
view_format: TextureFormat,
|
|
||||||
) -> bool {
|
|
||||||
use TextureFormat::*;
|
|
||||||
|
|
||||||
match (texture_format, view_format) {
|
|
||||||
(NV12, R8Unorm | R8Uint | Rg8Unorm | Rg8Uint) => true,
|
|
||||||
_ => texture_format.remove_srgb_suffix() == view_format.remove_srgb_suffix(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_texture_view_plane(
|
|
||||||
texture_format: TextureFormat,
|
|
||||||
view_format: TextureFormat,
|
|
||||||
plane: Option<u32>,
|
|
||||||
) -> Result<(), resource::CreateTextureViewError> {
|
|
||||||
use TextureFormat::*;
|
|
||||||
|
|
||||||
match (texture_format, view_format, plane) {
|
|
||||||
(NV12, R8Unorm | R8Uint, Some(0)) => Ok(()),
|
|
||||||
(NV12, Rg8Unorm | Rg8Uint, Some(1)) => Ok(()),
|
|
||||||
(NV12, _, _) => {
|
|
||||||
Err(resource::CreateTextureViewError::InvalidTextureViewPlane { plane, view_format })
|
|
||||||
}
|
|
||||||
|
|
||||||
(_, _, Some(_)) => Err(
|
|
||||||
resource::CreateTextureViewError::InvalidTextureViewPlaneOnNonplanarTexture {
|
|
||||||
plane,
|
|
||||||
texture_format,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -202,7 +202,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
dimension: wgt::TextureViewDimension::D2,
|
dimension: wgt::TextureViewDimension::D2,
|
||||||
usage: hal::TextureUses::COLOR_TARGET,
|
usage: hal::TextureUses::COLOR_TARGET,
|
||||||
range: wgt::ImageSubresourceRange::default(),
|
range: wgt::ImageSubresourceRange::default(),
|
||||||
plane: None,
|
|
||||||
};
|
};
|
||||||
let clear_view = unsafe {
|
let clear_view = unsafe {
|
||||||
hal::Device::create_texture_view(
|
hal::Device::create_texture_view(
|
||||||
|
@ -892,6 +892,20 @@ pub enum TextureDimensionError {
|
|||||||
block_height: u32,
|
block_height: u32,
|
||||||
format: wgt::TextureFormat,
|
format: wgt::TextureFormat,
|
||||||
},
|
},
|
||||||
|
#[error(
|
||||||
|
"Width {width} is not a multiple of {format:?}'s width multiple requirement ({multiple})"
|
||||||
|
)]
|
||||||
|
WidthNotMultipleOf {
|
||||||
|
width: u32,
|
||||||
|
multiple: u32,
|
||||||
|
format: wgt::TextureFormat,
|
||||||
|
},
|
||||||
|
#[error("Height {height} is not a multiple of {format:?}'s height multiple requirement ({multiple})")]
|
||||||
|
HeightNotMultipleOf {
|
||||||
|
height: u32,
|
||||||
|
multiple: u32,
|
||||||
|
format: wgt::TextureFormat,
|
||||||
|
},
|
||||||
#[error("Multisampled texture depth or array layers must be 1, got {0}")]
|
#[error("Multisampled texture depth or array layers must be 1, got {0}")]
|
||||||
MultisampledDepthOrArrayLayer(u32),
|
MultisampledDepthOrArrayLayer(u32),
|
||||||
}
|
}
|
||||||
@ -978,12 +992,11 @@ pub struct TextureViewDescriptor<'a> {
|
|||||||
pub dimension: Option<wgt::TextureViewDimension>,
|
pub dimension: Option<wgt::TextureViewDimension>,
|
||||||
/// Range within the texture that is accessible via this view.
|
/// Range within the texture that is accessible via this view.
|
||||||
pub range: wgt::ImageSubresourceRange,
|
pub range: wgt::ImageSubresourceRange,
|
||||||
/// The plane of the texture view.
|
|
||||||
pub plane: Option<u32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct HalTextureViewDescriptor {
|
pub(crate) struct HalTextureViewDescriptor {
|
||||||
|
pub texture_format: wgt::TextureFormat,
|
||||||
pub format: wgt::TextureFormat,
|
pub format: wgt::TextureFormat,
|
||||||
pub dimension: wgt::TextureViewDimension,
|
pub dimension: wgt::TextureViewDimension,
|
||||||
pub range: wgt::ImageSubresourceRange,
|
pub range: wgt::ImageSubresourceRange,
|
||||||
@ -991,7 +1004,7 @@ pub(crate) struct HalTextureViewDescriptor {
|
|||||||
|
|
||||||
impl HalTextureViewDescriptor {
|
impl HalTextureViewDescriptor {
|
||||||
pub fn aspects(&self) -> hal::FormatAspects {
|
pub fn aspects(&self) -> hal::FormatAspects {
|
||||||
hal::FormatAspects::new(self.format, self.range.aspect)
|
hal::FormatAspects::new(self.texture_format, self.range.aspect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,16 +1103,6 @@ pub enum CreateTextureViewError {
|
|||||||
texture: wgt::TextureFormat,
|
texture: wgt::TextureFormat,
|
||||||
view: wgt::TextureFormat,
|
view: wgt::TextureFormat,
|
||||||
},
|
},
|
||||||
#[error("Invalid texture view plane `{plane:?}` with view format `{view_format:?}`")]
|
|
||||||
InvalidTextureViewPlane {
|
|
||||||
plane: Option<u32>,
|
|
||||||
view_format: wgt::TextureFormat,
|
|
||||||
},
|
|
||||||
#[error("Invalid texture view plane `{plane:?}` on non-planar texture `{texture_format:?}`")]
|
|
||||||
InvalidTextureViewPlaneOnNonplanarTexture {
|
|
||||||
plane: Option<u32>,
|
|
||||||
texture_format: wgt::TextureFormat,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Error)]
|
#[derive(Clone, Debug, Error)]
|
||||||
|
@ -422,7 +422,6 @@ impl<A: hal::Api> Example<A> {
|
|||||||
dimension: wgt::TextureViewDimension::D2,
|
dimension: wgt::TextureViewDimension::D2,
|
||||||
usage: hal::TextureUses::RESOURCE,
|
usage: hal::TextureUses::RESOURCE,
|
||||||
range: wgt::ImageSubresourceRange::default(),
|
range: wgt::ImageSubresourceRange::default(),
|
||||||
plane: None,
|
|
||||||
};
|
};
|
||||||
let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };
|
let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };
|
||||||
|
|
||||||
@ -661,7 +660,6 @@ impl<A: hal::Api> Example<A> {
|
|||||||
dimension: wgt::TextureViewDimension::D2,
|
dimension: wgt::TextureViewDimension::D2,
|
||||||
usage: hal::TextureUses::COLOR_TARGET,
|
usage: hal::TextureUses::COLOR_TARGET,
|
||||||
range: wgt::ImageSubresourceRange::default(),
|
range: wgt::ImageSubresourceRange::default(),
|
||||||
plane: None,
|
|
||||||
};
|
};
|
||||||
let surface_tex_view = unsafe {
|
let surface_tex_view = unsafe {
|
||||||
self.device
|
self.device
|
||||||
|
@ -142,7 +142,6 @@ fn fill_screen(exposed: &hal::ExposedAdapter<hal::api::Gles>, width: u32, height
|
|||||||
dimension: wgt::TextureViewDimension::D2,
|
dimension: wgt::TextureViewDimension::D2,
|
||||||
usage: hal::TextureUses::COLOR_TARGET,
|
usage: hal::TextureUses::COLOR_TARGET,
|
||||||
range: wgt::ImageSubresourceRange::default(),
|
range: wgt::ImageSubresourceRange::default(),
|
||||||
plane: None,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -555,7 +555,6 @@ impl<A: hal::Api> Example<A> {
|
|||||||
dimension: wgt::TextureViewDimension::D2,
|
dimension: wgt::TextureViewDimension::D2,
|
||||||
usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC,
|
usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC,
|
||||||
range: wgt::ImageSubresourceRange::default(),
|
range: wgt::ImageSubresourceRange::default(),
|
||||||
plane: None,
|
|
||||||
};
|
};
|
||||||
let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };
|
let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };
|
||||||
|
|
||||||
@ -888,7 +887,6 @@ impl<A: hal::Api> Example<A> {
|
|||||||
dimension: wgt::TextureViewDimension::D2,
|
dimension: wgt::TextureViewDimension::D2,
|
||||||
usage: hal::TextureUses::COPY_DST,
|
usage: hal::TextureUses::COPY_DST,
|
||||||
range: wgt::ImageSubresourceRange::default(),
|
range: wgt::ImageSubresourceRange::default(),
|
||||||
plane: None,
|
|
||||||
};
|
};
|
||||||
let surface_tex_view = unsafe {
|
let surface_tex_view = unsafe {
|
||||||
self.device
|
self.device
|
||||||
|
@ -140,9 +140,11 @@ pub fn map_texture_format_for_srv_uav(
|
|||||||
crate::FormatAspects::STENCIL,
|
crate::FormatAspects::STENCIL,
|
||||||
) => dxgiformat::DXGI_FORMAT_X24_TYPELESS_G8_UINT,
|
) => dxgiformat::DXGI_FORMAT_X24_TYPELESS_G8_UINT,
|
||||||
|
|
||||||
(format, crate::FormatAspects::COLOR) => map_texture_format(format),
|
(_, crate::FormatAspects::DEPTH)
|
||||||
|
| (_, crate::FormatAspects::STENCIL)
|
||||||
|
| (_, crate::FormatAspects::DEPTH_STENCIL) => return None,
|
||||||
|
|
||||||
_ => return None,
|
_ => map_texture_format(format),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,6 +415,15 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
|||||||
wgt::TextureAspect::All => 0..2,
|
wgt::TextureAspect::All => 0..2,
|
||||||
wgt::TextureAspect::DepthOnly => 0..1,
|
wgt::TextureAspect::DepthOnly => 0..1,
|
||||||
wgt::TextureAspect::StencilOnly => 1..2,
|
wgt::TextureAspect::StencilOnly => 1..2,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
} else if let Some(planes) = barrier.texture.format.planes() {
|
||||||
|
match barrier.range.aspect {
|
||||||
|
wgt::TextureAspect::All => 0..planes,
|
||||||
|
wgt::TextureAspect::Plane0 => 0..1,
|
||||||
|
wgt::TextureAspect::Plane1 => 1..2,
|
||||||
|
wgt::TextureAspect::Plane2 => 2..3,
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match barrier.texture.format {
|
match barrier.texture.format {
|
||||||
|
@ -467,11 +467,7 @@ impl crate::Device<super::Api> for super::Device {
|
|||||||
aspects: view_desc.aspects,
|
aspects: view_desc.aspects,
|
||||||
target_base: (
|
target_base: (
|
||||||
texture.resource.clone(),
|
texture.resource.clone(),
|
||||||
texture.calc_subresource(
|
texture.calc_subresource(desc.range.base_mip_level, desc.range.base_array_layer, 0),
|
||||||
desc.range.base_mip_level,
|
|
||||||
desc.range.base_array_layer,
|
|
||||||
desc.plane.unwrap_or(0),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
handle_srv: if desc.usage.intersects(crate::TextureUses::RESOURCE) {
|
handle_srv: if desc.usage.intersects(crate::TextureUses::RESOURCE) {
|
||||||
let raw_desc = unsafe { view_desc.to_srv() };
|
let raw_desc = unsafe { view_desc.to_srv() };
|
||||||
|
@ -456,6 +456,7 @@ impl Texture {
|
|||||||
pub struct TextureView {
|
pub struct TextureView {
|
||||||
raw_format: d3d12::Format,
|
raw_format: d3d12::Format,
|
||||||
aspects: crate::FormatAspects,
|
aspects: crate::FormatAspects,
|
||||||
|
/// only used by resolve
|
||||||
target_base: (d3d12::Resource, u32),
|
target_base: (d3d12::Resource, u32),
|
||||||
handle_srv: Option<descriptor::Handle>,
|
handle_srv: Option<descriptor::Handle>,
|
||||||
handle_uav: Option<descriptor::Handle>,
|
handle_uav: Option<descriptor::Handle>,
|
||||||
|
@ -14,12 +14,11 @@ pub(super) struct ViewDescriptor {
|
|||||||
array_layer_count: u32,
|
array_layer_count: u32,
|
||||||
mip_level_base: u32,
|
mip_level_base: u32,
|
||||||
mip_level_count: u32,
|
mip_level_count: u32,
|
||||||
plane: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::TextureViewDescriptor<'_> {
|
impl crate::TextureViewDescriptor<'_> {
|
||||||
pub(super) fn to_internal(&self, texture: &super::Texture) -> ViewDescriptor {
|
pub(super) fn to_internal(&self, texture: &super::Texture) -> ViewDescriptor {
|
||||||
let aspects = crate::FormatAspects::new(self.format, self.range.aspect);
|
let aspects = crate::FormatAspects::new(texture.format, self.range.aspect);
|
||||||
|
|
||||||
ViewDescriptor {
|
ViewDescriptor {
|
||||||
dimension: self.dimension,
|
dimension: self.dimension,
|
||||||
@ -31,11 +30,18 @@ impl crate::TextureViewDescriptor<'_> {
|
|||||||
mip_level_count: self.range.mip_level_count.unwrap_or(!0),
|
mip_level_count: self.range.mip_level_count.unwrap_or(!0),
|
||||||
array_layer_base: self.range.base_array_layer,
|
array_layer_base: self.range.base_array_layer,
|
||||||
array_layer_count: self.range.array_layer_count.unwrap_or(!0),
|
array_layer_count: self.range.array_layer_count.unwrap_or(!0),
|
||||||
plane: self.plane.unwrap_or(0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn aspects_to_plane(aspects: crate::FormatAspects) -> u32 {
|
||||||
|
match aspects {
|
||||||
|
crate::FormatAspects::PLANE_1 => 1,
|
||||||
|
crate::FormatAspects::PLANE_2 => 2,
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ViewDescriptor {
|
impl ViewDescriptor {
|
||||||
pub(crate) unsafe fn to_srv(&self) -> Option<d3d12_ty::D3D12_SHADER_RESOURCE_VIEW_DESC> {
|
pub(crate) unsafe fn to_srv(&self) -> Option<d3d12_ty::D3D12_SHADER_RESOURCE_VIEW_DESC> {
|
||||||
let mut desc = d3d12_ty::D3D12_SHADER_RESOURCE_VIEW_DESC {
|
let mut desc = d3d12_ty::D3D12_SHADER_RESOURCE_VIEW_DESC {
|
||||||
@ -81,7 +87,7 @@ impl ViewDescriptor {
|
|||||||
*desc.u.Texture2D_mut() = d3d12_ty::D3D12_TEX2D_SRV {
|
*desc.u.Texture2D_mut() = d3d12_ty::D3D12_TEX2D_SRV {
|
||||||
MostDetailedMip: self.mip_level_base,
|
MostDetailedMip: self.mip_level_base,
|
||||||
MipLevels: self.mip_level_count,
|
MipLevels: self.mip_level_count,
|
||||||
PlaneSlice: self.plane,
|
PlaneSlice: aspects_to_plane(self.aspects),
|
||||||
ResourceMinLODClamp: 0.0,
|
ResourceMinLODClamp: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +111,7 @@ impl ViewDescriptor {
|
|||||||
MipLevels: self.mip_level_count,
|
MipLevels: self.mip_level_count,
|
||||||
FirstArraySlice: self.array_layer_base,
|
FirstArraySlice: self.array_layer_base,
|
||||||
ArraySize: self.array_layer_count,
|
ArraySize: self.array_layer_count,
|
||||||
PlaneSlice: self.plane,
|
PlaneSlice: aspects_to_plane(self.aspects),
|
||||||
ResourceMinLODClamp: 0.0,
|
ResourceMinLODClamp: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,7 +187,7 @@ impl ViewDescriptor {
|
|||||||
unsafe {
|
unsafe {
|
||||||
*desc.u.Texture2D_mut() = d3d12_ty::D3D12_TEX2D_UAV {
|
*desc.u.Texture2D_mut() = d3d12_ty::D3D12_TEX2D_UAV {
|
||||||
MipSlice: self.mip_level_base,
|
MipSlice: self.mip_level_base,
|
||||||
PlaneSlice: self.plane,
|
PlaneSlice: aspects_to_plane(self.aspects),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +198,7 @@ impl ViewDescriptor {
|
|||||||
MipSlice: self.mip_level_base,
|
MipSlice: self.mip_level_base,
|
||||||
FirstArraySlice: self.array_layer_base,
|
FirstArraySlice: self.array_layer_base,
|
||||||
ArraySize: self.array_layer_count,
|
ArraySize: self.array_layer_count,
|
||||||
PlaneSlice: self.plane,
|
PlaneSlice: aspects_to_plane(self.aspects),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +258,7 @@ impl ViewDescriptor {
|
|||||||
unsafe {
|
unsafe {
|
||||||
*desc.u.Texture2D_mut() = d3d12_ty::D3D12_TEX2D_RTV {
|
*desc.u.Texture2D_mut() = d3d12_ty::D3D12_TEX2D_RTV {
|
||||||
MipSlice: self.mip_level_base,
|
MipSlice: self.mip_level_base,
|
||||||
PlaneSlice: self.plane,
|
PlaneSlice: aspects_to_plane(self.aspects),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,7 +280,7 @@ impl ViewDescriptor {
|
|||||||
MipSlice: self.mip_level_base,
|
MipSlice: self.mip_level_base,
|
||||||
FirstArraySlice: self.array_layer_base,
|
FirstArraySlice: self.array_layer_base,
|
||||||
ArraySize: self.array_layer_count,
|
ArraySize: self.array_layer_count,
|
||||||
PlaneSlice: self.plane,
|
PlaneSlice: aspects_to_plane(self.aspects),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -725,6 +725,11 @@ bitflags!(
|
|||||||
const COLOR = 1 << 0;
|
const COLOR = 1 << 0;
|
||||||
const DEPTH = 1 << 1;
|
const DEPTH = 1 << 1;
|
||||||
const STENCIL = 1 << 2;
|
const STENCIL = 1 << 2;
|
||||||
|
const PLANE_0 = 1 << 3;
|
||||||
|
const PLANE_1 = 1 << 4;
|
||||||
|
const PLANE_2 = 1 << 5;
|
||||||
|
|
||||||
|
const DEPTH_STENCIL = Self::DEPTH.bits() | Self::STENCIL.bits();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -734,6 +739,9 @@ impl FormatAspects {
|
|||||||
wgt::TextureAspect::All => Self::all(),
|
wgt::TextureAspect::All => Self::all(),
|
||||||
wgt::TextureAspect::DepthOnly => Self::DEPTH,
|
wgt::TextureAspect::DepthOnly => Self::DEPTH,
|
||||||
wgt::TextureAspect::StencilOnly => Self::STENCIL,
|
wgt::TextureAspect::StencilOnly => Self::STENCIL,
|
||||||
|
wgt::TextureAspect::Plane0 => Self::PLANE_0,
|
||||||
|
wgt::TextureAspect::Plane1 => Self::PLANE_1,
|
||||||
|
wgt::TextureAspect::Plane2 => Self::PLANE_2,
|
||||||
};
|
};
|
||||||
Self::from(format) & aspect_mask
|
Self::from(format) & aspect_mask
|
||||||
}
|
}
|
||||||
@ -748,6 +756,9 @@ impl FormatAspects {
|
|||||||
Self::COLOR => wgt::TextureAspect::All,
|
Self::COLOR => wgt::TextureAspect::All,
|
||||||
Self::DEPTH => wgt::TextureAspect::DepthOnly,
|
Self::DEPTH => wgt::TextureAspect::DepthOnly,
|
||||||
Self::STENCIL => wgt::TextureAspect::StencilOnly,
|
Self::STENCIL => wgt::TextureAspect::StencilOnly,
|
||||||
|
Self::PLANE_0 => wgt::TextureAspect::Plane0,
|
||||||
|
Self::PLANE_1 => wgt::TextureAspect::Plane1,
|
||||||
|
Self::PLANE_2 => wgt::TextureAspect::Plane2,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -761,8 +772,9 @@ impl From<wgt::TextureFormat> for FormatAspects {
|
|||||||
| wgt::TextureFormat::Depth32Float
|
| wgt::TextureFormat::Depth32Float
|
||||||
| wgt::TextureFormat::Depth24Plus => Self::DEPTH,
|
| wgt::TextureFormat::Depth24Plus => Self::DEPTH,
|
||||||
wgt::TextureFormat::Depth32FloatStencil8 | wgt::TextureFormat::Depth24PlusStencil8 => {
|
wgt::TextureFormat::Depth32FloatStencil8 | wgt::TextureFormat::Depth24PlusStencil8 => {
|
||||||
Self::DEPTH | Self::STENCIL
|
Self::DEPTH_STENCIL
|
||||||
}
|
}
|
||||||
|
wgt::TextureFormat::NV12 => Self::PLANE_0 | Self::PLANE_1,
|
||||||
_ => Self::COLOR,
|
_ => Self::COLOR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1013,7 +1025,6 @@ pub struct TextureViewDescriptor<'a> {
|
|||||||
pub dimension: wgt::TextureViewDimension,
|
pub dimension: wgt::TextureViewDimension,
|
||||||
pub usage: TextureUses,
|
pub usage: TextureUses,
|
||||||
pub range: wgt::ImageSubresourceRange,
|
pub range: wgt::ImageSubresourceRange,
|
||||||
pub plane: Option<u32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -396,7 +396,7 @@ impl crate::Device<super::Api> for super::Device {
|
|||||||
conv::map_texture_view_dimension(desc.dimension)
|
conv::map_texture_view_dimension(desc.dimension)
|
||||||
};
|
};
|
||||||
|
|
||||||
let aspects = crate::FormatAspects::new(desc.format, desc.range.aspect);
|
let aspects = crate::FormatAspects::new(texture.format, desc.range.aspect);
|
||||||
|
|
||||||
let raw_format = self
|
let raw_format = self
|
||||||
.shared
|
.shared
|
||||||
|
@ -30,6 +30,7 @@ pub struct PhysicalDeviceFeatures {
|
|||||||
image_robustness: Option<vk::PhysicalDeviceImageRobustnessFeaturesEXT>,
|
image_robustness: Option<vk::PhysicalDeviceImageRobustnessFeaturesEXT>,
|
||||||
robustness2: Option<vk::PhysicalDeviceRobustness2FeaturesEXT>,
|
robustness2: Option<vk::PhysicalDeviceRobustness2FeaturesEXT>,
|
||||||
multiview: Option<vk::PhysicalDeviceMultiviewFeaturesKHR>,
|
multiview: Option<vk::PhysicalDeviceMultiviewFeaturesKHR>,
|
||||||
|
sampler_ycbcr_conversion: Option<vk::PhysicalDeviceSamplerYcbcrConversionFeatures>,
|
||||||
astc_hdr: Option<vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT>,
|
astc_hdr: Option<vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT>,
|
||||||
shader_float16: Option<(
|
shader_float16: Option<(
|
||||||
vk::PhysicalDeviceShaderFloat16Int8Features,
|
vk::PhysicalDeviceShaderFloat16Int8Features,
|
||||||
@ -273,6 +274,17 @@ impl PhysicalDeviceFeatures {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
sampler_ycbcr_conversion: if device_api_version >= vk::API_VERSION_1_1
|
||||||
|
|| enabled_extensions.contains(&vk::KhrSamplerYcbcrConversionFn::name())
|
||||||
|
{
|
||||||
|
Some(
|
||||||
|
vk::PhysicalDeviceSamplerYcbcrConversionFeatures::builder()
|
||||||
|
// .sampler_ycbcr_conversion(requested_features.contains(wgt::Features::TEXTURE_FORMAT_NV12))
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
astc_hdr: if enabled_extensions.contains(&vk::ExtTextureCompressionAstcHdrFn::name()) {
|
astc_hdr: if enabled_extensions.contains(&vk::ExtTextureCompressionAstcHdrFn::name()) {
|
||||||
Some(
|
Some(
|
||||||
vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT::builder()
|
vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT::builder()
|
||||||
@ -344,7 +356,6 @@ impl PhysicalDeviceFeatures {
|
|||||||
|
|
||||||
fn to_wgpu(
|
fn to_wgpu(
|
||||||
&self,
|
&self,
|
||||||
adapter_info: &wgt::AdapterInfo,
|
|
||||||
instance: &ash::Instance,
|
instance: &ash::Instance,
|
||||||
phd: vk::PhysicalDevice,
|
phd: vk::PhysicalDevice,
|
||||||
caps: &PhysicalDeviceCapabilities,
|
caps: &PhysicalDeviceCapabilities,
|
||||||
@ -595,11 +606,11 @@ impl PhysicalDeviceFeatures {
|
|||||||
F::FLOAT32_FILTERABLE,
|
F::FLOAT32_FILTERABLE,
|
||||||
is_float32_filterable_supported(instance, phd),
|
is_float32_filterable_supported(instance, phd),
|
||||||
);
|
);
|
||||||
features.set(
|
|
||||||
F::TEXTURE_FORMAT_NV12,
|
if let Some(ref _sampler_ycbcr_conversion) = self.sampler_ycbcr_conversion {
|
||||||
(caps.device_api_version >= vk::API_VERSION_1_1
|
features.set(
|
||||||
|| caps.supports_extension(vk::KhrSamplerYcbcrConversionFn::name()))
|
F::TEXTURE_FORMAT_NV12,
|
||||||
&& supports_format(
|
supports_format(
|
||||||
instance,
|
instance,
|
||||||
phd,
|
phd,
|
||||||
vk::Format::G8_B8R8_2PLANE_420_UNORM,
|
vk::Format::G8_B8R8_2PLANE_420_UNORM,
|
||||||
@ -607,9 +618,12 @@ impl PhysicalDeviceFeatures {
|
|||||||
vk::FormatFeatureFlags::SAMPLED_IMAGE
|
vk::FormatFeatureFlags::SAMPLED_IMAGE
|
||||||
| vk::FormatFeatureFlags::TRANSFER_SRC
|
| vk::FormatFeatureFlags::TRANSFER_SRC
|
||||||
| vk::FormatFeatureFlags::TRANSFER_DST,
|
| vk::FormatFeatureFlags::TRANSFER_DST,
|
||||||
)
|
) && !caps
|
||||||
&& !adapter_info.driver.contains("MoltenVK"),
|
.driver
|
||||||
);
|
.map(|driver| driver.driver_id == vk::DriverId::MOLTENVK)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
(features, dl_flags)
|
(features, dl_flags)
|
||||||
}
|
}
|
||||||
@ -693,6 +707,11 @@ impl PhysicalDeviceCapabilities {
|
|||||||
if requested_features.contains(wgt::Features::MULTIVIEW) {
|
if requested_features.contains(wgt::Features::MULTIVIEW) {
|
||||||
extensions.push(vk::KhrMultiviewFn::name());
|
extensions.push(vk::KhrMultiviewFn::name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Require `VK_KHR_sampler_ycbcr_conversion` if the associated feature was requested
|
||||||
|
if requested_features.contains(wgt::Features::TEXTURE_FORMAT_NV12) {
|
||||||
|
extensions.push(vk::KhrSamplerYcbcrConversionFn::name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.device_api_version < vk::API_VERSION_1_2 {
|
if self.device_api_version < vk::API_VERSION_1_2 {
|
||||||
@ -944,6 +963,16 @@ impl super::InstanceShared {
|
|||||||
builder = builder.push_next(next);
|
builder = builder.push_next(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `VK_KHR_sampler_ycbcr_conversion` is promoted to 1.1
|
||||||
|
if capabilities.device_api_version >= vk::API_VERSION_1_1
|
||||||
|
|| capabilities.supports_extension(vk::KhrSamplerYcbcrConversionFn::name())
|
||||||
|
{
|
||||||
|
let next = features
|
||||||
|
.sampler_ycbcr_conversion
|
||||||
|
.insert(vk::PhysicalDeviceSamplerYcbcrConversionFeatures::default());
|
||||||
|
builder = builder.push_next(next);
|
||||||
|
}
|
||||||
|
|
||||||
if capabilities.supports_extension(vk::ExtDescriptorIndexingFn::name()) {
|
if capabilities.supports_extension(vk::ExtDescriptorIndexingFn::name()) {
|
||||||
let next = features
|
let next = features
|
||||||
.descriptor_indexing
|
.descriptor_indexing
|
||||||
@ -1074,7 +1103,7 @@ impl super::Instance {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (available_features, downlevel_flags) =
|
let (available_features, downlevel_flags) =
|
||||||
phd_features.to_wgpu(&info, &self.shared.raw, phd, &phd_capabilities);
|
phd_features.to_wgpu(&self.shared.raw, phd, &phd_capabilities);
|
||||||
let mut workarounds = super::Workarounds::empty();
|
let mut workarounds = super::Workarounds::empty();
|
||||||
{
|
{
|
||||||
// TODO: only enable for particular devices
|
// TODO: only enable for particular devices
|
||||||
@ -1671,14 +1700,14 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
|||||||
.framebuffer_stencil_sample_counts
|
.framebuffer_stencil_sample_counts
|
||||||
.min(limits.sampled_image_stencil_sample_counts)
|
.min(limits.sampled_image_stencil_sample_counts)
|
||||||
} else {
|
} else {
|
||||||
match format.sample_type(None, None) {
|
match format.sample_type(None, None).unwrap() {
|
||||||
Some(wgt::TextureSampleType::Float { .. }) => limits
|
wgt::TextureSampleType::Float { .. } => limits
|
||||||
.framebuffer_color_sample_counts
|
.framebuffer_color_sample_counts
|
||||||
.min(limits.sampled_image_color_sample_counts),
|
.min(limits.sampled_image_color_sample_counts),
|
||||||
Some(wgt::TextureSampleType::Sint) | Some(wgt::TextureSampleType::Uint) => {
|
wgt::TextureSampleType::Sint | wgt::TextureSampleType::Uint => {
|
||||||
limits.sampled_image_integer_sample_counts
|
limits.sampled_image_integer_sample_counts
|
||||||
}
|
}
|
||||||
_ => vk::SampleCountFlags::TYPE_1,
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ pub fn derive_image_layout(
|
|||||||
format: wgt::TextureFormat,
|
format: wgt::TextureFormat,
|
||||||
) -> vk::ImageLayout {
|
) -> vk::ImageLayout {
|
||||||
// Note: depth textures are always sampled with RODS layout
|
// Note: depth textures are always sampled with RODS layout
|
||||||
let is_color = crate::FormatAspects::from(format).contains(crate::FormatAspects::COLOR);
|
let is_color = !format.is_depth_stencil_format();
|
||||||
match usage {
|
match usage {
|
||||||
crate::TextureUses::UNINITIALIZED => vk::ImageLayout::UNDEFINED,
|
crate::TextureUses::UNINITIALIZED => vk::ImageLayout::UNDEFINED,
|
||||||
crate::TextureUses::COPY_SRC => vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
|
crate::TextureUses::COPY_SRC => vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
|
||||||
@ -402,18 +402,10 @@ pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> vk::Format {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_aspects(aspects: crate::FormatAspects, plane: Option<u32>) -> vk::ImageAspectFlags {
|
pub fn map_aspects(aspects: crate::FormatAspects) -> vk::ImageAspectFlags {
|
||||||
let mut flags = vk::ImageAspectFlags::empty();
|
let mut flags = vk::ImageAspectFlags::empty();
|
||||||
match plane {
|
if aspects.contains(crate::FormatAspects::COLOR) {
|
||||||
Some(0) => flags |= vk::ImageAspectFlags::PLANE_0,
|
flags |= vk::ImageAspectFlags::COLOR;
|
||||||
Some(1) => flags |= vk::ImageAspectFlags::PLANE_1,
|
|
||||||
Some(2) => flags |= vk::ImageAspectFlags::PLANE_2,
|
|
||||||
Some(plane) => panic!("Unexpected plane {}", plane),
|
|
||||||
None => {
|
|
||||||
if aspects.contains(crate::FormatAspects::COLOR) {
|
|
||||||
flags |= vk::ImageAspectFlags::COLOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if aspects.contains(crate::FormatAspects::DEPTH) {
|
if aspects.contains(crate::FormatAspects::DEPTH) {
|
||||||
flags |= vk::ImageAspectFlags::DEPTH;
|
flags |= vk::ImageAspectFlags::DEPTH;
|
||||||
@ -421,6 +413,15 @@ pub fn map_aspects(aspects: crate::FormatAspects, plane: Option<u32>) -> vk::Ima
|
|||||||
if aspects.contains(crate::FormatAspects::STENCIL) {
|
if aspects.contains(crate::FormatAspects::STENCIL) {
|
||||||
flags |= vk::ImageAspectFlags::STENCIL;
|
flags |= vk::ImageAspectFlags::STENCIL;
|
||||||
}
|
}
|
||||||
|
if aspects.contains(crate::FormatAspects::PLANE_0) {
|
||||||
|
flags |= vk::ImageAspectFlags::PLANE_0;
|
||||||
|
}
|
||||||
|
if aspects.contains(crate::FormatAspects::PLANE_1) {
|
||||||
|
flags |= vk::ImageAspectFlags::PLANE_1;
|
||||||
|
}
|
||||||
|
if aspects.contains(crate::FormatAspects::PLANE_2) {
|
||||||
|
flags |= vk::ImageAspectFlags::PLANE_2;
|
||||||
|
}
|
||||||
flags
|
flags
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,10 +615,9 @@ pub fn map_copy_extent(extent: &crate::CopyExtent) -> vk::Extent3D {
|
|||||||
pub fn map_subresource_range(
|
pub fn map_subresource_range(
|
||||||
range: &wgt::ImageSubresourceRange,
|
range: &wgt::ImageSubresourceRange,
|
||||||
format: wgt::TextureFormat,
|
format: wgt::TextureFormat,
|
||||||
plane: Option<u32>,
|
|
||||||
) -> vk::ImageSubresourceRange {
|
) -> vk::ImageSubresourceRange {
|
||||||
vk::ImageSubresourceRange {
|
vk::ImageSubresourceRange {
|
||||||
aspect_mask: map_aspects(crate::FormatAspects::new(format, range.aspect), plane),
|
aspect_mask: map_aspects(crate::FormatAspects::new(format, range.aspect)),
|
||||||
base_mip_level: range.base_mip_level,
|
base_mip_level: range.base_mip_level,
|
||||||
level_count: range.mip_level_count.unwrap_or(vk::REMAINING_MIP_LEVELS),
|
level_count: range.mip_level_count.unwrap_or(vk::REMAINING_MIP_LEVELS),
|
||||||
base_array_layer: range.base_array_layer,
|
base_array_layer: range.base_array_layer,
|
||||||
@ -634,7 +634,7 @@ pub(super) fn map_subresource_range_combined_aspect(
|
|||||||
format: wgt::TextureFormat,
|
format: wgt::TextureFormat,
|
||||||
private_caps: &super::PrivateCapabilities,
|
private_caps: &super::PrivateCapabilities,
|
||||||
) -> vk::ImageSubresourceRange {
|
) -> vk::ImageSubresourceRange {
|
||||||
let mut range = map_subresource_range(range, format, None);
|
let mut range = map_subresource_range(range, format);
|
||||||
if !private_caps.texture_s8 && format == wgt::TextureFormat::Stencil8 {
|
if !private_caps.texture_s8 && format == wgt::TextureFormat::Stencil8 {
|
||||||
range.aspect_mask |= vk::ImageAspectFlags::DEPTH;
|
range.aspect_mask |= vk::ImageAspectFlags::DEPTH;
|
||||||
}
|
}
|
||||||
@ -650,7 +650,7 @@ pub fn map_subresource_layers(
|
|||||||
z: base.origin.z as i32,
|
z: base.origin.z as i32,
|
||||||
};
|
};
|
||||||
let subresource = vk::ImageSubresourceLayers {
|
let subresource = vk::ImageSubresourceLayers {
|
||||||
aspect_mask: map_aspects(base.aspect, None),
|
aspect_mask: map_aspects(base.aspect),
|
||||||
mip_level: base.mip_level,
|
mip_level: base.mip_level,
|
||||||
base_array_layer: base.array_layer,
|
base_array_layer: base.array_layer,
|
||||||
layer_count: 1,
|
layer_count: 1,
|
||||||
|
@ -667,6 +667,9 @@ impl super::Device {
|
|||||||
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE;
|
vk::ImageCreateFlags::MUTABLE_FORMAT | vk::ImageCreateFlags::EXTENDED_USAGE;
|
||||||
view_formats.push(desc.format)
|
view_formats.push(desc.format)
|
||||||
}
|
}
|
||||||
|
if desc.format.is_multi_planar_format() {
|
||||||
|
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
super::Texture {
|
super::Texture {
|
||||||
raw: vk_image,
|
raw: vk_image,
|
||||||
@ -989,7 +992,7 @@ impl crate::Device<super::Api> for super::Device {
|
|||||||
wgt_view_formats = desc.view_formats.clone();
|
wgt_view_formats = desc.view_formats.clone();
|
||||||
wgt_view_formats.push(desc.format);
|
wgt_view_formats.push(desc.format);
|
||||||
|
|
||||||
if self.shared.private_caps.image_format_list && !desc.format.is_multi_planar_format() {
|
if self.shared.private_caps.image_format_list {
|
||||||
vk_view_formats = desc
|
vk_view_formats = desc
|
||||||
.view_formats
|
.view_formats
|
||||||
.iter()
|
.iter()
|
||||||
@ -998,6 +1001,9 @@ impl crate::Device<super::Api> for super::Device {
|
|||||||
vk_view_formats.push(original_format)
|
vk_view_formats.push(original_format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if desc.format.is_multi_planar_format() {
|
||||||
|
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
let mut vk_info = vk::ImageCreateInfo::builder()
|
let mut vk_info = vk::ImageCreateInfo::builder()
|
||||||
.flags(raw_flags)
|
.flags(raw_flags)
|
||||||
@ -1071,7 +1077,7 @@ impl crate::Device<super::Api> for super::Device {
|
|||||||
texture: &super::Texture,
|
texture: &super::Texture,
|
||||||
desc: &crate::TextureViewDescriptor,
|
desc: &crate::TextureViewDescriptor,
|
||||||
) -> Result<super::TextureView, crate::DeviceError> {
|
) -> Result<super::TextureView, crate::DeviceError> {
|
||||||
let subresource_range = conv::map_subresource_range(&desc.range, desc.format, desc.plane);
|
let subresource_range = conv::map_subresource_range(&desc.range, texture.format);
|
||||||
let mut vk_info = vk::ImageViewCreateInfo::builder()
|
let mut vk_info = vk::ImageViewCreateInfo::builder()
|
||||||
.flags(vk::ImageViewCreateFlags::empty())
|
.flags(vk::ImageViewCreateFlags::empty())
|
||||||
.image(texture.raw)
|
.image(texture.raw)
|
||||||
|
@ -2411,9 +2411,9 @@ pub enum TextureFormat {
|
|||||||
/// - 0: Single 8 bit channel luminance.
|
/// - 0: Single 8 bit channel luminance.
|
||||||
/// - 1: Dual 8 bit channel chrominance at half width and half height.
|
/// - 1: Dual 8 bit channel chrominance at half width and half height.
|
||||||
///
|
///
|
||||||
/// Valid view formats for luminance are [`TextureFormat::R8Unorm`] and [`TextureFormat::R8Uint`].
|
/// Valid view formats for luminance are [`TextureFormat::R8Unorm`].
|
||||||
///
|
///
|
||||||
/// Valid view formats for chrominance are [`TextureFormat::Rg8Unorm`] and [`TextureFormat::Rg8Uint`].
|
/// Valid view formats for chrominance are [`TextureFormat::Rg8Unorm`].
|
||||||
///
|
///
|
||||||
/// Width and height must be even.
|
/// Width and height must be even.
|
||||||
///
|
///
|
||||||
@ -2835,6 +2835,18 @@ impl Serialize for TextureFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TextureAspect {
|
||||||
|
/// Returns the texture aspect for a given plane.
|
||||||
|
pub fn from_plane(plane: u32) -> Option<Self> {
|
||||||
|
Some(match plane {
|
||||||
|
0 => Self::Plane0,
|
||||||
|
1 => Self::Plane1,
|
||||||
|
2 => Self::Plane2,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TextureFormat {
|
impl TextureFormat {
|
||||||
/// Returns the aspect-specific format of the original format
|
/// Returns the aspect-specific format of the original format
|
||||||
///
|
///
|
||||||
@ -2852,7 +2864,10 @@ impl TextureFormat {
|
|||||||
) => Some(Self::Stencil8),
|
) => Some(Self::Stencil8),
|
||||||
(Self::Depth24PlusStencil8, TextureAspect::DepthOnly) => Some(Self::Depth24Plus),
|
(Self::Depth24PlusStencil8, TextureAspect::DepthOnly) => Some(Self::Depth24Plus),
|
||||||
(Self::Depth32FloatStencil8, TextureAspect::DepthOnly) => Some(Self::Depth32Float),
|
(Self::Depth32FloatStencil8, TextureAspect::DepthOnly) => Some(Self::Depth32Float),
|
||||||
(format, TextureAspect::All) => Some(format),
|
(Self::NV12, TextureAspect::Plane0) => Some(Self::R8Unorm),
|
||||||
|
(Self::NV12, TextureAspect::Plane1) => Some(Self::Rg8Unorm),
|
||||||
|
// views to multi-planar formats must specify the plane
|
||||||
|
(format, TextureAspect::All) if !format.is_multi_planar_format() => Some(format),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2894,7 +2909,15 @@ impl TextureFormat {
|
|||||||
|
|
||||||
/// Returns `true` if the format is a multi-planar format
|
/// Returns `true` if the format is a multi-planar format
|
||||||
pub fn is_multi_planar_format(&self) -> bool {
|
pub fn is_multi_planar_format(&self) -> bool {
|
||||||
matches!(*self, Self::NV12)
|
self.planes().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of planes a multi-planar format has.
|
||||||
|
pub fn planes(&self) -> Option<u32> {
|
||||||
|
match *self {
|
||||||
|
Self::NV12 => Some(2),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the format has a color aspect
|
/// Returns `true` if the format has a color aspect
|
||||||
@ -2922,6 +2945,14 @@ impl TextureFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the size multiple requirement for a texture using this format.
|
||||||
|
pub fn size_multiple_requirement(&self) -> (u32, u32) {
|
||||||
|
match *self {
|
||||||
|
Self::NV12 => (2, 2),
|
||||||
|
_ => self.block_dimensions(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the dimension of a [block](https://gpuweb.github.io/gpuweb/#texel-block) of texels.
|
/// Returns the dimension of a [block](https://gpuweb.github.io/gpuweb/#texel-block) of texels.
|
||||||
///
|
///
|
||||||
/// Uncompressed formats have a block dimension of `(1, 1)`.
|
/// Uncompressed formats have a block dimension of `(1, 1)`.
|
||||||
@ -2975,9 +3006,8 @@ impl TextureFormat {
|
|||||||
| Self::Depth24Plus
|
| Self::Depth24Plus
|
||||||
| Self::Depth24PlusStencil8
|
| Self::Depth24PlusStencil8
|
||||||
| Self::Depth32Float
|
| Self::Depth32Float
|
||||||
| Self::Depth32FloatStencil8 => (1, 1),
|
| Self::Depth32FloatStencil8
|
||||||
|
| Self::NV12 => (1, 1),
|
||||||
Self::NV12 => (2, 2),
|
|
||||||
|
|
||||||
Self::Bc1RgbaUnorm
|
Self::Bc1RgbaUnorm
|
||||||
| Self::Bc1RgbaUnormSrgb
|
| Self::Bc1RgbaUnormSrgb
|
||||||
@ -3253,16 +3283,17 @@ impl TextureFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the sample type compatible with this format and aspect
|
/// Returns the sample type compatible with this format and aspect.
|
||||||
///
|
///
|
||||||
/// Returns `None` only if the format is combined depth-stencil
|
/// Returns `None` only if this is a combined depth-stencil format or a multi-planar format
|
||||||
/// and `TextureAspect::All` or no `aspect` was provided
|
/// and `TextureAspect::All` or no `aspect` was provided.
|
||||||
pub fn sample_type(
|
pub fn sample_type(
|
||||||
&self,
|
&self,
|
||||||
aspect: Option<TextureAspect>,
|
aspect: Option<TextureAspect>,
|
||||||
device_features: Option<Features>,
|
device_features: Option<Features>,
|
||||||
) -> Option<TextureSampleType> {
|
) -> Option<TextureSampleType> {
|
||||||
let float = TextureSampleType::Float { filterable: true };
|
let float = TextureSampleType::Float { filterable: true };
|
||||||
|
let unfilterable_float = TextureSampleType::Float { filterable: false };
|
||||||
let float32_sample_type = TextureSampleType::Float {
|
let float32_sample_type = TextureSampleType::Float {
|
||||||
filterable: device_features
|
filterable: device_features
|
||||||
.unwrap_or(Features::empty())
|
.unwrap_or(Features::empty())
|
||||||
@ -3314,12 +3345,17 @@ impl TextureFormat {
|
|||||||
Self::Stencil8 => Some(uint),
|
Self::Stencil8 => Some(uint),
|
||||||
Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => Some(depth),
|
Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => Some(depth),
|
||||||
Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
|
Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
|
||||||
None | Some(TextureAspect::All) => None,
|
|
||||||
Some(TextureAspect::DepthOnly) => Some(depth),
|
Some(TextureAspect::DepthOnly) => Some(depth),
|
||||||
Some(TextureAspect::StencilOnly) => Some(uint),
|
Some(TextureAspect::StencilOnly) => Some(uint),
|
||||||
|
_ => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
Self::NV12 => None,
|
Self::NV12 => match aspect {
|
||||||
|
Some(TextureAspect::Plane0) | Some(TextureAspect::Plane1) => {
|
||||||
|
Some(unfilterable_float)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
|
||||||
Self::R16Unorm
|
Self::R16Unorm
|
||||||
| Self::R16Snorm
|
| Self::R16Snorm
|
||||||
@ -3368,7 +3404,8 @@ impl TextureFormat {
|
|||||||
/// since uncompressed formats have a block size of 1x1.
|
/// since uncompressed formats have a block size of 1x1.
|
||||||
///
|
///
|
||||||
/// Returns `None` if any of the following are true:
|
/// Returns `None` if any of the following are true:
|
||||||
/// - the format is combined depth-stencil and no `aspect` was provided
|
/// - the format is a combined depth-stencil and no `aspect` was provided
|
||||||
|
/// - the format is a multi-planar format and no `aspect` was provided
|
||||||
/// - the format is `Depth24Plus`
|
/// - the format is `Depth24Plus`
|
||||||
/// - the format is `Depth24PlusStencil8` and `aspect` is depth.
|
/// - the format is `Depth24PlusStencil8` and `aspect` is depth.
|
||||||
#[deprecated(since = "0.19.0", note = "Use `block_copy_size` instead.")]
|
#[deprecated(since = "0.19.0", note = "Use `block_copy_size` instead.")]
|
||||||
@ -3384,7 +3421,8 @@ impl TextureFormat {
|
|||||||
/// since uncompressed formats have a block size of 1x1.
|
/// since uncompressed formats have a block size of 1x1.
|
||||||
///
|
///
|
||||||
/// Returns `None` if any of the following are true:
|
/// Returns `None` if any of the following are true:
|
||||||
/// - the format is combined depth-stencil and no `aspect` was provided
|
/// - the format is a combined depth-stencil and no `aspect` was provided
|
||||||
|
/// - the format is a multi-planar format and no `aspect` was provided
|
||||||
/// - the format is `Depth24Plus`
|
/// - the format is `Depth24Plus`
|
||||||
/// - the format is `Depth24PlusStencil8` and `aspect` is depth.
|
/// - the format is `Depth24PlusStencil8` and `aspect` is depth.
|
||||||
pub fn block_copy_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
|
pub fn block_copy_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
|
||||||
@ -3427,17 +3465,21 @@ impl TextureFormat {
|
|||||||
Self::Depth32Float => Some(4),
|
Self::Depth32Float => Some(4),
|
||||||
Self::Depth24Plus => None,
|
Self::Depth24Plus => None,
|
||||||
Self::Depth24PlusStencil8 => match aspect {
|
Self::Depth24PlusStencil8 => match aspect {
|
||||||
None | Some(TextureAspect::All) => None,
|
|
||||||
Some(TextureAspect::DepthOnly) => None,
|
Some(TextureAspect::DepthOnly) => None,
|
||||||
Some(TextureAspect::StencilOnly) => Some(1),
|
Some(TextureAspect::StencilOnly) => Some(1),
|
||||||
|
_ => None,
|
||||||
},
|
},
|
||||||
Self::Depth32FloatStencil8 => match aspect {
|
Self::Depth32FloatStencil8 => match aspect {
|
||||||
None | Some(TextureAspect::All) => None,
|
|
||||||
Some(TextureAspect::DepthOnly) => Some(4),
|
Some(TextureAspect::DepthOnly) => Some(4),
|
||||||
Some(TextureAspect::StencilOnly) => Some(1),
|
Some(TextureAspect::StencilOnly) => Some(1),
|
||||||
|
_ => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
Self::NV12 => None,
|
Self::NV12 => match aspect {
|
||||||
|
Some(TextureAspect::Plane0) => Some(1),
|
||||||
|
Some(TextureAspect::Plane1) => Some(2),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
|
||||||
Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb | Self::Bc4RUnorm | Self::Bc4RSnorm => {
|
Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb | Self::Bc4RUnorm | Self::Bc4RSnorm => {
|
||||||
Some(8)
|
Some(8)
|
||||||
@ -3475,7 +3517,7 @@ impl TextureFormat {
|
|||||||
|
|
||||||
/// Returns the number of components this format has taking into account the `aspect`.
|
/// Returns the number of components this format has taking into account the `aspect`.
|
||||||
///
|
///
|
||||||
/// The `aspect` is only relevant for combined depth-stencil formats.
|
/// The `aspect` is only relevant for combined depth-stencil formats and multi-planar formats.
|
||||||
pub fn components_with_aspect(&self, aspect: TextureAspect) -> u8 {
|
pub fn components_with_aspect(&self, aspect: TextureAspect) -> u8 {
|
||||||
match *self {
|
match *self {
|
||||||
Self::R8Unorm
|
Self::R8Unorm
|
||||||
@ -3526,11 +3568,15 @@ impl TextureFormat {
|
|||||||
Self::Stencil8 | Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => 1,
|
Self::Stencil8 | Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => 1,
|
||||||
|
|
||||||
Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
|
Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
|
||||||
TextureAspect::All => 2,
|
|
||||||
TextureAspect::DepthOnly | TextureAspect::StencilOnly => 1,
|
TextureAspect::DepthOnly | TextureAspect::StencilOnly => 1,
|
||||||
|
_ => 2,
|
||||||
},
|
},
|
||||||
|
|
||||||
Self::NV12 => 3,
|
Self::NV12 => match aspect {
|
||||||
|
TextureAspect::Plane0 => 1,
|
||||||
|
TextureAspect::Plane1 => 2,
|
||||||
|
_ => 3,
|
||||||
|
},
|
||||||
|
|
||||||
Self::Bc4RUnorm | Self::Bc4RSnorm => 1,
|
Self::Bc4RUnorm | Self::Bc4RSnorm => 1,
|
||||||
Self::Bc5RgUnorm | Self::Bc5RgSnorm => 2,
|
Self::Bc5RgUnorm | Self::Bc5RgSnorm => 2,
|
||||||
@ -5633,6 +5679,12 @@ pub enum TextureAspect {
|
|||||||
StencilOnly,
|
StencilOnly,
|
||||||
/// Depth.
|
/// Depth.
|
||||||
DepthOnly,
|
DepthOnly,
|
||||||
|
/// Plane 0.
|
||||||
|
Plane0,
|
||||||
|
/// Plane 1.
|
||||||
|
Plane1,
|
||||||
|
/// Plane 2.
|
||||||
|
Plane2,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How edges should be handled in texture addressing.
|
/// How edges should be handled in texture addressing.
|
||||||
|
@ -1610,7 +1610,6 @@ impl crate::Context for Context {
|
|||||||
base_array_layer: desc.base_array_layer,
|
base_array_layer: desc.base_array_layer,
|
||||||
array_layer_count: desc.array_layer_count,
|
array_layer_count: desc.array_layer_count,
|
||||||
},
|
},
|
||||||
plane: desc.plane,
|
|
||||||
};
|
};
|
||||||
let global = &self.0;
|
let global = &self.0;
|
||||||
let (id, error) = wgc::gfx_select!(
|
let (id, error) = wgc::gfx_select!(
|
||||||
|
@ -606,6 +606,9 @@ fn map_texture_aspect(aspect: wgt::TextureAspect) -> web_sys::GpuTextureAspect {
|
|||||||
wgt::TextureAspect::All => web_sys::GpuTextureAspect::All,
|
wgt::TextureAspect::All => web_sys::GpuTextureAspect::All,
|
||||||
wgt::TextureAspect::StencilOnly => web_sys::GpuTextureAspect::StencilOnly,
|
wgt::TextureAspect::StencilOnly => web_sys::GpuTextureAspect::StencilOnly,
|
||||||
wgt::TextureAspect::DepthOnly => web_sys::GpuTextureAspect::DepthOnly,
|
wgt::TextureAspect::DepthOnly => web_sys::GpuTextureAspect::DepthOnly,
|
||||||
|
wgt::TextureAspect::Plane0 | wgt::TextureAspect::Plane1 | wgt::TextureAspect::Plane2 => {
|
||||||
|
panic!("multi-plane textures are not supported")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,8 +1301,6 @@ pub struct TextureViewDescriptor<'a> {
|
|||||||
/// If `Some(count)`, `base_array_layer + count` must be less or equal to the underlying array count.
|
/// If `Some(count)`, `base_array_layer + count` must be less or equal to the underlying array count.
|
||||||
/// If `None`, considered to include the rest of the array layers, but at least 1 in total.
|
/// If `None`, considered to include the rest of the array layers, but at least 1 in total.
|
||||||
pub array_layer_count: Option<u32>,
|
pub array_layer_count: Option<u32>,
|
||||||
/// The index (plane slice number) of the plane to use in the texture.
|
|
||||||
pub plane: Option<u32>,
|
|
||||||
}
|
}
|
||||||
static_assertions::assert_impl_all!(TextureViewDescriptor<'_>: Send, Sync);
|
static_assertions::assert_impl_all!(TextureViewDescriptor<'_>: Send, Sync);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user