Skip to content

Commit fcfe77d

Browse files
committed
ByteAddressableBuffer: remove mut variant, make ByteAddressableBuffer generic on mutability
1 parent f4956fc commit fcfe77d

File tree

11 files changed

+132
-59
lines changed

11 files changed

+132
-59
lines changed

crates/spirv-std/src/byte_addressable_buffer.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,16 @@ unsafe fn buffer_store_intrinsic<T>(
4343
.write(value);
4444
}
4545

46-
/// `ByteAddressableBuffer` is a read-only untyped blob of data, allowing loads
47-
/// of arbitrary basic data types at arbitrary indices. See
48-
/// [`MutByteAddressableBuffer`] for a writeable variant.
46+
/// `ByteAddressableBuffer` is a view to an untyped blob of data, allowing
47+
/// loads and stores of arbitrary basic data types at arbitrary indices. Use
48+
/// `from_slice()` or `from_mut_slice()` to create the `ByteAddressableBuffer`,
49+
/// with only the mutable slice allowing stores.
4950
///
5051
/// # Alignment
5152
/// All data must be aligned to size 4, each element within the data (e.g.
5253
/// struct fields) must have a size and alignment of a multiple of 4, and the
5354
/// `byte_index` passed to load and store must be a multiple of 4. Technically
54-
/// it's not a *byte* addressable buffer, but rather a *word* buffer, but this
55+
/// it is not a *byte* addressable buffer, but rather a *word* buffer, but this
5556
/// naming and behavior was inherited from HLSL (where it's UB to pass in an
5657
/// index not a multiple of 4).
5758
///
@@ -61,15 +62,15 @@ unsafe fn buffer_store_intrinsic<T>(
6162
/// allowing all sorts of safety guarantees to be bypassed (effectively a
6263
/// transmute).
6364
#[repr(transparent)]
64-
pub struct ByteAddressableBuffer<'a> {
65+
pub struct ByteAddressableBuffer<T> {
6566
/// The underlying array of bytes, able to be directly accessed.
66-
pub data: &'a [u32],
67+
pub data: T,
6768
}
6869

69-
impl<'a> ByteAddressableBuffer<'a> {
70+
impl<'a> ByteAddressableBuffer<&'a [u32]> {
7071
/// Creates a `ByteAddressableBuffer` from the untyped blob of data.
7172
#[inline]
72-
pub fn new(data: &'a [u32]) -> Self {
73+
pub fn from_slice(data: &'a [u32]) -> Self {
7374
Self { data }
7475
}
7576

@@ -102,19 +103,10 @@ impl<'a> ByteAddressableBuffer<'a> {
102103
}
103104
}
104105

105-
/// `MutByteAddressableBuffer` is a mutable untyped blob of data, allowing
106-
/// loads and stores of arbitrary basic data types at arbitrary indices. See
107-
/// [`ByteAddressableBuffer`] for details.
108-
#[repr(transparent)]
109-
pub struct MutByteAddressableBuffer<'a> {
110-
/// The underlying array of bytes, able to be directly accessed.
111-
pub data: &'a mut [u32],
112-
}
113-
114-
impl<'a> MutByteAddressableBuffer<'a> {
106+
impl<'a> ByteAddressableBuffer<&'a mut [u32]> {
115107
/// Creates a `ByteAddressableBuffer` from the untyped blob of data.
116108
#[inline]
117-
pub fn new(data: &'a mut [u32]) -> Self {
109+
pub fn from_mut_slice(data: &'a mut [u32]) -> Self {
118110
Self { data }
119111
}
120112

crates/spirv-std/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,10 @@ pub mod vector;
112112

113113
pub use self::sampler::Sampler;
114114
pub use crate::macros::Image;
115+
pub use byte_addressable_buffer::ByteAddressableBuffer;
115116
pub use num_traits;
116117
pub use runtime_array::*;
117118
pub use typed_buffer::*;
118-
pub use {
119-
byte_addressable_buffer::ByteAddressableBuffer,
120-
byte_addressable_buffer::MutByteAddressableBuffer,
121-
};
122119

123120
pub use glam;
124121

tests/ui/arch/debug_printf_type_checking.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ help: the return type of this call is `u32` due to the type of the argument pass
7575
| |
7676
| this argument influences the return type of `spirv_std`
7777
note: function defined here
78-
--> $SPIRV_STD_SRC/lib.rs:141:8
78+
--> $SPIRV_STD_SRC/lib.rs:138:8
7979
|
80-
141 | pub fn debug_printf_assert_is_type<T>(ty: T) -> T {
80+
138 | pub fn debug_printf_assert_is_type<T>(ty: T) -> T {
8181
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
8282
= note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info)
8383
help: change the type of the numeric literal from `u32` to `f32`
@@ -102,9 +102,9 @@ help: the return type of this call is `f32` due to the type of the argument pass
102102
| |
103103
| this argument influences the return type of `spirv_std`
104104
note: function defined here
105-
--> $SPIRV_STD_SRC/lib.rs:141:8
105+
--> $SPIRV_STD_SRC/lib.rs:138:8
106106
|
107-
141 | pub fn debug_printf_assert_is_type<T>(ty: T) -> T {
107+
138 | pub fn debug_printf_assert_is_type<T>(ty: T) -> T {
108108
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
109109
= note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info)
110110
help: change the type of the numeric literal from `f32` to `u32`
@@ -129,12 +129,12 @@ error[E0277]: the trait bound `{float}: Vector<f32, 2>` is not satisfied
129129
<UVec3 as Vector<u32, 3>>
130130
and 5 others
131131
note: required by a bound in `debug_printf_assert_is_vector`
132-
--> $SPIRV_STD_SRC/lib.rs:148:8
132+
--> $SPIRV_STD_SRC/lib.rs:145:8
133133
|
134-
146 | pub fn debug_printf_assert_is_vector<
134+
143 | pub fn debug_printf_assert_is_vector<
135135
| ----------------------------- required by a bound in this function
136-
147 | TY: crate::scalar::Scalar,
137-
148 | V: crate::vector::Vector<TY, SIZE>,
136+
144 | TY: crate::scalar::Scalar,
137+
145 | V: crate::vector::Vector<TY, SIZE>,
138138
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `debug_printf_assert_is_vector`
139139
= note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info)
140140

@@ -155,9 +155,9 @@ help: the return type of this call is `Vec2` due to the type of the argument pas
155155
| |
156156
| this argument influences the return type of `spirv_std`
157157
note: function defined here
158-
--> $SPIRV_STD_SRC/lib.rs:141:8
158+
--> $SPIRV_STD_SRC/lib.rs:138:8
159159
|
160-
141 | pub fn debug_printf_assert_is_type<T>(ty: T) -> T {
160+
138 | pub fn debug_printf_assert_is_type<T>(ty: T) -> T {
161161
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
162162
= note: this error originates in the macro `debug_printf` (in Nightly builds, run with -Z macro-backtrace for more info)
163163

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
// build-pass
22

33
use spirv_std::spirv;
4-
use spirv_std::{glam::Vec4, ByteAddressableBuffer, MutByteAddressableBuffer};
4+
use spirv_std::{glam::Vec4, ByteAddressableBuffer};
55

66
#[spirv(fragment)]
77
pub fn load(
8+
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32],
9+
out: &mut [i32; 4],
10+
) {
11+
unsafe {
12+
let buf = ByteAddressableBuffer::from_slice(buf);
13+
*out = buf.load(5);
14+
}
15+
}
16+
17+
#[spirv(fragment)]
18+
pub fn load_mut(
819
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32],
920
out: &mut [i32; 4],
1021
) {
1122
unsafe {
12-
let buf = ByteAddressableBuffer::new(buf);
23+
let buf = ByteAddressableBuffer::from_mut_slice(buf);
1324
*out = buf.load(5);
1425
}
1526
}
@@ -20,7 +31,7 @@ pub fn store(
2031
#[spirv(flat)] val: [i32; 4],
2132
) {
2233
unsafe {
23-
let mut buf = MutByteAddressableBuffer::new(buf);
34+
let mut buf = ByteAddressableBuffer::from_mut_slice(buf);
2435
buf.store(5, val);
2536
}
2637
}

tests/ui/byte_addressable_buffer/big_struct.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// build-pass
22

33
use spirv_std::spirv;
4-
use spirv_std::{ByteAddressableBuffer, MutByteAddressableBuffer};
4+
use spirv_std::ByteAddressableBuffer;
55

66
pub struct BigStruct {
77
a: u32,
@@ -14,11 +14,22 @@ pub struct BigStruct {
1414

1515
#[spirv(fragment)]
1616
pub fn load(
17+
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32],
18+
out: &mut BigStruct,
19+
) {
20+
unsafe {
21+
let buf = ByteAddressableBuffer::from_slice(buf);
22+
*out = buf.load(5);
23+
}
24+
}
25+
26+
#[spirv(fragment)]
27+
pub fn load_mut(
1728
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32],
1829
out: &mut BigStruct,
1930
) {
2031
unsafe {
21-
let buf = ByteAddressableBuffer::new(buf);
32+
let buf = ByteAddressableBuffer::from_mut_slice(buf);
2233
*out = buf.load(5);
2334
}
2435
}
@@ -29,7 +40,7 @@ pub fn store(
2940
#[spirv(flat)] val: BigStruct,
3041
) {
3142
unsafe {
32-
let mut buf = MutByteAddressableBuffer::new(buf);
43+
let mut buf = ByteAddressableBuffer::from_mut_slice(buf);
3344
buf.store(5, val);
3445
}
3546
}

tests/ui/byte_addressable_buffer/complex.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// build-pass
22

33
use spirv_std::spirv;
4-
use spirv_std::{glam::Vec2, ByteAddressableBuffer, MutByteAddressableBuffer};
4+
use spirv_std::{glam::Vec2, ByteAddressableBuffer};
55

66
pub struct Complex {
77
x: u32,
@@ -20,11 +20,22 @@ pub struct Nesty {
2020

2121
#[spirv(fragment)]
2222
pub fn load(
23+
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32],
24+
out: &mut Nesty,
25+
) {
26+
unsafe {
27+
let buf = ByteAddressableBuffer::from_slice(buf);
28+
*out = buf.load(5);
29+
}
30+
}
31+
32+
#[spirv(fragment)]
33+
pub fn load_mut(
2334
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32],
2435
out: &mut Nesty,
2536
) {
2637
unsafe {
27-
let buf = ByteAddressableBuffer::new(buf);
38+
let buf = ByteAddressableBuffer::from_mut_slice(buf);
2839
*out = buf.load(5);
2940
}
3041
}
@@ -35,7 +46,7 @@ pub fn store(
3546
val: Nesty,
3647
) {
3748
unsafe {
38-
let mut buf = MutByteAddressableBuffer::new(buf);
49+
let mut buf = ByteAddressableBuffer::from_mut_slice(buf);
3950
buf.store(5, val);
4051
}
4152
}
Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
// build-pass
22

33
use spirv_std::spirv;
4-
use spirv_std::{ByteAddressableBuffer, MutByteAddressableBuffer};
4+
use spirv_std::ByteAddressableBuffer;
55

66
pub struct EmptyStruct {}
77

88
#[spirv(fragment)]
99
pub fn load(
10+
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32],
11+
out: &mut EmptyStruct,
12+
) {
13+
unsafe {
14+
let buf = ByteAddressableBuffer::from_slice(buf);
15+
*out = buf.load(5);
16+
}
17+
}
18+
19+
#[spirv(fragment)]
20+
pub fn load_mut(
1021
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32],
1122
out: &mut EmptyStruct,
1223
) {
1324
unsafe {
14-
let buf = ByteAddressableBuffer::new(buf);
25+
let buf = ByteAddressableBuffer::from_mut_slice(buf);
1526
*out = buf.load(5);
1627
}
1728
}
@@ -20,7 +31,7 @@ pub fn load(
2031
pub fn store(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32]) {
2132
let val = EmptyStruct {};
2233
unsafe {
23-
let mut buf = MutByteAddressableBuffer::new(buf);
34+
let mut buf = ByteAddressableBuffer::from_mut_slice(buf);
2435
buf.store(5, val);
2536
}
2637
}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
// build-pass
22

33
use spirv_std::spirv;
4-
use spirv_std::{ByteAddressableBuffer, MutByteAddressableBuffer};
4+
use spirv_std::ByteAddressableBuffer;
55

66
#[spirv(fragment)]
7-
pub fn load(
7+
pub fn load(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32], out: &mut f32) {
8+
unsafe {
9+
let buf = ByteAddressableBuffer::from_slice(buf);
10+
*out = buf.load(5);
11+
}
12+
}
13+
14+
#[spirv(fragment)]
15+
pub fn load_mut(
816
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32],
917
out: &mut f32,
1018
) {
1119
unsafe {
12-
let buf = ByteAddressableBuffer::new(buf);
20+
let buf = ByteAddressableBuffer::from_mut_slice(buf);
1321
*out = buf.load(5);
1422
}
1523
}
1624

1725
#[spirv(fragment)]
1826
pub fn store(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], val: f32) {
1927
unsafe {
20-
let mut buf = MutByteAddressableBuffer::new(buf);
28+
let mut buf = ByteAddressableBuffer::from_mut_slice(buf);
2129
buf.store(5, val);
2230
}
2331
}

tests/ui/byte_addressable_buffer/small_struct.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// build-pass
22

33
use spirv_std::spirv;
4-
use spirv_std::{ByteAddressableBuffer, MutByteAddressableBuffer};
4+
use spirv_std::ByteAddressableBuffer;
55

66
pub struct SmallStruct {
77
a: u32,
@@ -10,11 +10,22 @@ pub struct SmallStruct {
1010

1111
#[spirv(fragment)]
1212
pub fn load(
13+
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32],
14+
out: &mut SmallStruct,
15+
) {
16+
unsafe {
17+
let buf = ByteAddressableBuffer::from_slice(buf);
18+
*out = buf.load(5);
19+
}
20+
}
21+
22+
#[spirv(fragment)]
23+
pub fn load_mut(
1324
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32],
1425
out: &mut SmallStruct,
1526
) {
1627
unsafe {
17-
let buf = ByteAddressableBuffer::new(buf);
28+
let buf = ByteAddressableBuffer::from_mut_slice(buf);
1829
*out = buf.load(5);
1930
}
2031
}
@@ -27,7 +38,7 @@ pub fn store(
2738
) {
2839
let val = SmallStruct { a, b };
2940
unsafe {
30-
let mut buf = MutByteAddressableBuffer::new(buf);
41+
let mut buf = ByteAddressableBuffer::from_mut_slice(buf);
3142
buf.store(5, val);
3243
}
3344
}

0 commit comments

Comments
 (0)