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

Added new UNRESTRICTED_INDEX_BUFFER downlevel flag. #3157

Merged
Show file tree
Hide file tree
Changes from 5 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: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Bottom level categories:
- Convert all `Default` Implementations on Enums to `derive(Default)`
- Implement `Default` for `CompositeAlphaMode`
- Improve compute shader validation error message. By @haraldreingruber in [#3139](https://github.com/gfx-rs/wgpu/pull/3139)
- New downlevel feature `UNRESTRICTED_INDEX_BUFFER` to indicate support for using `INDEX` together with other non-copy/map usages (unsupported on WebGL). By @Wumpf in [#3157](https://github.com/gfx-rs/wgpu/pull/3157)

#### WebGPU
- Implement `queue_validate_write_buffer` by @jinleili in [#3098](https://github.com/gfx-rs/wgpu/pull/3098)
Expand Down
23 changes: 23 additions & 0 deletions wgpu-core/src/command/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,10 +541,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let hub = A::hub(self);
let mut token = Token::root();

let (device_guard, mut token) = hub.devices.read(&mut token);
let (mut cmd_buf_guard, mut token) = hub.command_buffers.write(&mut token);
let cmd_buf = CommandBuffer::get_encoder_mut(&mut *cmd_buf_guard, command_encoder_id)?;
let (buffer_guard, _) = hub.buffers.read(&mut token);

let device = &device_guard[cmd_buf.device_id.value];

#[cfg(feature = "trace")]
if let Some(ref mut list) = cmd_buf.commands {
list.push(TraceCommand::CopyBufferToBuffer {
Expand Down Expand Up @@ -594,6 +597,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
if destination_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 {
return Err(TransferError::UnalignedBufferOffset(destination_offset).into());
}
if !device
.downlevel
.flags
.contains(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER)
&& (src_buffer.usage.contains(wgt::BufferUsages::INDEX)
|| dst_buffer.usage.contains(wgt::BufferUsages::INDEX))
{
let forbidden_usages = wgt::BufferUsages::VERTEX
| wgt::BufferUsages::UNIFORM
| wgt::BufferUsages::INDIRECT
| wgt::BufferUsages::STORAGE;
if src_buffer.usage.intersects(forbidden_usages)
|| dst_buffer.usage.intersects(forbidden_usages)
{
return Err(TransferError::MissingDownlevelFlags(MissingDownlevelFlags(
wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER,
))
.into());
}
}

let source_end_offset = source_offset + size;
let destination_end_offset = destination_offset + size;
Expand Down
11 changes: 11 additions & 0 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,17 @@ impl<A: HalApi> Device<A> {
});
}

if desc.usage.contains(wgt::BufferUsages::INDEX)
&& desc.usage.contains(
wgt::BufferUsages::VERTEX
| wgt::BufferUsages::UNIFORM
| wgt::BufferUsages::INDIRECT
| wgt::BufferUsages::STORAGE,
)
{
self.require_downlevel_flags(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER)?;
}

let mut usage = conv::map_buffer_usage(desc.usage);

if desc.usage.is_empty() {
Expand Down
4 changes: 3 additions & 1 deletion wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
device::{DeviceError, HostMap, MissingFeatures},
device::{DeviceError, HostMap, MissingDownlevelFlags, MissingFeatures},
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Resource, Token},
id::{AdapterId, DeviceId, SurfaceId, TextureId, Valid},
init_tracker::{BufferInitTracker, TextureInitTracker},
Expand Down Expand Up @@ -248,6 +248,8 @@ pub enum CreateBufferError {
UsageMismatch(wgt::BufferUsages),
#[error("Buffer size {requested} is greater than the maximum buffer size ({maximum})")]
MaxBufferSize { requested: u64, maximum: u64 },
#[error(transparent)]
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
}

impl<A: hal::Api> Resource for Buffer<A> {
Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/dx11/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ impl super::Adapter {
| wgt::Features::CLEAR_TEXTURE
| wgt::Features::TEXTURE_FORMAT_16BIT_NORM
| wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO;
let mut downlevel =
wgt::DownlevelFlags::BASE_VERTEX | wgt::DownlevelFlags::READ_ONLY_DEPTH_STENCIL;
let mut downlevel = wgt::DownlevelFlags::BASE_VERTEX
| wgt::DownlevelFlags::READ_ONLY_DEPTH_STENCIL
| wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER;

// Features from queries
downlevel.set(
Expand Down
5 changes: 5 additions & 0 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ impl super::Adapter {
wgt::DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED,
!(cfg!(target_arch = "wasm32") || is_angle),
);
// see https://registry.khronos.org/webgl/specs/latest/2.0/#BUFFER_OBJECT_BINDING
downlevel_flags.set(
wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER,
!cfg!(target_arch = "wasm32"),
);

let mut features = wgt::Features::empty()
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
Expand Down
9 changes: 8 additions & 1 deletion wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ bitflags::bitflags! {

/// Supports samplers with anisotropic filtering. Note this isn't actually required by
/// WebGPU, the implementation is allowed to completely ignore aniso clamp. This flag is
/// here for native backends so they can comunicate to the user of aniso is enabled.
/// here for native backends so they can communi cate to the user of aniso is enabled.
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
///
/// All backends and all devices support anisotropic filtering.
const ANISOTROPIC_FILTERING = 1 << 10;
Expand All @@ -1087,6 +1087,13 @@ bitflags::bitflags! {
///
/// WebGL doesn't support this.
const BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED = 1 << 15;

/// Supports buffers to combine [`BufferUsages::INDEX`] with usages other than [`BufferUsages::COPY_DST`] and [`BufferUsages::COPY_SRC`].
/// Furthermore, in absence of this feature it is not allowed to copy index buffers from/to buffers with a set of usage flags containing
/// [`BufferUsages::VERTEX`]/[`BufferUsages::UNIFORM`]/[`BufferUsages::STORAGE`] or [`BufferUsages::INDIRECT`].
///
/// WebGL doesn't support this.
const UNRESTRICTED_INDEX_BUFFER = 1 << 16;
}
}

Expand Down