Skip to content

Commit 6183e20

Browse files
[rs] Merge gfx-rs#493
493: Use BCn textures if possible in skybox example r=kvark a=cwfitzgerald This converts the skybox to using compressed textures if available. I have designed the code to be extensible to other compressed formats as they are added. Additionally I added srgb to the texture types, as we were using a srgb framebuffer without properly converting into linear on the texture reads. Co-authored-by: Connor Fitzgerald <[email protected]>
2 parents c320599 + aeffeaf commit 6183e20

File tree

4 files changed

+123
-79
lines changed

4 files changed

+123
-79
lines changed

wgpu/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ vulkan-portability = ["wgc/gfx-backend-vulkan"]
2727
package = "wgpu-core"
2828
version = "0.5"
2929
git = "https://github.com/gfx-rs/wgpu"
30-
rev = "9e4839eb049707629fa8a91e3603085433f352a4"
30+
rev = "b35209398823e95d71cce718fd98fa54ce43271d"
3131
features = ["raw-window-handle"]
3232

3333
[dependencies.wgt]
3434
package = "wgpu-types"
3535
version = "0.5"
3636
git = "https://github.com/gfx-rs/wgpu"
37-
rev = "9e4839eb049707629fa8a91e3603085433f352a4"
37+
rev = "b35209398823e95d71cce718fd98fa54ce43271d"
3838

3939
[dependencies]
4040
arrayvec = "0.5"
@@ -59,6 +59,7 @@ winit = { version = "0.22.1", features = ["web-sys"] }
5959
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
6060
bytemuck = "1"
6161
noise = "0.6.0"
62+
ddsfile = "0.4.0"
6263

6364
[[example]]
6465
name="hello-compute"

wgpu/examples/README.md

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,32 @@ Notably, `capture` example shows rendering without a surface/window. It reads ba
1010
All framework-based examples render to the window.
1111

1212
## Feature matrix
13-
| Feature | boids | cube | mipmap | msaa-line | shadow | skybox | texture-arrays | water |
14-
| ---------------------- | ------ | ------ | ------ | --------- | ------ | ------ | -------------- | ------ |
15-
| vertex attributes | :star: | :star: | :star: | :star: | :star: | | :star: | :star: |
16-
| instancing | :star: | | | | | | | |
17-
| lines and points | | | | :star: | | | | |
18-
| sampled color textures | :star: | :star: | :star: | | | :star: | :star: | :star: |
19-
| storage textures | :star: | | | | | | | |
20-
| binding array | | | | | | | :star: | |
21-
| comparison samplers | | | | | :star: | | | |
22-
| subresource views | | | :star: | | :star: | | | |
23-
| cubemaps | | | | | | :star: | | |
24-
| multisampling | | | | :star: | | | | |
25-
| off-screen rendering | | | | | :star: | | | :star: |
26-
| stencil testing | | | | | | | | |
27-
| depth testing | | | | | :star: | | | :star: |
28-
| depth biasing | | | | | :star: | | | |
29-
| read-only depth | | | | | | | | :star: |
30-
| blending | | | | | | | | :star: |
31-
| render bundles | | | | :star: | | | | :star: |
32-
| compute passes | :star: | | | | | | | |
33-
| optional extensions | | | | | | | :star: | |
34-
| - binding indexing | | | | | | | :star: | |
35-
| - push constants | | | | | | | :star: | |
36-
| - depth clamping | | | | | :star: | | | |
37-
| WGSL shaders | | | | | | | | |
13+
| Feature | boids | cube | mipmap | msaa-line | shadow | skybox | texture-arrays | water |
14+
| ------------------------- | ------ | ------ | ------ | --------- | ------ | ------ | -------------- | ------ |
15+
| vertex attributes | :star: | :star: | :star: | :star: | :star: | | :star: | :star: |
16+
| instancing | :star: | | | | | | | |
17+
| lines and points | | | | :star: | | | | |
18+
| sampled color textures | :star: | :star: | :star: | | | :star: | :star: | :star: |
19+
| storage textures | :star: | | | | | | | |
20+
| binding array | | | | | | | :star: | |
21+
| comparison samplers | | | | | :star: | | | |
22+
| subresource views | | | :star: | | :star: | | | |
23+
| cubemaps | | | | | | :star: | | |
24+
| multisampling | | | | :star: | | | | |
25+
| off-screen rendering | | | | | :star: | | | :star: |
26+
| stencil testing | | | | | | | | |
27+
| depth testing | | | | | :star: | | | :star: |
28+
| depth biasing | | | | | :star: | | | |
29+
| read-only depth | | | | | | | | :star: |
30+
| blending | | | | | | | | :star: |
31+
| render bundles | | | | :star: | | | | :star: |
32+
| compute passes | :star: | | | | | | | |
33+
| optional extensions | | | | | | | :star: | |
34+
| - binding indexing | | | | | | | :star: | |
35+
| - push constants | | | | | | | :star: | |
36+
| - depth clamping | | | | | :star: | | | |
37+
| - BCn compressed textures | | | | | | :star: | | |
38+
| WGSL shaders | | | | | | | | |
3839

