Skip to content

Commit d63ca09

Browse files
authored
Add usage to TextureViewDescriptor (#6755)
Signed-off-by: sagudev <[email protected]>
1 parent 79280bc commit d63ca09

File tree

12 files changed

+87
-14
lines changed

12 files changed

+87
-14
lines changed

deno_webgpu/texture.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ pub fn op_webgpu_create_texture_view(
115115
format: args.format,
116116
dimension: args.dimension,
117117
range: args.range,
118+
usage: None, // FIXME: Obtain actual value from desc
118119
};
119120

120121
gfx_put!(instance.texture_create_view(

examples/src/mipmap/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ impl Example {
127127
label: Some("mip"),
128128
format: None,
129129
dimension: None,
130+
usage: None,
130131
aspect: wgpu::TextureAspect::All,
131132
base_mip_level: mip,
132133
mip_level_count: Some(1),

examples/src/multiple_render_targets/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ impl MultiTargetRenderer {
6969
label: Some("view"),
7070
format: None,
7171
dimension: Some(wgpu::TextureViewDimension::D2),
72+
usage: None,
7273
aspect: wgpu::TextureAspect::All,
7374
base_mip_level: 0,
7475
mip_level_count: None,

examples/src/ray_cube_compute/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ impl crate::framework::Example for Example {
177177
label: None,
178178
format: Some(wgpu::TextureFormat::Rgba8Unorm),
179179
dimension: Some(wgpu::TextureViewDimension::D2),
180+
usage: None,
180181
aspect: wgpu::TextureAspect::All,
181182
base_mip_level: 0,
182183
mip_level_count: None,

examples/src/shadow/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ impl crate::framework::Example for Example {
393393
label: Some("shadow"),
394394
format: None,
395395
dimension: Some(wgpu::TextureViewDimension::D2),
396+
usage: None,
396397
aspect: wgpu::TextureAspect::All,
397398
base_mip_level: 0,
398399
mip_level_count: None,

tests/tests/bgra8unorm_storage.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new()
4444
label: None,
4545
format: None,
4646
dimension: None,
47+
usage: None,
4748
aspect: wgpu::TextureAspect::All,
4849
base_mip_level: 0,
4950
base_array_layer: 0,

tests/tests/device.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ static DIFFERENT_BGL_ORDER_BW_SHADER_AND_API: GpuTestConfiguration = GpuTestConf
688688
label: None,
689689
format: None,
690690
dimension: None,
691+
usage: None,
691692
aspect: wgt::TextureAspect::All,
692693
base_mip_level: 0,
693694
mip_level_count: None,

wgpu-core/src/device/resource.rs

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,39 @@ impl Device {
10861086
.saturating_sub(desc.range.base_array_layer),
10871087
});
10881088

1089+
let resolved_usage = {
1090+
let usage = desc.usage.unwrap_or(wgt::TextureUsages::empty());
1091+
if usage.is_empty() {
1092+
texture.desc.usage
1093+
} else if texture.desc.usage.contains(usage) {
1094+
usage
1095+
} else {
1096+
return Err(resource::CreateTextureViewError::InvalidTextureViewUsage {
1097+
view: usage,
1098+
texture: texture.desc.usage,
1099+
});
1100+
}
1101+
};
1102+
1103+
let allowed_format_usages = self
1104+
.describe_format_features(resolved_format)?
1105+
.allowed_usages;
1106+
if resolved_usage.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
1107+
&& !allowed_format_usages.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
1108+
{
1109+
return Err(
1110+
resource::CreateTextureViewError::TextureViewFormatNotRenderable(resolved_format),
1111+
);
1112+
}
1113+
1114+
if resolved_usage.contains(wgt::TextureUsages::STORAGE_BINDING)
1115+
&& !allowed_format_usages.contains(wgt::TextureUsages::STORAGE_BINDING)
1116+
{
1117+
return Err(
1118+
resource::CreateTextureViewError::TextureViewFormatNotStorage(resolved_format),
1119+
);
1120+
}
1121+
10891122
// validate TextureViewDescriptor
10901123

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

12081241
// https://gpuweb.github.io/gpuweb/#abstract-opdef-renderable-texture-view
12091242
let render_extent = 'error: {
1210-
if !texture
1211-
.desc
1212-
.usage
1213-
.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
1214-
{
1215-
break 'error Err(TextureViewNotRenderableReason::Usage(texture.desc.usage));
1243+
if !resolved_usage.contains(wgt::TextureUsages::RENDER_ATTACHMENT) {
1244+
break 'error Err(TextureViewNotRenderableReason::Usage(resolved_usage));
12161245
}
12171246

12181247
if !(resolved_dimension == TextureViewDimension::D2
@@ -1309,6 +1338,7 @@ impl Device {
13091338
texture_format: texture.desc.format,
13101339
format: resolved_format,
13111340
dimension: resolved_dimension,
1341+
usage: resolved_usage,
13121342
range: resolved_range,
13131343
},
13141344
format_features: texture.format_features,
@@ -2090,7 +2120,7 @@ impl Device {
20902120
{
20912121
view.same_device(self)?;
20922122

2093-
let (pub_usage, internal_use) = self.texture_use_parameters(
2123+
let internal_use = self.texture_use_parameters(
20942124
binding,
20952125
decl,
20962126
view,
@@ -2100,7 +2130,6 @@ impl Device {
21002130
used.views.insert_single(view.clone(), internal_use);
21012131

21022132
let texture = &view.parent;
2103-
texture.check_usage(pub_usage)?;
21042133

21052134
used_texture_ranges.push(TextureInitTrackerAction {
21062135
texture: texture.clone(),
@@ -2399,7 +2428,7 @@ impl Device {
23992428
decl: &wgt::BindGroupLayoutEntry,
24002429
view: &TextureView,
24012430
expected: &'static str,
2402-
) -> Result<(wgt::TextureUsages, hal::TextureUses), binding_model::CreateBindGroupError> {
2431+
) -> Result<hal::TextureUses, binding_model::CreateBindGroupError> {
24032432
use crate::binding_model::CreateBindGroupError as Error;
24042433
if view
24052434
.desc
@@ -2458,10 +2487,8 @@ impl Device {
24582487
view_dimension: view.desc.dimension,
24592488
});
24602489
}
2461-
Ok((
2462-
wgt::TextureUsages::TEXTURE_BINDING,
2463-
hal::TextureUses::RESOURCE,
2464-
))
2490+
view.check_usage(wgt::TextureUsages::TEXTURE_BINDING)?;
2491+
Ok(hal::TextureUses::RESOURCE)
24652492
}
24662493
wgt::BindingType::StorageTexture {
24672494
access,
@@ -2524,7 +2551,8 @@ impl Device {
25242551
hal::TextureUses::STORAGE_READ_WRITE
25252552
}
25262553
};
2527-
Ok((wgt::TextureUsages::STORAGE_BINDING, internal_use))
2554+
view.check_usage(wgt::TextureUsages::STORAGE_BINDING)?;
2555+
Ok(internal_use)
25282556
}
25292557
_ => Err(Error::WrongBindingType {
25302558
binding,

wgpu-core/src/resource.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,7 @@ impl Texture {
10601060
bind_groups: Mutex::new(rank::TEXTURE_BIND_GROUPS, WeakVec::new()),
10611061
}
10621062
}
1063+
10631064
/// Checks that the given texture usage contains the required texture usage,
10641065
/// returns an error otherwise.
10651066
pub(crate) fn check_usage(
@@ -1552,6 +1553,9 @@ pub struct TextureViewDescriptor<'a> {
15521553
/// - For 2D textures it must be one of `D2`, `D2Array`, `Cube`, or `CubeArray`.
15531554
/// - For 3D textures it must be `D3`.
15541555
pub dimension: Option<wgt::TextureViewDimension>,
1556+
/// The allowed usage(s) for the texture view. Must be a subset of the usage flags of the texture.
1557+
/// If not provided, defaults to the full set of usage flags of the texture.
1558+
pub usage: Option<wgt::TextureUsages>,
15551559
/// Range within the texture that is accessible via this view.
15561560
pub range: wgt::ImageSubresourceRange,
15571561
}
@@ -1560,6 +1564,7 @@ pub struct TextureViewDescriptor<'a> {
15601564
pub(crate) struct HalTextureViewDescriptor {
15611565
pub texture_format: wgt::TextureFormat,
15621566
pub format: wgt::TextureFormat,
1567+
pub usage: wgt::TextureUsages,
15631568
pub dimension: wgt::TextureViewDimension,
15641569
pub range: wgt::ImageSubresourceRange,
15651570
}
@@ -1631,6 +1636,23 @@ impl TextureView {
16311636
.map(|it| it.as_ref())
16321637
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
16331638
}
1639+
1640+
/// Checks that the given texture usage contains the required texture usage,
1641+
/// returns an error otherwise.
1642+
pub(crate) fn check_usage(
1643+
&self,
1644+
expected: wgt::TextureUsages,
1645+
) -> Result<(), MissingTextureUsageError> {
1646+
if self.desc.usage.contains(expected) {
1647+
Ok(())
1648+
} else {
1649+
Err(MissingTextureUsageError {
1650+
res: self.error_ident(),
1651+
actual: self.desc.usage,
1652+
expected,
1653+
})
1654+
}
1655+
}
16341656
}
16351657

16361658
#[derive(Clone, Debug, Error)]
@@ -1645,6 +1667,15 @@ pub enum CreateTextureViewError {
16451667
view: wgt::TextureViewDimension,
16461668
texture: wgt::TextureDimension,
16471669
},
1670+
#[error("Texture view format `{0:?}` is not renderable")]
1671+
TextureViewFormatNotRenderable(wgt::TextureFormat),
1672+
#[error("Texture view format `{0:?}` is not storage bindable")]
1673+
TextureViewFormatNotStorage(wgt::TextureFormat),
1674+
#[error("Invalid texture view usage `{view:?}` with texture of usage `{texture:?}`")]
1675+
InvalidTextureViewUsage {
1676+
view: wgt::TextureUsages,
1677+
texture: wgt::TextureUsages,
1678+
},
16481679
#[error("Invalid texture view dimension `{0:?}` of a multisampled texture")]
16491680
InvalidMultisampledTextureViewDimension(wgt::TextureViewDimension),
16501681
#[error("Invalid texture depth `{depth}` for texture view of dimension `Cubemap`. Cubemap views must use images of size 6.")]
@@ -1680,6 +1711,8 @@ pub enum CreateTextureViewError {
16801711
},
16811712
#[error(transparent)]
16821713
InvalidResource(#[from] InvalidResourceError),
1714+
#[error(transparent)]
1715+
MissingFeatures(#[from] MissingFeatures),
16831716
}
16841717

16851718
#[derive(Clone, Debug, Error)]

wgpu-types/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6102,6 +6102,9 @@ pub struct TextureViewDescriptor<L> {
61026102
/// The dimension of the texture view. For 1D textures, this must be `D1`. For 2D textures it must be one of
61036103
/// `D2`, `D2Array`, `Cube`, and `CubeArray`. For 3D textures it must be `D3`
61046104
pub dimension: Option<TextureViewDimension>,
6105+
/// The allowed usage(s) for the texture view. Must be a subset of the usage flags of the texture.
6106+
/// If not provided, defaults to the full set of usage flags of the texture.
6107+
pub usage: Option<TextureUsages>,
61056108
/// Aspect of the texture. Color textures must be [`TextureAspect::All`].
61066109
pub aspect: TextureAspect,
61076110
/// Base mip level.

0 commit comments

Comments
 (0)