Skip to content

Commit

Permalink
Update multi-planar texture API (#4837)
Browse files Browse the repository at this point in the history
  • Loading branch information
teoxoy authored Dec 7, 2023
1 parent 411c1e5 commit 0cbabcf
Show file tree
Hide file tree
Showing 26 changed files with 247 additions and 181 deletions.
1 change: 0 additions & 1 deletion deno_webgpu/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ pub fn op_webgpu_create_texture_view(
format: args.format,
dimension: args.dimension,
range: args.range,
plane: None,
};

gfx_put!(texture => instance.texture_create_view(
Expand Down
1 change: 0 additions & 1 deletion examples/src/mipmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ impl Example {
mip_level_count: Some(1),
base_array_layer: 0,
array_layer_count: None,
..Default::default()
})
})
.collect::<Vec<_>>();
Expand Down
1 change: 0 additions & 1 deletion examples/src/shadow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,6 @@ impl crate::framework::Example for Example {
mip_level_count: None,
base_array_layer: i as u32,
array_layer_count: Some(1),
..Default::default()
}))
})
.collect::<Vec<_>>();
Expand Down
1 change: 0 additions & 1 deletion tests/tests/bgra8unorm_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
base_array_layer: 0,
mip_level_count: Some(1),
array_layer_count: Some(1),
..Default::default()
});

