Skip to content

Commit

Permalink
Add usage to TextureViewDescriptor (#6755)
Browse files Browse the repository at this point in the history
Signed-off-by: sagudev <16504129 [email protected]>
  • Loading branch information
sagudev authored Dec 18, 2024
1 parent 79280bc commit d63ca09
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 14 deletions.
1 change: 1 addition & 0 deletions deno_webgpu/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 115,7 @@ pub fn op_webgpu_create_texture_view(
format: args.format,
dimension: args.dimension,
range: args.range,
usage: None, // FIXME: Obtain actual value from desc
};

gfx_put!(instance.texture_create_view(
Expand Down
1 change: 1 addition & 0 deletions examples/src/mipmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 127,7 @@ impl Example {
label: Some("mip"),
format: None,
dimension: None,
usage: None,
aspect: wgpu::TextureAspect::All,
base_mip_level: mip,
mip_level_count: Some(1),
Expand Down
1 change: 1 addition & 0 deletions examples/src/multiple_render_targets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 69,7 @@ impl MultiTargetRenderer {
label: Some("view"),
format: None,
dimension: Some(wgpu::TextureViewDimension::D2),
usage: None,
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
mip_level_count: None,
Expand Down
1 change: 1 addition & 0 deletions examples/src/ray_cube_compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 177,7 @@ impl crate::framework::Example for Example {
label: None,
format: Some(wgpu::TextureFormat::Rgba8Unorm),
dimension: Some(wgpu::TextureViewDimension::D2),
usage: None,
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
mip_level_count: None,
Expand Down
1 change: 1 addition & 0 deletions examples/src/shadow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 393,7 @@ impl crate::framework::Example for Example {
label: Some("shadow"),
format: None,
dimension: Some(wgpu::TextureViewDimension::D2),
usage: None,
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
mip_level_count: None,
Expand Down
1 change: 1 addition & 0 deletions tests/tests/bgra8unorm_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 44,7 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
label: None,
format: None,
dimension: None,
usage: None,
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
base_array_layer: 0,
Expand Down
1 change: 1 addition & 0 deletions tests/tests/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 688,7 @@ static DIFFERENT_BGL_ORDER_BW_SHADER_AND_API: GpuTestConfiguration = GpuTestConf
label: None,
format: None,
dimension: None,
usage: None,
aspect: wgt::TextureAspect::All,
base_mip_level: 0,
mip_level_count: None,
Expand Down
56 changes: 42 additions & 14 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 1086,39 @@ impl Device {
.saturating_sub(desc.range.base_array_layer),
});

let resolved_usage = {
let usage = desc.usage.unwrap_or(wgt::TextureUsages::empty());
if usage.is_empty() {
texture.desc.usage
} else if texture.desc.usage.contains(usage) {
usage
} else {
return Err(resource::CreateTextureViewError::InvalidTextureViewUsage {
view: usage,
texture: texture.desc.usage,
});
}
};

let allowed_format_usages = self
.describe_format_features(resolved_format)?
.allowed_usages;
if resolved_usage.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
&& !allowed_format_usages.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
{
return Err(
resource::CreateTextureViewError::TextureViewFormatNotRenderable(resolved_format),
);
}

if resolved_usage.contains(wgt::TextureUsages::STORAGE_BINDING)
&& !allowed_format_usages.contains(wgt::TextureUsages::STORAGE_BINDING)
{
return Err(
resource::CreateTextureViewError::TextureViewFormatNotStorage(resolved_format),
);
}

// validate TextureViewDescriptor

let aspects = hal::FormatAspects::new(texture.desc.format, desc.range.aspect);
Expand Down Expand Up @@ -1207,12 1240,8 @@ impl Device {

// https://gpuweb.github.io/gpuweb/#abstract-opdef-renderable-texture-view
let render_extent = 'error: {
if !texture
.desc
.usage
.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
{
break 'error Err(TextureViewNotRenderableReason::Usage(texture.desc.usage));
if !resolved_usage.contains(wgt::TextureUsages::RENDER_ATTACHMENT) {
break 'error Err(TextureViewNotRenderableReason::Usage(resolved_usage));
}

if !(resolved_dimension == TextureViewDimension::D2
Expand Down Expand Up @@ -1309,6 1338,7 @@ impl Device {
texture_format: texture.desc.format,
format: resolved_format,
dimension: resolved_dimension,
usage: resolved_usage,
range: resolved_range,
},
format_features: texture.format_features,
Expand Down Expand Up @@ -2090,7 2120,7 @@ impl Device {
{
view.same_device(self)?;

let (pub_usage, internal_use) = self.texture_use_parameters(
let internal_use = self.texture_use_parameters(
binding,
decl,
view,
Expand All @@ -2100,7 2130,6 @@ impl Device {
used.views.insert_single(view.clone(), internal_use);

let texture = &view.parent;
texture.check_usage(pub_usage)?;

used_texture_ranges.push(TextureInitTrackerAction {
texture: texture.clone(),
Expand Down Expand Up @@ -2399,7 2428,7 @@ impl Device {
decl: &wgt::BindGroupLayoutEntry,
view: &TextureView,
expected: &'static str,
) -> Result<(wgt::TextureUsages, hal::TextureUses), binding_model::CreateBindGroupError> {
) -> Result<hal::TextureUses, binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error;
if view
.desc
Expand Down Expand Up @@ -2458,10 2487,8 @@ impl Device {
view_dimension: view.desc.dimension,
});
}
Ok((
wgt::TextureUsages::TEXTURE_BINDING,
hal::TextureUses::RESOURCE,
))
view.check_usage(wgt::TextureUsages::TEXTURE_BINDING)?;
Ok(hal::TextureUses::RESOURCE)
}
wgt::BindingType::StorageTexture {
access,
Expand Down Expand Up @@ -2524,7 2551,8 @@ impl Device {
hal::TextureUses::STORAGE_READ_WRITE
}
};
Ok((wgt::TextureUsages::STORAGE_BINDING, internal_use))
view.check_usage(wgt::TextureUsages::STORAGE_BINDING)?;
Ok(internal_use)
}
_ => Err(Error::WrongBindingType {
binding,
Expand Down
33 changes: 33 additions & 0 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 1060,7 @@ impl Texture {
bind_groups: Mutex::new(rank::TEXTURE_BIND_GROUPS, WeakVec::new()),
}
}

/// Checks that the given texture usage contains the required texture usage,
/// returns an error otherwise.
pub(crate) fn check_usage(
Expand Down Expand Up @@ -1552,6 1553,9 @@ pub struct TextureViewDescriptor<'a> {
/// - For 2D textures it must be one of `D2`, `D2Array`, `Cube`, or `CubeArray`.
/// - For 3D textures it must be `D3`.
pub dimension: Option<wgt::TextureViewDimension>,
/// The allowed usage(s) for the texture view. Must be a subset of the usage flags of the texture.
/// If not provided, defaults to the full set of usage flags of the texture.
pub usage: Option<wgt::TextureUsages>,
/// Range within the texture that is accessible via this view.
pub range: wgt::ImageSubresourceRange,
}
Expand All @@ -1560,6 1564,7 @@ pub struct TextureViewDescriptor<'a> {
pub(crate) struct HalTextureViewDescriptor {
pub texture_format: wgt::TextureFormat,
pub format: wgt::TextureFormat,
pub usage: wgt::TextureUsages,
pub dimension: wgt::TextureViewDimension,
pub range: wgt::ImageSubresourceRange,
}
Expand Down Expand Up @@ -1631,6 1636,23 @@ impl TextureView {
.map(|it| it.as_ref())
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
}

/// Checks that the given texture usage contains the required texture usage,
/// returns an error otherwise.
pub(crate) fn check_usage(
&self,
expected: wgt::TextureUsages,
) -> Result<(), MissingTextureUsageError> {
if self.desc.usage.contains(expected) {
Ok(())
} else {
Err(MissingTextureUsageError {
res: self.error_ident(),
actual: self.desc.usage,
expected,
})
}
}
}

#[derive(Clone, Debug, Error)]
Expand All @@ -1645,6 1667,15 @@ pub enum CreateTextureViewError {
view: wgt::TextureViewDimension,
texture: wgt::TextureDimension,
},
#[error("Texture view format `{0:?}` is not renderable")]
TextureViewFormatNotRenderable(wgt::TextureFormat),
#[error("Texture view format `{0:?}` is not storage bindable")]
TextureViewFormatNotStorage(wgt::TextureFormat),
#[error("Invalid texture view usage `{view:?}` with texture of usage `{texture:?}`")]
InvalidTextureViewUsage {
view: wgt::TextureUsages,
texture: wgt::TextureUsages,
},
#[error("Invalid texture view dimension `{0:?}` of a multisampled texture")]
InvalidMultisampledTextureViewDimension(wgt::TextureViewDimension),
#[error("Invalid texture depth `{depth}` for texture view of dimension `Cubemap`. Cubemap views must use images of size 6.")]
Expand Down Expand Up @@ -1680,6 1711,8 @@ pub enum CreateTextureViewError {
},
#[error(transparent)]
InvalidResource(#[from] InvalidResourceError),
#[error(transparent)]
MissingFeatures(#[from] MissingFeatures),
}

#[derive(Clone, Debug, Error)]
Expand Down
3 changes: 3 additions & 0 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6102,6 6102,9 @@ pub struct TextureViewDescriptor<L> {
/// The dimension of the texture view. For 1D textures, this must be `D1`. For 2D textures it must be one of
/// `D2`, `D2Array`, `Cube`, and `CubeArray`. For 3D textures it must be `D3`
pub dimension: Option<TextureViewDimension>,
/// The allowed usage(s) for the texture view. Must be a subset of the usage flags of the texture.
/// If not provided, defaults to the full set of usage flags of the texture.
pub usage: Option<TextureUsages>,
/// Aspect of the texture. Color textures must be [`TextureAspect::All`].
pub aspect: TextureAspect,
/// Base mip level.
Expand Down
1 change: 1 addition & 0 deletions wgpu/src/backend/webgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2683,6 2683,7 @@ impl dispatch::TextureInterface for WebTexture {
if let Some(label) = desc.label {
mapped.set_label(label);
}
mapped.set_usage(desc.usage.unwrap_or(wgt::TextureUsages::empty()).bits());

let view = self.inner.create_view_with_descriptor(&mapped).unwrap();

Expand Down
1 change: 1 addition & 0 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 1967,7 @@ impl dispatch::TextureInterface for CoreTexture {
label: desc.label.map(Borrowed),
format: desc.format,
dimension: desc.dimension,
usage: desc.usage,
range: wgt::ImageSubresourceRange {
aspect: desc.aspect,
base_mip_level: desc.base_mip_level,
Expand Down

0 comments on commit d63ca09

Please sign in to comment.