Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cts_runner/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:crea
webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:limitTest="atDefault";testValueName="atLimit";async=true;pointList=true;frontFacing=false;sampleIndex=false;sampleMaskIn=false;sampleMaskOut=true
//FAIL: webgpu:api,validation,capability_checks,limits,maxInterStageShaderVariables:createRenderPipeline,at_over:*
// https://github.com/gpuweb/cts/issues/4538
webgpu:api,validation,createBindGroup:binding_must_contain_resource_defined_in_layout:*
webgpu:api,validation,createBindGroup:buffer_offset_and_size_for_bind_groups_match:*
webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:*
webgpu:api,validation,createBindGroup:buffer,resource_binding_size:*
webgpu:api,validation,createBindGroup:storage_texture,*
webgpu:api,validation,createBindGroupLayout:storage_texture,formats:*
// Fails because we coerce a size of 0 in `GPUDevice.createBindGroup(…)` to `buffer.size - offset`.
// FAIL webgpu:api,validation,createBindGroup:buffer_offset_and_size_for_bind_groups_match:*
webgpu:api,validation,encoding,beginComputePass:*
Expand Down
21 changes: 8 additions & 13 deletions wgpu-core/src/binding_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ pub enum CreateBindGroupLayoutError {
InvalidBindingIndex { binding: u32, maximum: u32 },
#[error("Invalid visibility {0:?}")]
InvalidVisibility(wgt::ShaderStages),
#[error("Binding index {binding}: {access:?} access to storage textures with format {format:?} is not supported")]
UnsupportedStorageTextureAccess {
binding: u32,
access: wgt::StorageTextureAccess,
format: wgt::TextureFormat,
},
}

impl WebGpuError for CreateBindGroupLayoutError {
Expand All @@ -88,7 +94,8 @@ impl WebGpuError for CreateBindGroupLayoutError {
| Self::InvalidBindingIndex { .. }
| Self::InvalidVisibility(_)
| Self::ContainsBothBindingArrayAndDynamicOffsetArray
| Self::ContainsBothBindingArrayAndUniformBuffer => ErrorType::Validation,
| Self::ContainsBothBindingArrayAndUniformBuffer
| Self::UnsupportedStorageTextureAccess { .. } => ErrorType::Validation,
}
}
}
Expand Down Expand Up @@ -242,14 +249,6 @@ pub enum CreateBindGroupError {
MissingTLASVertexReturn { binding: u32 },
#[error("Bound texture views can not have both depth and stencil aspects enabled")]
DepthStencilAspect,
#[error("The adapter does not support read access for storage textures of format {0:?}")]
StorageReadNotSupported(wgt::TextureFormat),
#[error("The adapter does not support atomics for storage textures of format {0:?}")]
StorageAtomicNotSupported(wgt::TextureFormat),
#[error("The adapter does not support write access for storage textures of format {0:?}")]
StorageWriteNotSupported(wgt::TextureFormat),
#[error("The adapter does not support read-write access for storage textures of format {0:?}")]
StorageReadWriteNotSupported(wgt::TextureFormat),
#[error(transparent)]
ResourceUsageCompatibility(#[from] ResourceUsageCompatibilityError),
#[error(transparent)]
Expand Down Expand Up @@ -287,10 +286,6 @@ impl WebGpuError for CreateBindGroupError {
| Self::WrongSamplerComparison { .. }
| Self::WrongSamplerFiltering { .. }
| Self::DepthStencilAspect
| Self::StorageReadNotSupported(_)
| Self::StorageWriteNotSupported(_)
| Self::StorageReadWriteNotSupported(_)
| Self::StorageAtomicNotSupported(_)
| Self::MissingTLASVertexReturn { .. }
| Self::InvalidExternalTextureMipLevelCount { .. }
| Self::InvalidExternalTextureFormat { .. } => return ErrorType::Validation,
Expand Down
80 changes: 34 additions & 46 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2578,8 +2578,10 @@ impl Device {
Bt::StorageTexture {
access,
view_dimension,
format: _,
format,
} => {
use wgt::{StorageTextureAccess as Access, TextureFormatFeatureFlags as Flags};

match view_dimension {
TextureViewDimension::Cube | TextureViewDimension::CubeArray => {
return Err(binding_model::CreateBindGroupLayoutError::Entry {
Expand All @@ -2600,6 +2602,30 @@ impl Device {
}
_ => (),
}

let format_features =
self.describe_format_features(format).map_err(|error| {
binding_model::CreateBindGroupLayoutError::Entry {
binding: entry.binding,
error: BindGroupLayoutEntryError::MissingFeatures(error),
}
})?;

let required_feature_flag = match access {
Access::WriteOnly => Flags::STORAGE_WRITE_ONLY,
Access::ReadOnly => Flags::STORAGE_READ_ONLY,
Access::ReadWrite => Flags::STORAGE_READ_WRITE,
Access::Atomic => Flags::STORAGE_ATOMIC,
};

if !format_features.flags.contains(required_feature_flag) {
return Err(binding_model::CreateBindGroupLayoutError::UnsupportedStorageTextureAccess {
binding: entry.binding,
access,
format,
});
}

(
Some(
wgt::Features::TEXTURE_BINDING_ARRAY
Expand Down Expand Up @@ -3484,52 +3510,14 @@ impl Device {
});
}

let internal_use = match access {
wgt::StorageTextureAccess::WriteOnly => {
if !view
.format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::STORAGE_WRITE_ONLY)
{
return Err(Error::StorageWriteNotSupported(view.desc.format));
}
wgt::TextureUses::STORAGE_WRITE_ONLY
}
wgt::StorageTextureAccess::ReadOnly => {
if !view
.format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::STORAGE_READ_ONLY)
{
return Err(Error::StorageReadNotSupported(view.desc.format));
}
wgt::TextureUses::STORAGE_READ_ONLY
}
wgt::StorageTextureAccess::ReadWrite => {
if !view
.format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE)
{
return Err(Error::StorageReadWriteNotSupported(view.desc.format));
}

wgt::TextureUses::STORAGE_READ_WRITE
}
wgt::StorageTextureAccess::Atomic => {
if !view
.format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::STORAGE_ATOMIC)
{
return Err(Error::StorageAtomicNotSupported(view.desc.format));
}

wgt::TextureUses::STORAGE_ATOMIC
}
};
view.check_usage(wgt::TextureUsages::STORAGE_BINDING)?;
Ok(internal_use)

Ok(match access {
wgt::StorageTextureAccess::ReadOnly => wgt::TextureUses::STORAGE_READ_ONLY,
wgt::StorageTextureAccess::WriteOnly => wgt::TextureUses::STORAGE_WRITE_ONLY,
wgt::StorageTextureAccess::ReadWrite => wgt::TextureUses::STORAGE_READ_WRITE,
wgt::StorageTextureAccess::Atomic => wgt::TextureUses::STORAGE_ATOMIC,
})
}
wgt::BindingType::ExternalTexture => {
if view.desc.dimension != TextureViewDimension::D2 {
Expand Down