@@ -5,7 +5,7 @@ use futures::task::{LocalSpawn, LocalSpawnExt};
5
5
use std:: borrow:: Cow :: Borrowed ;
6
6
use wgpu:: util:: DeviceExt ;
7
7
8
- const SKYBOX_FORMAT : wgpu :: TextureFormat = wgpu :: TextureFormat :: Rgba8Unorm ;
8
+ const IMAGE_SIZE : u32 = 512 ;
9
9
10
10
type Uniform = cgmath:: Matrix4 < f32 > ;
11
11
type Uniforms = [ Uniform ; 2 ] ;
@@ -40,6 +40,10 @@ impl Skybox {
40
40
}
41
41
42
42
impl framework:: Example for Skybox {
43
+ fn optional_features ( ) -> wgpu:: Features {
44
+ wgpu:: Features :: TEXTURE_COMPRESSION_BC
45
+ }
46
+
43
47
fn init (
44
48
sc_desc : & wgpu:: SwapChainDescriptor ,
45
49
device : & wgpu:: Device ,
@@ -79,13 +83,11 @@ impl framework::Example for Skybox {
79
83
80
84
let aspect = sc_desc. width as f32 / sc_desc. height as f32 ;
81
85
let uniforms = Self :: generate_uniforms ( aspect) ;
82
- let uniform_buf = device. create_buffer_init (
83
- & wgpu:: util:: BufferInitDescriptor {
84
- label : Some ( "Uniform Buffer" ) ,
85
- contents : bytemuck:: cast_slice ( & raw_uniforms ( & uniforms) ) ,
86
- usage : wgpu:: BufferUsage :: UNIFORM | wgpu:: BufferUsage :: COPY_DST ,
87
- }
88
- ) ;
86
+ let uniform_buf = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
87
+ label : Some ( "Uniform Buffer" ) ,
88
+ contents : bytemuck:: cast_slice ( & raw_uniforms ( & uniforms) ) ,
89
+ usage : wgpu:: BufferUsage :: UNIFORM | wgpu:: BufferUsage :: COPY_DST ,
90
+ } ) ;
89
91
90
92
let pipeline_layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
91
93
bind_group_layouts : Borrowed ( & [ & bind_group_layout] ) ,
@@ -136,79 +138,119 @@ impl framework::Example for Skybox {
136
138
..Default :: default ( )
137
139
} ) ;
138
140
139
- let paths: [ & ' static [ u8 ] ; 6 ] = [
140
- & include_bytes ! ( "images/posx.png" ) [ ..] ,
141
- & include_bytes ! ( "images/negx.png" ) [ ..] ,
142
- & include_bytes ! ( "images/posy.png" ) [ ..] ,
143
- & include_bytes ! ( "images/negy.png" ) [ ..] ,
144
- & include_bytes ! ( "images/posz.png" ) [ ..] ,
145
- & include_bytes ! ( "images/negz.png" ) [ ..] ,
146
- ] ;
147
-
148
- // we set these multiple times, but whatever
149
- let ( mut image_width, mut image_height) = ( 0 , 0 ) ;
150
- let faces = paths
151
- . iter ( )
152
- . map ( |png| {
153
- let png = std:: io:: Cursor :: new ( png) ;
154
- let decoder = png:: Decoder :: new ( png) ;
155
- let ( info, mut reader) = decoder. read_info ( ) . expect ( "can read info" ) ;
156
- image_width = info. width ;
157
- image_height = info. height ;
158
- let mut buf = vec ! [ 0 ; info. buffer_size( ) ] ;
159
- reader. next_frame ( & mut buf) . expect ( "can read png frame" ) ;
160
- buf
161
- } )
162
- . collect :: < Vec < _ > > ( ) ;
141
+ let device_features = device. features ( ) ;
142
+
143
+ let ( skybox_format, single_file) =
144
+ if device_features. contains ( wgt:: Features :: TEXTURE_COMPRESSION_BC ) {
145
+ ( wgpu:: TextureFormat :: Bc1RgbaUnormSrgb , true )
146
+ } else {
147
+ ( wgpu:: TextureFormat :: Rgba8UnormSrgb , false )
148
+ } ;
163
149
164
150
let texture = device. create_texture ( & wgpu:: TextureDescriptor {
165
151
size : wgpu:: Extent3d {
166
- width : image_width ,
167
- height : image_height ,
152
+ width : IMAGE_SIZE ,
153
+ height : IMAGE_SIZE ,
168
154
depth : 6 ,
169
155
} ,
170
156
mip_level_count : 1 ,
171
157
sample_count : 1 ,
172
158
dimension : wgpu:: TextureDimension :: D2 ,
173
- format : SKYBOX_FORMAT ,
159
+ format : skybox_format ,
174
160
usage : wgpu:: TextureUsage :: SAMPLED | wgpu:: TextureUsage :: COPY_DST ,
175
161
label : None ,
176
162
} ) ;
177
163
178
- for ( i , image ) in faces . iter ( ) . enumerate ( ) {
164
+ if single_file {
179
165
log:: debug!(
180
- "Copying skybox image {} of size {},{} to gpu" ,
181
- i,
182
- image_width,
183
- image_height,
166
+ "Copying BC1 skybox images of size {},{},6 to gpu" ,
167
+ IMAGE_SIZE ,
168
+ IMAGE_SIZE ,
184
169
) ;
170
+
171
+ let bc1_path: & [ u8 ] = & include_bytes ! ( "images/bc1.dds" ) [ ..] ;
172
+
173
+ let mut dds_cursor = std:: io:: Cursor :: new ( bc1_path) ;
174
+ let dds_file = ddsfile:: Dds :: read ( & mut dds_cursor) . unwrap ( ) ;
175
+
176
+ let block_width = 4 ;
177
+ let block_size = 8 ;
178
+
185
179
queue. write_texture (
186
180
wgpu:: TextureCopyView {
187
181
texture : & texture,
188
182
mip_level : 0 ,
189
- origin : wgpu:: Origin3d {
190
- x : 0 ,
191
- y : 0 ,
192
- z : i as u32 ,
193
- } ,
183
+ origin : wgpu:: Origin3d :: ZERO ,
194
184
} ,
195
- & image ,
185
+ & dds_file . data ,
196
186
wgpu:: TextureDataLayout {
197
187
offset : 0 ,
198
- bytes_per_row : 4 * image_width ,
199
- rows_per_image : 0 ,
188
+ bytes_per_row : block_size * ( ( IMAGE_SIZE + ( block_width - 1 ) ) / block_width ) ,
189
+ rows_per_image : IMAGE_SIZE ,
200
190
} ,
201
191
wgpu:: Extent3d {
202
- width : image_width ,
203
- height : image_height ,
204
- depth : 1 ,
192
+ width : IMAGE_SIZE ,
193
+ height : IMAGE_SIZE ,
194
+ depth : 6 ,
205
195
} ,
206
196
) ;
197
+ } else {
198
+ let paths: [ & ' static [ u8 ] ; 6 ] = [
199
+ & include_bytes ! ( "images/posx.png" ) [ ..] ,
200
+ & include_bytes ! ( "images/negx.png" ) [ ..] ,
201
+ & include_bytes ! ( "images/posy.png" ) [ ..] ,
202
+ & include_bytes ! ( "images/negy.png" ) [ ..] ,
203
+ & include_bytes ! ( "images/posz.png" ) [ ..] ,
204
+ & include_bytes ! ( "images/negz.png" ) [ ..] ,
205
+ ] ;
206
+
207
+ let faces = paths
208
+ . iter ( )
209
+ . map ( |png| {
210
+ let png = std:: io:: Cursor :: new ( png) ;
211
+ let decoder = png:: Decoder :: new ( png) ;
212
+ let ( info, mut reader) = decoder. read_info ( ) . expect ( "can read info" ) ;
213
+ let mut buf = vec ! [ 0 ; info. buffer_size( ) ] ;
214
+ reader. next_frame ( & mut buf) . expect ( "can read png frame" ) ;
215
+ buf
216
+ } )
217
+ . collect :: < Vec < _ > > ( ) ;
218
+
219
+ for ( i, image) in faces. iter ( ) . enumerate ( ) {
220
+ log:: debug!(
221
+ "Copying skybox image {} of size {},{} to gpu" ,
222
+ i,
223
+ IMAGE_SIZE ,
224
+ IMAGE_SIZE ,
225
+ ) ;
226
+ queue. write_texture (
227
+ wgpu:: TextureCopyView {
228
+ texture : & texture,
229
+ mip_level : 0 ,
230
+ origin : wgpu:: Origin3d {
231
+ x : 0 ,
232
+ y : 0 ,
233
+ z : i as u32 ,
234
+ } ,
235
+ } ,
236
+ & image,
237
+ wgpu:: TextureDataLayout {
238
+ offset : 0 ,
239
+ bytes_per_row : 4 * IMAGE_SIZE ,
240
+ rows_per_image : 0 ,
241
+ } ,
242
+ wgpu:: Extent3d {
243
+ width : IMAGE_SIZE ,
244
+ height : IMAGE_SIZE ,
245
+ depth : 1 ,
246
+ } ,
247
+ ) ;
248
+ }
207
249
}
208
250
209
251
let texture_view = texture. create_view ( & wgpu:: TextureViewDescriptor {
210
252
label : None ,
211
- format : SKYBOX_FORMAT ,
253
+ format : skybox_format ,
212
254
dimension : wgpu:: TextureViewDimension :: Cube ,
213
255
aspect : wgpu:: TextureAspect :: default ( ) ,
214
256
base_mip_level : 0 ,
0 commit comments