Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix being able to use storage textures without TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES #6690

Merged
merged 2 commits into from
Dec 10, 2024
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
1 change: 0 additions & 1 deletion examples/src/ray_traced_triangle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ impl crate::framework::Example for Example {
fn required_features() -> wgpu::Features {
wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
| wgpu::Features::EXPERIMENTAL_RAY_QUERY
| wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
}

fn required_limits() -> wgpu::Limits {
Expand Down
2 changes: 1 addition & 1 deletion player/tests/data/zero-init-texture-binding.ron
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(
features: "TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES",
features: "",
expectations: [
(
name: "Sampled Texture",
Expand Down
21 changes: 16 additions & 5 deletions wgpu-core/src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub fn map_buffer_usage(usage: wgt::BufferUsages) -> hal::BufferUses {
pub fn map_texture_usage(
usage: wgt::TextureUsages,
aspect: hal::FormatAspects,
flags: wgt::TextureFormatFeatureFlags,
) -> hal::TextureUses {
let mut u = hal::TextureUses::empty();
u.set(
Expand All @@ -121,10 +122,20 @@ pub fn map_texture_usage(
hal::TextureUses::RESOURCE,
usage.contains(wgt::TextureUsages::TEXTURE_BINDING),
);
u.set(
hal::TextureUses::STORAGE_READ_WRITE,
usage.contains(wgt::TextureUsages::STORAGE_BINDING),
);
if usage.contains(wgt::TextureUsages::STORAGE_BINDING) {
ErichDonGubler marked this conversation as resolved.
Show resolved Hide resolved
u.set(
hal::TextureUses::STORAGE_READ_ONLY,
flags.contains(wgt::TextureFormatFeatureFlags::STORAGE_READ_ONLY),
);
u.set(
hal::TextureUses::STORAGE_WRITE_ONLY,
flags.contains(wgt::TextureFormatFeatureFlags::STORAGE_WRITE_ONLY),
);
u.set(
hal::TextureUses::STORAGE_READ_WRITE,
flags.contains(wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE),
);
}
let is_color = aspect.contains(hal::FormatAspects::COLOR);
u.set(
hal::TextureUses::COLOR_TARGET,
Expand All @@ -143,7 +154,7 @@ pub fn map_texture_usage_for_texture(
) -> hal::TextureUses {
// Enforce having COPY_DST/DEPTH_STENCIL_WRITE/COLOR_TARGET otherwise we
// wouldn't be able to initialize the texture.
map_texture_usage(desc.usage, desc.format.into())
map_texture_usage(desc.usage, desc.format.into(), format_features.flags)
| if desc.format.is_depth_stencil_format() {
hal::TextureUses::DEPTH_STENCIL_WRITE
} else if desc.usage.contains(wgt::TextureUsages::COPY_DST) {
Expand Down
8 changes: 7 additions & 1 deletion wgpu-core/src/device/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1859,7 +1859,13 @@ impl Global {
height: config.height,
depth_or_array_layers: 1,
},
usage: conv::map_texture_usage(config.usage, hal::FormatAspects::COLOR),
usage: conv::map_texture_usage(
config.usage,
hal::FormatAspects::COLOR,
wgt::TextureFormatFeatureFlags::STORAGE_READ_ONLY
| wgt::TextureFormatFeatureFlags::STORAGE_WRITE_ONLY
| wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
),
view_formats: hal_view_formats,
};

Expand Down
20 changes: 11 additions & 9 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ impl Device {
let texture = Texture::new(
self,
resource::TextureInner::Native { raw: hal_texture },
conv::map_texture_usage(desc.usage, desc.format.into()),
conv::map_texture_usage(desc.usage, desc.format.into(), format_features.flags),
desc,
format_features,
resource::TextureClearMode::None,
Expand Down Expand Up @@ -2502,19 +2502,21 @@ impl Device {

let internal_use = match access {
wgt::StorageTextureAccess::WriteOnly => {
if !view.format_features.flags.intersects(
wgt::TextureFormatFeatureFlags::STORAGE_WRITE_ONLY
| wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
) {
if !view
.format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::STORAGE_WRITE_ONLY)
{
return Err(Error::StorageWriteNotSupported(view.desc.format));
}
hal::TextureUses::STORAGE_WRITE_ONLY
}
wgt::StorageTextureAccess::ReadOnly => {
if !view.format_features.flags.intersects(
wgt::TextureFormatFeatureFlags::STORAGE_READ_ONLY
| wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
) {
if !view
.format_features
.flags
.contains(wgt::TextureFormatFeatureFlags::STORAGE_READ_ONLY)
{
return Err(Error::StorageReadNotSupported(view.desc.format));
}
hal::TextureUses::STORAGE_READ_ONLY
Expand Down
6 changes: 5 additions & 1 deletion wgpu-core/src/present.rs
ErichDonGubler marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,16 @@ impl Surface {
usage: config.usage,
view_formats: config.view_formats,
};
let hal_usage = conv::map_texture_usage(config.usage, config.format.into());
let format_features = wgt::TextureFormatFeatures {
allowed_usages: wgt::TextureUsages::RENDER_ATTACHMENT,
flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4
| wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE,
};
let hal_usage = conv::map_texture_usage(
config.usage,
config.format.into(),
format_features.flags,
);
let clear_view_desc = hal::TextureViewDescriptor {
label: hal_label(
Some("(wgpu internal) clear surface texture view"),
Expand Down
14 changes: 9 additions & 5 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,16 +672,20 @@ impl crate::Adapter for super::Adapter {
);
// UAVs use srv_uav_format
caps.set(
Tfc::STORAGE_WRITE_ONLY,
Tfc::STORAGE_READ_ONLY,
data_srv_uav
.Support1
.contains(Direct3D12::D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW),
ErichDonGubler marked this conversation as resolved.
Show resolved Hide resolved
.Support2
.contains(Direct3D12::D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD),
);
caps.set(
Tfc::STORAGE_READ_WRITE | Tfc::STORAGE_READ_ONLY | Tfc::STORAGE_WRITE_ONLY,
Tfc::STORAGE_WRITE_ONLY,
data_srv_uav
.Support2
.contains(Direct3D12::D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD),
.contains(Direct3D12::D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE),
);
caps.set(
Tfc::STORAGE_READ_WRITE,
caps.contains(Tfc::STORAGE_READ_ONLY | Tfc::STORAGE_WRITE_ONLY),
ErichDonGubler marked this conversation as resolved.
Show resolved Hide resolved
);

// We load via UAV/SRV so use srv_uav_format
Expand Down
8 changes: 6 additions & 2 deletions wgpu-hal/src/dx12/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ pub fn map_texture_usage_to_resource_flags(
flags |= Direct3D12::D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
}
}
if usage.contains(crate::TextureUses::STORAGE_READ_WRITE) {
if usage.intersects(
crate::TextureUses::STORAGE_READ_ONLY
| crate::TextureUses::STORAGE_WRITE_ONLY
| crate::TextureUses::STORAGE_READ_WRITE,
) {
flags |= Direct3D12::D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
}

Expand Down Expand Up @@ -168,7 +172,7 @@ pub fn map_texture_usage_to_state(usage: crate::TextureUses) -> Direct3D12::D3D1
if usage.intersects(Tu::DEPTH_STENCIL_WRITE) {
state |= Direct3D12::D3D12_RESOURCE_STATE_DEPTH_WRITE;
}
if usage.intersects(Tu::STORAGE_READ_ONLY | Tu::STORAGE_READ_WRITE) {
if usage.intersects(Tu::STORAGE_READ_ONLY | Tu::STORAGE_WRITE_ONLY | Tu::STORAGE_READ_WRITE) {
state |= Direct3D12::D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
}
state
Expand Down
4 changes: 3 additions & 1 deletion wgpu-hal/src/dx12/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,9 @@ impl crate::Device for super::Device {
None
},
handle_uav: if desc.usage.intersects(
crate::TextureUses::STORAGE_READ_ONLY | crate::TextureUses::STORAGE_READ_WRITE,
crate::TextureUses::STORAGE_READ_ONLY
| crate::TextureUses::STORAGE_WRITE_ONLY
| crate::TextureUses::STORAGE_READ_WRITE,
ErichDonGubler marked this conversation as resolved.
Show resolved Hide resolved
) {
match unsafe { view_desc.to_uav() } {
Some(raw_desc) => {
Expand Down
14 changes: 7 additions & 7 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1719,26 +1719,26 @@ bitflags::bitflags! {
const DEPTH_STENCIL_READ = 1 << 6;
/// Read-write depth stencil usage
const DEPTH_STENCIL_WRITE = 1 << 7;
/// Read-only storage buffer usage. Corresponds to a UAV in d3d, so is exclusive, despite being read only.
/// Read-only storage texture usage. Corresponds to a UAV in d3d, so is exclusive, despite being read only.
const STORAGE_READ_ONLY = 1 << 8;
/// Write-only storage buffer usage.
/// Write-only storage texture usage.
const STORAGE_WRITE_ONLY = 1 << 9;
/// Read-write storage buffer usage.
const STORAGE_READ_WRITE = 1 << 9;
/// Read-write storage texture usage.
const STORAGE_READ_WRITE = 1 << 10;
ErichDonGubler marked this conversation as resolved.
Show resolved Hide resolved
/// The combination of states that a texture may be in _at the same time_.
const INCLUSIVE = Self::COPY_SRC.bits() | Self::RESOURCE.bits() | Self::DEPTH_STENCIL_READ.bits();
/// The combination of states that a texture must exclusively be in.
const EXCLUSIVE = Self::COPY_DST.bits() | Self::COLOR_TARGET.bits() | Self::DEPTH_STENCIL_WRITE.bits() | Self::STORAGE_READ_ONLY.bits() | Self::STORAGE_READ_WRITE.bits() | Self::PRESENT.bits();
const EXCLUSIVE = Self::COPY_DST.bits() | Self::COLOR_TARGET.bits() | Self::DEPTH_STENCIL_WRITE.bits() | Self::STORAGE_READ_ONLY.bits() | Self::STORAGE_WRITE_ONLY.bits() | Self::STORAGE_READ_WRITE.bits() | Self::PRESENT.bits();
/// The combination of all usages that the are guaranteed to be be ordered by the hardware.
/// If a usage is ordered, then if the texture state doesn't change between draw calls, there
/// are no barriers needed for synchronization.
const ORDERED = Self::INCLUSIVE.bits() | Self::COLOR_TARGET.bits() | Self::DEPTH_STENCIL_WRITE.bits() | Self::STORAGE_READ_ONLY.bits();

/// Flag used by the wgpu-core texture tracker to say a texture is in different states for every sub-resource
const COMPLEX = 1 << 10;
const COMPLEX = 1 << 11;
/// Flag used by the wgpu-core texture tracker to say that the tracker does not know the state of the sub-resource.
/// This is different from UNINITIALIZED as that says the tracker does know, but the texture has not been initialized.
const UNKNOWN = 1 << 11;
const UNKNOWN = 1 << 12;
}
}

Expand Down
6 changes: 3 additions & 3 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ impl crate::Adapter for super::Adapter {

// Metal defined pixel format capabilities
let all_caps = Tfc::SAMPLED_LINEAR
| Tfc::STORAGE_READ_ONLY
| Tfc::STORAGE_WRITE_ONLY
| Tfc::STORAGE_READ_WRITE
| Tfc::COLOR_ATTACHMENT
| Tfc::COLOR_ATTACHMENT_BLEND
| msaa_count
Expand Down Expand Up @@ -311,7 +309,7 @@ impl crate::Adapter for super::Adapter {
}
};

Tfc::COPY_SRC | Tfc::COPY_DST | Tfc::SAMPLED | extra
Tfc::COPY_SRC | Tfc::COPY_DST | Tfc::SAMPLED | Tfc::STORAGE_READ_ONLY | extra
}

unsafe fn surface_capabilities(
Expand Down Expand Up @@ -360,6 +358,8 @@ impl crate::Adapter for super::Adapter {
usage: crate::TextureUses::COLOR_TARGET
| crate::TextureUses::COPY_SRC
| crate::TextureUses::COPY_DST
| crate::TextureUses::STORAGE_READ_ONLY
| crate::TextureUses::STORAGE_WRITE_ONLY
| crate::TextureUses::STORAGE_READ_WRITE,
})
}
Expand Down
4 changes: 3 additions & 1 deletion wgpu-hal/src/vulkan/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,9 @@ pub fn map_vk_image_usage(usage: vk::ImageUsageFlags) -> crate::TextureUses {
bits |= crate::TextureUses::DEPTH_STENCIL_READ | crate::TextureUses::DEPTH_STENCIL_WRITE;
}
if usage.contains(vk::ImageUsageFlags::STORAGE) {
bits |= crate::TextureUses::STORAGE_READ_WRITE;
bits |= crate::TextureUses::STORAGE_READ_ONLY
| crate::TextureUses::STORAGE_WRITE_ONLY
| crate::TextureUses::STORAGE_READ_WRITE;
}
bits
}
Expand Down
50 changes: 27 additions & 23 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2374,7 +2374,7 @@ bitflags::bitflags! {
/// [`StorageTextureAccess::WriteOnly`].
const STORAGE_WRITE_ONLY = 1 << 6;
/// When used as a STORAGE texture, then a texture with this format can be bound with
/// any [`StorageTextureAccess`].
/// [`StorageTextureAccess::ReadWrite`].
const STORAGE_READ_WRITE = 1 << 9;
/// If not present, the texture can't be blended into the render target.
const BLENDABLE = 1 << 7;
Expand Down Expand Up @@ -3400,6 +3400,10 @@ impl TextureFormat {
let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4;
let msaa_resolve = msaa | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE;

let s_ro_wo = TextureFormatFeatureFlags::STORAGE_READ_ONLY
| TextureFormatFeatureFlags::STORAGE_WRITE_ONLY;
let s_all = s_ro_wo | TextureFormatFeatureFlags::STORAGE_READ_WRITE;

// Flags
let basic =
TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING;
Expand Down Expand Up @@ -3437,31 +3441,31 @@ impl TextureFormat {
Self::Rg8Snorm => ( noaa, basic),
Self::Rg8Uint => ( msaa, attachment),
Self::Rg8Sint => ( msaa, attachment),
Self::R32Uint => ( noaa, all_flags),
Self::R32Sint => ( noaa, all_flags),
Self::R32Float => ( msaa, all_flags),
Self::R32Uint => ( noaa | s_all, all_flags),
Self::R32Sint => ( noaa | s_all, all_flags),
Self::R32Float => ( msaa | s_all, all_flags),
Self::Rg16Uint => ( msaa, attachment),
Self::Rg16Sint => ( msaa, attachment),
Self::Rg16Float => (msaa_resolve, attachment),
Self::Rgba8Unorm => (msaa_resolve, all_flags),
Self::Rgba8Unorm => (msaa_resolve | s_ro_wo, all_flags),
Self::Rgba8UnormSrgb => (msaa_resolve, attachment),
Self::Rgba8Snorm => ( noaa, storage),
Self::Rgba8Uint => ( msaa, all_flags),
Self::Rgba8Sint => ( msaa, all_flags),
Self::Rgba8Snorm => ( s_ro_wo, storage),
Self::Rgba8Uint => ( msaa | s_ro_wo, all_flags),
Self::Rgba8Sint => ( msaa | s_ro_wo, all_flags),
Self::Bgra8Unorm => (bgra8unorm_f, bgra8unorm),
Self::Bgra8UnormSrgb => (msaa_resolve, attachment),
Self::Rgb10a2Uint => ( msaa, attachment),
Self::Rgb10a2Unorm => (msaa_resolve, attachment),
Self::Rg11b10Ufloat => ( msaa, rg11b10f),
Self::Rg32Uint => ( noaa, all_flags),
Self::Rg32Sint => ( noaa, all_flags),
Self::Rg32Float => ( noaa, all_flags),
Self::Rgba16Uint => ( msaa, all_flags),
Self::Rgba16Sint => ( msaa, all_flags),
Self::Rgba16Float => (msaa_resolve, all_flags),
Self::Rgba32Uint => ( noaa, all_flags),
Self::Rgba32Sint => ( noaa, all_flags),
Self::Rgba32Float => ( noaa, all_flags),
Self::Rg32Uint => ( noaa | s_ro_wo, all_flags),
Self::Rg32Sint => ( noaa | s_ro_wo, all_flags),
Self::Rg32Float => ( noaa | s_ro_wo, all_flags),
Self::Rgba16Uint => ( msaa | s_ro_wo, all_flags),
Self::Rgba16Sint => ( msaa | s_ro_wo, all_flags),
Self::Rgba16Float => (msaa_resolve | s_ro_wo, all_flags),
Self::Rgba32Uint => ( noaa | s_ro_wo, all_flags),
Self::Rgba32Sint => ( noaa | s_ro_wo, all_flags),
Self::Rgba32Float => ( noaa | s_ro_wo, all_flags),

Self::Stencil8 => ( msaa, attachment),
Self::Depth16Unorm => ( msaa, attachment),
Expand All @@ -3473,12 +3477,12 @@ impl TextureFormat {
// We only support sampling nv12 textures until we implement transfer plane data.
Self::NV12 => ( noaa, binding),

Self::R16Unorm => ( msaa, storage),
Self::R16Snorm => ( msaa, storage),
Self::Rg16Unorm => ( msaa, storage),
Self::Rg16Snorm => ( msaa, storage),
Self::Rgba16Unorm => ( msaa, storage),
Self::Rgba16Snorm => ( msaa, storage),
Self::R16Unorm => ( msaa | s_ro_wo, storage),
Self::R16Snorm => ( msaa | s_ro_wo, storage),
Self::Rg16Unorm => ( msaa | s_ro_wo, storage),
Self::Rg16Snorm => ( msaa | s_ro_wo, storage),
Self::Rgba16Unorm => ( msaa | s_ro_wo, storage),
Self::Rgba16Snorm => ( msaa | s_ro_wo, storage),

Self::Rgb9e5Ufloat => ( noaa, basic),

Expand Down
Loading