Skip to content

Commit b838b08

Browse files
Wumpfcwfitzgerald
andauthored
Added new UNRESTRICTED_INDEX_BUFFER downlevel flag. (#3157)
Co-authored-by: Connor Fitzgerald <[email protected]>
1 parent db30e39 commit b838b08

File tree

7 files changed

+54
-4
lines changed

7 files changed

+54
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Bottom level categories:
4747
- Convert all `Default` Implementations on Enums to `derive(Default)`
4848
- Implement `Default` for `CompositeAlphaMode`
4949
- Improve compute shader validation error message. By @haraldreingruber in [#3139](https://github.com/gfx-rs/wgpu/pull/3139)
50+
- 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)
5051

5152
#### WebGPU
5253
- Implement `queue_validate_write_buffer` by @jinleili in [#3098](https://github.com/gfx-rs/wgpu/pull/3098)

wgpu-core/src/command/transfer.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
544544
let hub = A::hub(self);
545545
let mut token = Token::root();
546546

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

552+
let device = &device_guard[cmd_buf.device_id.value];
553+
551554
#[cfg(feature = "trace")]
552555
if let Some(ref mut list) = cmd_buf.commands {
553556
list.push(TraceCommand::CopyBufferToBuffer {
@@ -597,6 +600,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
597600
if destination_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 {
598601
return Err(TransferError::UnalignedBufferOffset(destination_offset).into());
599602
}
603+
if !device
604+
.downlevel
605+
.flags
606+
.contains(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER)
607+
&& (src_buffer.usage.contains(wgt::BufferUsages::INDEX)
608+
|| dst_buffer.usage.contains(wgt::BufferUsages::INDEX))
609+
{
610+
let forbidden_usages = wgt::BufferUsages::VERTEX
611+
| wgt::BufferUsages::UNIFORM
612+
| wgt::BufferUsages::INDIRECT
613+
| wgt::BufferUsages::STORAGE;
614+
if src_buffer.usage.intersects(forbidden_usages)
615+
|| dst_buffer.usage.intersects(forbidden_usages)
616+
{
617+
return Err(TransferError::MissingDownlevelFlags(MissingDownlevelFlags(
618+
wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER,
619+
))
620+
.into());
621+
}
622+
}
600623

601624
let source_end_offset = source_offset + size;
602625
let destination_end_offset = destination_offset + size;

wgpu-core/src/device/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,17 @@ impl<A: HalApi> Device<A> {
590590
});
591591
}
592592

593+
if desc.usage.contains(wgt::BufferUsages::INDEX)
594+
&& desc.usage.contains(
595+
wgt::BufferUsages::VERTEX
596+
| wgt::BufferUsages::UNIFORM
597+
| wgt::BufferUsages::INDIRECT
598+
| wgt::BufferUsages::STORAGE,
599+
)
600+
{
601+
self.require_downlevel_flags(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER)?;
602+
}
603+
593604
let mut usage = conv::map_buffer_usage(desc.usage);
594605

595606
if desc.usage.is_empty() {

wgpu-core/src/resource.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
device::{DeviceError, HostMap, MissingFeatures},
2+
device::{DeviceError, HostMap, MissingDownlevelFlags, MissingFeatures},
33
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Resource, Token},
44
id::{AdapterId, DeviceId, SurfaceId, TextureId, Valid},
55
init_tracker::{BufferInitTracker, TextureInitTracker},
@@ -248,6 +248,8 @@ pub enum CreateBufferError {
248248
UsageMismatch(wgt::BufferUsages),
249249
#[error("Buffer size {requested} is greater than the maximum buffer size ({maximum})")]
250250
MaxBufferSize { requested: u64, maximum: u64 },
251+
#[error(transparent)]
252+
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
251253
}
252254

253255
impl<A: hal::Api> Resource for Buffer<A> {

wgpu-hal/src/dx11/adapter.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ impl super::Adapter {
9191
| wgt::Features::CLEAR_TEXTURE
9292
| wgt::Features::TEXTURE_FORMAT_16BIT_NORM
9393
| wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO;
94-
let mut downlevel =
95-
wgt::DownlevelFlags::BASE_VERTEX | wgt::DownlevelFlags::READ_ONLY_DEPTH_STENCIL;
94+
let mut downlevel = wgt::DownlevelFlags::BASE_VERTEX
95+
| wgt::DownlevelFlags::READ_ONLY_DEPTH_STENCIL
96+
| wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER;
9697

9798
// Features from queries
9899
downlevel.set(

wgpu-hal/src/gles/adapter.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ impl super::Adapter {
312312
wgt::DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED,
313313
!(cfg!(target_arch = "wasm32") || is_angle),
314314
);
315+
// see https://registry.khronos.org/webgl/specs/latest/2.0/#BUFFER_OBJECT_BINDING
316+
downlevel_flags.set(
317+
wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER,
318+
!cfg!(target_arch = "wasm32"),
319+
);
315320

316321
let mut features = wgt::Features::empty()
317322
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES

wgpu-types/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ bitflags::bitflags! {
10561056

10571057
/// Supports samplers with anisotropic filtering. Note this isn't actually required by
10581058
/// WebGPU, the implementation is allowed to completely ignore aniso clamp. This flag is
1059-
/// here for native backends so they can comunicate to the user of aniso is enabled.
1059+
/// here for native backends so they can communicate to the user of aniso is enabled.
10601060
///
10611061
/// All backends and all devices support anisotropic filtering.
10621062
const ANISOTROPIC_FILTERING = 1 << 10;
@@ -1080,6 +1080,13 @@ bitflags::bitflags! {
10801080
///
10811081
/// WebGL doesn't support this.
10821082
const BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED = 1 << 15;
1083+
1084+
/// Supports buffers to combine [`BufferUsages::INDEX`] with usages other than [`BufferUsages::COPY_DST`] and [`BufferUsages::COPY_SRC`].
1085+
/// Furthermore, in absence of this feature it is not allowed to copy index buffers from/to buffers with a set of usage flags containing
1086+
/// [`BufferUsages::VERTEX`]/[`BufferUsages::UNIFORM`]/[`BufferUsages::STORAGE`] or [`BufferUsages::INDIRECT`].
1087+
///
1088+
/// WebGL doesn't support this.
1089+
const UNRESTRICTED_INDEX_BUFFER = 1 << 16;
10831090
}
10841091
}
10851092

0 commit comments

Comments
 (0)