3940
## Hacking
4041

wgpu/examples/skybox/images/bc1.dds

768 KB
Binary file not shown.

wgpu/examples/skybox/main.rs

Lines changed: 94 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use futures::task::{LocalSpawn, LocalSpawnExt};
55
use std::borrow::Cow::Borrowed;
66
use wgpu::util::DeviceExt;
77

8-
const SKYBOX_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm;
8+
const IMAGE_SIZE: u32 = 512;
99

1010
type Uniform = cgmath::Matrix4<f32>;
1111
type Uniforms = [Uniform; 2];
@@ -40,6 +40,10 @@ impl Skybox {
4040
}
4141

4242
impl framework::Example for Skybox {
43+
fn optional_features() -> wgpu::Features {
44+
wgpu::Features::TEXTURE_COMPRESSION_BC
45+
}
46+
4347
fn init(
4448
sc_desc: &wgpu::SwapChainDescriptor,
4549
device: &wgpu::Device,
@@ -79,13 +83,11 @@ impl framework::Example for Skybox {
7983

8084
let aspect = sc_desc.width as f32 / sc_desc.height as f32;
8185
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+
});
8991

9092
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
9193
bind_group_layouts: Borrowed(&[&bind_group_layout]),
@@ -136,79 +138,119 @@ impl framework::Example for Skybox {
136138
..Default::default()
137139
});
138140

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+
};
163149

164150
let texture = device.create_texture(&wgpu::TextureDescriptor {
165151
size: wgpu::Extent3d {
166-
width: image_width,
167-
height: image_height,
152+
width: IMAGE_SIZE,
153+
height: IMAGE_SIZE,
168154
depth: 6,
169155
},
170156
mip_level_count: 1,
171157
sample_count: 1,
172158
dimension: wgpu::TextureDimension::D2,
173-
format: SKYBOX_FORMAT,
159+
format: skybox_format,
174160
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
175161
label: None,
176162
});
177163

178-
for (i, image) in faces.iter().enumerate() {
164+
if single_file {
179165
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,
184169
);
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+
185179
queue.write_texture(
186180
wgpu::TextureCopyView {
187181
texture: &texture,
188182
mip_level: 0,
189-
origin: wgpu::Origin3d {
190-
x: 0,
191-
y: 0,
192-
z: i as u32,
193-
},
183+
origin: wgpu::Origin3d::ZERO,
194184
},
195-
&image,
185+
&dds_file.data,
196186
wgpu::TextureDataLayout {
197187
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,
200190
},
201191
wgpu::Extent3d {
202-
width: image_width,
203-
height: image_height,
204-
depth: 1,
192+
width: IMAGE_SIZE,
193+
height: IMAGE_SIZE,
194+
depth: 6,
205195
},
206196
);
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+
}
207249
}
208250

209251
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor {
210252
label: None,
211-
format: SKYBOX_FORMAT,
253+
format: skybox_format,
212254
dimension: wgpu::TextureViewDimension::Cube,
213255
aspect: wgpu::TextureAspect::default(),
214256
base_mip_level: 0,

0 commit comments

Comments
 (0)