@@ -4,55 +4,82 @@ use wgpu_test::{initialize_test, TestParameters};
4
4
5
5
use wasm_bindgen_test:: * ;
6
6
7
- #[ test]
8
- #[ wasm_bindgen_test]
9
- fn write_texture_subset_2d ( ) {
10
- let size = 256 ;
11
- let parameters = TestParameters :: default ( ) . backend_failure ( wgpu:: Backends :: DX12 ) ;
7
+ fn total_bytes_in_copy (
8
+ texture_format : wgpu:: TextureFormat ,
9
+ bytes_per_row : u32 ,
10
+ rows_per_image : u32 ,
11
+ copy_extent : wgpu:: Extent3d ,
12
+ ) -> u32 {
13
+ let block_size = texture_format. block_size ( None ) . unwrap_or ( 1 ) ;
14
+
15
+ let block_dim = texture_format. block_dimensions ( ) ;
16
+
17
+ let block_width = copy_extent. width / block_dim. 0 ;
18
+ let block_height = copy_extent. height / block_dim. 1 ;
19
+
20
+ let bytes_per_image = bytes_per_row * rows_per_image;
21
+ let mut total_bytes = bytes_per_image * ( copy_extent. depth_or_array_layers - 1 ) ;
22
+
23
+ if block_height != 0 {
24
+ let last_row_bytes = block_width * block_size;
25
+ let last_image_bytes = bytes_per_row * ( block_height - 1 ) + last_row_bytes;
26
+ total_bytes += last_image_bytes;
27
+ }
28
+
29
+ total_bytes
30
+ }
31
+
32
+ fn test (
33
+ format : wgpu:: TextureFormat ,
34
+ bytes_per_row : u32 ,
35
+ rows_per_image : u32 ,
36
+ total_size_in_bytes : u32 ,
37
+ mip_level : u32 ,
38
+ mips_count : u32 ,
39
+ tex_size : wgpu:: Extent3d ,
40
+ write_size : wgpu:: Extent3d ,
41
+ copy_size : wgpu:: Extent3d ,
42
+ ) {
43
+ let parameters = TestParameters :: default ( ) ;
12
44
initialize_test ( parameters, |ctx| {
13
45
let tex = ctx. device . create_texture ( & wgpu:: TextureDescriptor {
14
46
label : None ,
15
47
dimension : wgpu:: TextureDimension :: D2 ,
16
- size : wgpu:: Extent3d {
17
- width : size,
18
- height : size,
19
- depth_or_array_layers : 1 ,
20
- } ,
21
- format : wgpu:: TextureFormat :: R8Uint ,
48
+ size : tex_size,
49
+ format,
22
50
usage : wgpu:: TextureUsages :: COPY_DST
23
51
| wgpu:: TextureUsages :: COPY_SRC
24
52
| wgpu:: TextureUsages :: TEXTURE_BINDING ,
25
- mip_level_count : 1 ,
53
+ mip_level_count : mips_count ,
26
54
sample_count : 1 ,
27
55
view_formats : & [ ] ,
28
56
} ) ;
29
- let data = vec ! [ 1u8 ; size as usize * 2 ] ;
57
+
58
+ let val = ( mip_level + 1 ) as u8 ;
59
+ let data = vec ! [ val; total_size_in_bytes as usize ] ;
60
+
30
61
// Write the first two rows
31
62
ctx. queue . write_texture (
32
63
wgpu:: ImageCopyTexture {
33
64
texture : & tex,
34
- mip_level : 0 ,
65
+ mip_level,
35
66
origin : wgpu:: Origin3d :: ZERO ,
36
67
aspect : wgpu:: TextureAspect :: All ,
37
68
} ,
38
69
bytemuck:: cast_slice ( & data) ,
39
70
wgpu:: ImageDataLayout {
40
71
offset : 0 ,
41
- bytes_per_row : Some ( size) ,
42
- rows_per_image : Some ( size) ,
43
- } ,
44
- wgpu:: Extent3d {
45
- width : size,
46
- height : 2 ,
47
- depth_or_array_layers : 1 ,
72
+ bytes_per_row : Some ( bytes_per_row) ,
73
+ rows_per_image : Some ( rows_per_image) ,
48
74
} ,
75
+ write_size,
49
76
) ;
50
77
51
78
ctx. queue . submit ( None ) ;
52
79
53
80
let read_buffer = ctx. device . create_buffer ( & wgpu:: BufferDescriptor {
54
81
label : None ,
55
- size : ( size * size ) as u64 ,
82
+ size : ( total_size_in_bytes ) as u64 ,
56
83
usage : wgpu:: BufferUsages :: MAP_READ | wgpu:: BufferUsages :: COPY_DST ,
57
84
mapped_at_creation : false ,
58
85
} ) ;
@@ -64,23 +91,19 @@ fn write_texture_subset_2d() {
64
91
encoder. copy_texture_to_buffer (
65
92
wgpu:: ImageCopyTexture {
66
93
texture : & tex,
67
- mip_level : 0 ,
94
+ mip_level,
68
95
origin : wgpu:: Origin3d :: ZERO ,
69
96
aspect : wgpu:: TextureAspect :: All ,
70
97
} ,
71
98
wgpu:: ImageCopyBuffer {
72
99
buffer : & read_buffer,
73
100
layout : wgpu:: ImageDataLayout {
74
101
offset : 0 ,
75
- bytes_per_row : Some ( size ) ,
76
- rows_per_image : Some ( size ) ,
102
+ bytes_per_row : Some ( bytes_per_row ) ,
103
+ rows_per_image : Some ( rows_per_image ) ,
77
104
} ,
78
105
} ,
79
- wgpu:: Extent3d {
80
- width : size,
81
- height : size,
82
- depth_or_array_layers : 1 ,
83
- } ,
106
+ copy_size,
84
107
) ;
85
108
86
109
ctx. queue . submit ( Some ( encoder. finish ( ) ) ) ;
@@ -90,107 +113,113 @@ fn write_texture_subset_2d() {
90
113
ctx. device . poll ( wgpu:: Maintain :: Wait ) ;
91
114
let data: Vec < u8 > = slice. get_mapped_range ( ) . to_vec ( ) ;
92
115
93
- for byte in & data[ ..( size as usize * 2 ) ] {
94
- assert_eq ! ( * byte, 1 ) ;
116
+ for byte in & data[ ..( total_size_in_bytes as usize ) ] {
117
+ assert_eq ! ( * byte, val ) ;
95
118
}
96
- for byte in & data[ ( size as usize * 2 ) ..] {
119
+ for byte in & data[ ( total_size_in_bytes as usize ) ..] {
97
120
assert_eq ! ( * byte, 0 ) ;
98
121
}
99
122
} ) ;
100
123
}
101
124
102
125
#[ test]
103
126
#[ wasm_bindgen_test]
104
- fn write_texture_subset_3d ( ) {
105
- let size = 256 ;
106
- let depth = 4 ;
107
- let parameters = TestParameters :: default ( ) ;
108
- initialize_test ( parameters, |ctx| {
109
- let tex = ctx. device . create_texture ( & wgpu:: TextureDescriptor {
110
- label : None ,
111
- dimension : wgpu:: TextureDimension :: D3 ,
112
- size : wgpu:: Extent3d {
113
- width : size,
114
- height : size,
115
- depth_or_array_layers : depth,
116
- } ,
117
- format : wgpu:: TextureFormat :: R8Uint ,
118
- usage : wgpu:: TextureUsages :: COPY_DST
119
- | wgpu:: TextureUsages :: COPY_SRC
120
- | wgpu:: TextureUsages :: TEXTURE_BINDING ,
121
- mip_level_count : 1 ,
122
- sample_count : 1 ,
123
- view_formats : & [ ] ,
124
- } ) ;
125
- let data = vec ! [ 1u8 ; ( size * size) as usize * 2 ] ;
126
- // Write the first two slices
127
- ctx. queue . write_texture (
128
- wgpu:: ImageCopyTexture {
129
- texture : & tex,
130
- mip_level : 0 ,
131
- origin : wgpu:: Origin3d :: ZERO ,
132
- aspect : wgpu:: TextureAspect :: All ,
133
- } ,
134
- bytemuck:: cast_slice ( & data) ,
135
- wgpu:: ImageDataLayout {
136
- offset : 0 ,
137
- bytes_per_row : Some ( size) ,
138
- rows_per_image : Some ( size) ,
139
- } ,
140
- wgpu:: Extent3d {
141
- width : size,
142
- height : size,
143
- depth_or_array_layers : 2 ,
144
- } ,
145
- ) ;
146
-
147
- ctx. queue . submit ( None ) ;
148
-
149
- let read_buffer = ctx. device . create_buffer ( & wgpu:: BufferDescriptor {
150
- label : None ,
151
- size : ( size * size * depth) as u64 ,
152
- usage : wgpu:: BufferUsages :: MAP_READ | wgpu:: BufferUsages :: COPY_DST ,
153
- mapped_at_creation : false ,
154
- } ) ;
155
-
156
- let mut encoder = ctx
157
- . device
158
- . create_command_encoder ( & wgpu:: CommandEncoderDescriptor { label : None } ) ;
127
+ fn write_texture_subset_2d ( ) {
128
+ let format = wgpu:: TextureFormat :: R8Uint ;
129
+ let mips_count = 1 ;
130
+ let tex_size = wgpu:: Extent3d {
131
+ width : 256 ,
132
+ height : 256 ,
133
+ depth_or_array_layers : 1 ,
134
+ } ;
135
+
136
+ let bytes_per_row = tex_size. width ;
137
+ let rows_per_image = tex_size. height ;
138
+
139
+ let total_bytes_in_copy = total_bytes_in_copy ( format, bytes_per_row, rows_per_image, tex_size) ;
140
+
141
+ test (
142
+ format,
143
+ bytes_per_row,
144
+ rows_per_image,
145
+ total_bytes_in_copy,
146
+ 0 ,
147
+ mips_count,
148
+ tex_size,
149
+ tex_size,
150
+ tex_size,
151
+ ) ;
152
+ }
159
153
160
- encoder. copy_texture_to_buffer (
161
- wgpu:: ImageCopyTexture {
162
- texture : & tex,
163
- mip_level : 0 ,
164
- origin : wgpu:: Origin3d :: ZERO ,
165
- aspect : wgpu:: TextureAspect :: All ,
166
- } ,
167
- wgpu:: ImageCopyBuffer {
168
- buffer : & read_buffer,
169
- layout : wgpu:: ImageDataLayout {
170
- offset : 0 ,
171
- bytes_per_row : Some ( size) ,
172
- rows_per_image : Some ( size) ,
173
- } ,
174
- } ,
175
- wgpu:: Extent3d {
176
- width : size,
177
- height : size,
178
- depth_or_array_layers : depth,
179
- } ,
154
+ #[ test]
155
+ #[ wasm_bindgen_test]
156
+ fn write_texture_subset_2d_mips ( ) {
157
+ let format = wgpu:: TextureFormat :: R8Uint ;
158
+ let mips_count = 3 ;
159
+ let tex_size = wgpu:: Extent3d {
160
+ width : 2048 ,
161
+ height : 2048 ,
162
+ depth_or_array_layers : 1 ,
163
+ } ;
164
+ for mip_level in 0 ..mips_count {
165
+ let mip_w = tex_size. width / ( 1 << mip_level) ;
166
+ let mip_h = tex_size. height / ( 1 << mip_level) ;
167
+ let bytes_per_row = mip_w;
168
+ let rows_per_image = mip_h;
169
+
170
+ let mip_extent = wgpu:: Extent3d {
171
+ width : mip_w,
172
+ height : 2 ,
173
+ depth_or_array_layers : tex_size. depth_or_array_layers ,
174
+ } ;
175
+
176
+ let total_bytes_in_copy =
177
+ total_bytes_in_copy ( format, bytes_per_row, rows_per_image, mip_extent) ;
178
+
179
+ test (
180
+ format,
181
+ bytes_per_row,
182
+ rows_per_image,
183
+ total_bytes_in_copy,
184
+ mip_level,
185
+ mips_count,
186
+ tex_size,
187
+ mip_extent,
188
+ mip_extent,
180
189
) ;
190
+ }
191
+ }
181
192
182
- ctx. queue . submit ( Some ( encoder. finish ( ) ) ) ;
183
-
184
- let slice = read_buffer. slice ( ..) ;
185
- slice. map_async ( wgpu:: MapMode :: Read , |_| ( ) ) ;
186
- ctx. device . poll ( wgpu:: Maintain :: Wait ) ;
187
- let data: Vec < u8 > = slice. get_mapped_range ( ) . to_vec ( ) ;
188
-
189
- for byte in & data[ ..( ( size * size) as usize * 2 ) ] {
190
- assert_eq ! ( * byte, 1 ) ;
191
- }
192
- for byte in & data[ ( ( size * size) as usize * 2 ) ..] {
193
- assert_eq ! ( * byte, 0 ) ;
194
- }
195
- } ) ;
193
+ #[ test]
194
+ #[ wasm_bindgen_test]
195
+ fn write_texture_subset_3d ( ) {
196
+ let format = wgpu:: TextureFormat :: R8Uint ;
197
+ let mips_count = 1 ;
198
+ let tex_size = wgpu:: Extent3d {
199
+ width : 256 ,
200
+ height : 256 ,
201
+ depth_or_array_layers : 4 ,
202
+ } ;
203
+ let copy_size = wgpu:: Extent3d {
204
+ width : 256 ,
205
+ height : 256 ,
206
+ depth_or_array_layers : 2 ,
207
+ } ;
208
+
209
+ let bytes_per_row = tex_size. width ;
210
+ let rows_per_image = tex_size. height ;
211
+
212
+ let total_bytes_in_copy = total_bytes_in_copy ( format, bytes_per_row, rows_per_image, copy_size) ;
213
+
214
+ test (
215
+ format,
216
+ bytes_per_row,
217
+ rows_per_image,
218
+ total_bytes_in_copy,
219
+ 0 ,
220
+ mips_count,
221
+ tex_size,
222
+ copy_size,
223
+ copy_size,
224
+ ) ;
196
225
}
0 commit comments