let readback_buffer = device.create_buffer(&wgpu::BufferDescriptor {
Expand Down
41 changes: 9 additions & 32 deletions tests/tests/nv12_texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfigurati
usage: wgpu::TextureUsages::TEXTURE_BINDING,
mip_level_count: 1,
sample_count: 1,
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
view_formats: &[],
});
let y_view = tex.create_view(&wgpu::TextureViewDescriptor {
format: Some(wgpu::TextureFormat::R8Unorm),
plane: Some(0),
aspect: wgpu::TextureAspect::Plane0,
..Default::default()
});
let uv_view = tex.create_view(&wgpu::TextureViewDescriptor {
format: Some(wgpu::TextureFormat::Rg8Unorm),
plane: Some(1),
aspect: wgpu::TextureAspect::Plane1,
..Default::default()
});
let sampler = ctx.device.create_sampler(&wgpu::SamplerDescriptor {
Expand Down Expand Up @@ -118,29 +118,6 @@ static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfigurati
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]
static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration =
GpuTestConfiguration::new()
Expand All @@ -163,7 +140,7 @@ static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration =
});
fail(&ctx.device, || {
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
plane: Some(0),
aspect: wgpu::TextureAspect::Plane0,
..Default::default()
});
});
Expand All @@ -186,12 +163,12 @@ static NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS: GpuTestConfiguration = GpuTestConf
usage: wgpu::TextureUsages::TEXTURE_BINDING,
mip_level_count: 1,
sample_count: 1,
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
view_formats: &[],
});
fail(&ctx.device, || {
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
format: Some(wgpu::TextureFormat::R8Unorm),
plane: Some(2),
aspect: wgpu::TextureAspect::Plane2,
..Default::default()
});
});
Expand All @@ -214,12 +191,12 @@ static NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE: GpuTestConfiguration = GpuTestConfigu
usage: wgpu::TextureUsages::TEXTURE_BINDING,
mip_level_count: 1,
sample_count: 1,
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
view_formats: &[],
});
fail(&ctx.device, || {
let _ = tex.create_view(&wgpu::TextureViewDescriptor {
format: Some(wgpu::TextureFormat::Rg8Unorm),
plane: Some(0),
aspect: wgpu::TextureAspect::Plane0,
..Default::default()
});
});
Expand All @@ -244,7 +221,7 @@ static NV12_TEXTURE_BAD_SIZE: GpuTestConfiguration = GpuTestConfiguration::new()
usage: wgpu::TextureUsages::TEXTURE_BINDING,
mip_level_count: 1,
sample_count: 1,
view_formats: &[wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::Rg8Unorm],
view_formats: &[],
});
});
});
5 changes: 1 addition & 4 deletions wgpu-core/src/command/clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,7 @@ fn clear_texture_via_buffer_copies<A: HalApi>(
encoder: &mut A::CommandEncoder,
dst_raw: &A::Texture,
) {
assert_eq!(
hal::FormatAspects::from(texture_desc.format),
hal::FormatAspects::COLOR
);
assert!(!texture_desc.format.is_depth_stencil_format());

if texture_desc.format == wgt::TextureFormat::NV12 {
// TODO: Currently COPY_DST for NV12 textures is unsupported.
Expand Down
83 changes: 35 additions & 48 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
.describe_format_features(adapter, desc.format)
.map_err(|error| CreateTextureError::MissingFeatures(desc.format, error))?;
Expand Down Expand Up @@ -751,8 +775,7 @@ impl<A: HalApi> Device<A> {
if desc.format == *format {
continue;
}

if !check_texture_view_format_compatible(desc.format, *format) {
if desc.format.remove_srgb_suffix() != format.remove_srgb_suffix() {
return Err(CreateTextureError::InvalidViewFormat(*format, desc.format));
}
hal_view_formats.push(*format);
Expand Down Expand Up @@ -806,20 +829,19 @@ impl<A: HalApi> Device<A> {
for mip_level in 0..desc.mip_level_count {
for array_layer in 0..desc.size.depth_or_array_layers {
macro_rules! push_clear_view {
($format:expr, $plane:expr) => {
($format:expr, $aspect:expr) => {
let desc = hal::TextureViewDescriptor {
label: clear_label,
format: $format,
dimension,
usage,
range: wgt::ImageSubresourceRange {
aspect: wgt::TextureAspect::All,
aspect: $aspect,
base_mip_level: mip_level,
mip_level_count: Some(1),
base_array_layer: array_layer,
array_layer_count: Some(1),
},
plane: $plane,
};
clear_views.push(Some(
unsafe { self.raw().create_texture_view(&raw_texture, &desc) }
Expand All @@ -828,11 +850,14 @@ impl<A: HalApi> Device<A> {
};
}

if desc.format == wgt::TextureFormat::NV12 {
push_clear_view!(wgt::TextureFormat::R8Unorm, Some(0));
push_clear_view!(wgt::TextureFormat::Rg8Unorm, Some(1));
if let Some(planes) = desc.format.planes() {
for plane in 0..planes {
let aspect = wgt::TextureAspect::from_plane(plane).unwrap();
let format = desc.format.aspect_specific_format(aspect).unwrap();
push_clear_view!(format, aspect);
}
} else {
push_clear_view!(desc.format, None);
push_clear_view!(desc.format, wgt::TextureAspect::All);
}
}
}
Expand Down Expand Up @@ -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
let render_extent = 'b: loop {
if !texture
Expand Down Expand Up @@ -1121,7 +1144,6 @@ impl<A: HalApi> Device<A> {
dimension: resolved_dimension,
usage,
range: resolved_range,
plane: desc.plane,
};

let raw = unsafe {
Expand All @@ -1142,6 +1164,7 @@ impl<A: HalApi> Device<A> {
parent: RwLock::new(Some(texture.clone())),
device: self.clone(),
desc: resource::HalTextureViewDescriptor {
texture_format: texture.desc.format,
format: resolved_format,
dimension: resolved_dimension,
range: resolved_range,
Expand Down Expand Up @@ -3383,39 +3406,3 @@ impl<A: HalApi> Resource<DeviceId> for Device<A> {
&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(()),
}
}
1 change: 0 additions & 1 deletion wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
dimension: wgt::TextureViewDimension::D2,
usage: hal::TextureUses::COLOR_TARGET,
range: wgt::ImageSubresourceRange::default(),
plane: None,
};
let clear_view = unsafe {
hal::Device::create_texture_view(
Expand Down
29 changes: 16 additions & 13 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,20 @@ pub enum TextureDimensionError {
block_height: u32,
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}")]
MultisampledDepthOrArrayLayer(u32),
}
Expand Down Expand Up @@ -978,20 +992,19 @@ pub struct TextureViewDescriptor<'a> {
pub dimension: Option<wgt::TextureViewDimension>,
/// Range within the texture that is accessible via this view.
pub range: wgt::ImageSubresourceRange,
/// The plane of the texture view.
pub plane: Option<u32>,
}

#[derive(Debug)]
pub(crate) struct HalTextureViewDescriptor {
pub texture_format: wgt::TextureFormat,
pub format: wgt::TextureFormat,
pub dimension: wgt::TextureViewDimension,
pub range: wgt::ImageSubresourceRange,
}

impl HalTextureViewDescriptor {
pub fn aspects(&self) -> hal::FormatAspects {
hal::FormatAspects::new(self.format, self.range.aspect)
hal::FormatAspects::new(self.texture_format, self.range.aspect)
}
}

Expand Down Expand Up @@ -1090,16 +1103,6 @@ pub enum CreateTextureViewError {
texture: 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)]
Expand Down
2 changes: 0 additions & 2 deletions wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,6 @@ impl<A: hal::Api> Example<A> {
dimension: wgt::TextureViewDimension::D2,
usage: hal::TextureUses::RESOURCE,
range: wgt::ImageSubresourceRange::default(),
plane: None,
};
let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };

Expand Down Expand Up @@ -661,7 +660,6 @@ impl<A: hal::Api> Example<A> {
dimension: wgt::TextureViewDimension::D2,
usage: hal::TextureUses::COLOR_TARGET,
range: wgt::ImageSubresourceRange::default(),
plane: None,
};
let surface_tex_view = unsafe {
self.device
Expand Down
1 change: 0 additions & 1 deletion wgpu-hal/examples/raw-gles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ fn fill_screen(exposed: &hal::ExposedAdapter<hal::api::Gles>, width: u32, height
dimension: wgt::TextureViewDimension::D2,
usage: hal::TextureUses::COLOR_TARGET,
range: wgt::ImageSubresourceRange::default(),
plane: None,
},
)
.unwrap()
Expand Down
2 changes: 0 additions & 2 deletions wgpu-hal/examples/ray-traced-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,6 @@ impl<A: hal::Api> Example<A> {
dimension: wgt::TextureViewDimension::D2,
usage: hal::TextureUses::STORAGE_READ_WRITE | hal::TextureUses::COPY_SRC,
range: wgt::ImageSubresourceRange::default(),
plane: None,
};
let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() };

Expand Down Expand Up @@ -888,7 +887,6 @@ impl<A: hal::Api> Example<A> {
dimension: wgt::TextureViewDimension::D2,
usage: hal::TextureUses::COPY_DST,
range: wgt::ImageSubresourceRange::default(),
plane: None,
};
let surface_tex_view = unsafe {
self.device
Expand Down
Loading

0 comments on commit 0cbabcf

Please sign in to comment.