Skip to content

Commit

Permalink
[rs] Merge gfx-rs#493
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bors[bot] and cwfitzgerald authored Jul 31, 2020
2 parents c320599 + aeffeaf commit 6183e20
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 79 deletions.
5 changes: 3 additions & 2 deletions wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ vulkan-portability = ["wgc/gfx-backend-vulkan"]
package = "wgpu-core"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "9e4839eb049707629fa8a91e3603085433f352a4"
rev = "b35209398823e95d71cce718fd98fa54ce43271d"
features = ["raw-window-handle"]

[dependencies.wgt]
package = "wgpu-types"
version = "0.5"
git = "https://github.com/gfx-rs/wgpu"
rev = "9e4839eb049707629fa8a91e3603085433f352a4"
rev = "b35209398823e95d71cce718fd98fa54ce43271d"

[dependencies]
arrayvec = "0.5"
Expand All @@ -59,6 +59,7 @@ winit = { version = "0.22.1", features = ["web-sys"] }
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
bytemuck = "1"
noise = "0.6.0"
ddsfile = "0.4.0"

[[example]]
name="hello-compute"
Expand Down
51 changes: 26 additions & 25 deletions wgpu/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,32 @@ Notably, `capture` example shows rendering without a surface/window. It reads ba
All framework-based examples render to the window.

## Feature matrix
| Feature | boids | cube | mipmap | msaa-line | shadow | skybox | texture-arrays | water |
| ---------------------- | ------ | ------ | ------ | --------- | ------ | ------ | -------------- | ------ |
| vertex attributes | :star: | :star: | :star: | :star: | :star: | | :star: | :star: |
| instancing | :star: | | | | | | | |
| lines and points | | | | :star: | | | | |
| sampled color textures | :star: | :star: | :star: | | | :star: | :star: | :star: |
| storage textures | :star: | | | | | | | |
| binding array | | | | | | | :star: | |
| comparison samplers | | | | | :star: | | | |
| subresource views | | | :star: | | :star: | | | |
| cubemaps | | | | | | :star: | | |
| multisampling | | | | :star: | | | | |
| off-screen rendering | | | | | :star: | | | :star: |
| stencil testing | | | | | | | | |
| depth testing | | | | | :star: | | | :star: |
| depth biasing | | | | | :star: | | | |
| read-only depth | | | | | | | | :star: |
| blending | | | | | | | | :star: |
| render bundles | | | | :star: | | | | :star: |
| compute passes | :star: | | | | | | | |
| optional extensions | | | | | | | :star: | |
| - binding indexing | | | | | | | :star: | |
| - push constants | | | | | | | :star: | |
| - depth clamping | | | | | :star: | | | |
| WGSL shaders | | | | | | | | |
| Feature | boids | cube | mipmap | msaa-line | shadow | skybox | texture-arrays | water |
| ------------------------- | ------ | ------ | ------ | --------- | ------ | ------ | -------------- | ------ |
| vertex attributes | :star: | :star: | :star: | :star: | :star: | | :star: | :star: |
| instancing | :star: | | | | | | | |
| lines and points | | | | :star: | | | | |
| sampled color textures | :star: | :star: | :star: | | | :star: | :star: | :star: |
| storage textures | :star: | | | | | | | |
| binding array | | | | | | | :star: | |
| comparison samplers | | | | | :star: | | | |
| subresource views | | | :star: | | :star: | | | |
| cubemaps | | | | | | :star: | | |
| multisampling | | | | :star: | | | | |
| off-screen rendering | | | | | :star: | | | :star: |
| stencil testing | | | | | | | | |
| depth testing | | | | | :star: | | | :star: |
| depth biasing | | | | | :star: | | | |
| read-only depth | | | | | | | | :star: |
| blending | | | | | | | | :star: |
| render bundles | | | | :star: | | | | :star: |
| compute passes | :star: | | | | | | | |
| optional extensions | | | | | | | :star: | |
| - binding indexing | | | | | | | :star: | |
| - push constants | | | | | | | :star: | |
| - depth clamping | | | | | :star: | | | |
| - BCn compressed textures | | | | | | :star: | | |
| WGSL shaders | | | | | | | | |

## Hacking

Expand Down
Binary file added wgpu/examples/skybox/images/bc1.dds
Binary file not shown.
146 changes: 94 additions & 52 deletions wgpu/examples/skybox/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use futures::task::{LocalSpawn, LocalSpawnExt};
use std::borrow::Cow::Borrowed;
use wgpu::util::DeviceExt;

const SKYBOX_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm;
const IMAGE_SIZE: u32 = 512;

type Uniform = cgmath::Matrix4<f32>;
type Uniforms = [Uniform; 2];
Expand Down Expand Up @@ -40,6 +40,10 @@ impl Skybox {
}

impl framework::Example for Skybox {
fn optional_features() -> wgpu::Features {
wgpu::Features::TEXTURE_COMPRESSION_BC
}

fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
Expand Down Expand Up @@ -79,13 +83,11 @@ impl framework::Example for Skybox {

let aspect = sc_desc.width as f32 / sc_desc.height as f32;
let uniforms = Self::generate_uniforms(aspect);
let uniform_buf = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Uniform Buffer"),
contents: bytemuck::cast_slice(&raw_uniforms(&uniforms)),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
}
);
let uniform_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Uniform Buffer"),
contents: bytemuck::cast_slice(&raw_uniforms(&uniforms)),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
});

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

let paths: [&'static [u8]; 6] = [
&include_bytes!("images/posx.png")[..],
&include_bytes!("images/negx.png")[..],
&include_bytes!("images/posy.png")[..],
&include_bytes!("images/negy.png")[..],
&include_bytes!("images/posz.png")[..],
&include_bytes!("images/negz.png")[..],
];

// we set these multiple times, but whatever
let (mut image_width, mut image_height) = (0, 0);
let faces = paths
.iter()
.map(|png| {
let png = std::io::Cursor::new(png);
let decoder = png::Decoder::new(png);
let (info, mut reader) = decoder.read_info().expect("can read info");
image_width = info.width;
image_height = info.height;
let mut buf = vec![0; info.buffer_size()];
reader.next_frame(&mut buf).expect("can read png frame");
buf
})
.collect::<Vec<_>>();
let device_features = device.features();

let (skybox_format, single_file) =
if device_features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) {
(wgpu::TextureFormat::Bc1RgbaUnormSrgb, true)
} else {
(wgpu::TextureFormat::Rgba8UnormSrgb, false)
};

let texture = device.create_texture(&wgpu::TextureDescriptor {
size: wgpu::Extent3d {
width: image_width,
height: image_height,
width: IMAGE_SIZE,
height: IMAGE_SIZE,
depth: 6,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: SKYBOX_FORMAT,
format: skybox_format,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
label: None,
});

for (i, image) in faces.iter().enumerate() {
if single_file {
log::debug!(
"Copying skybox image {} of size {},{} to gpu",
i,
image_width,
image_height,
"Copying BC1 skybox images of size {},{},6 to gpu",
IMAGE_SIZE,
IMAGE_SIZE,
);

let bc1_path: &[u8] = &include_bytes!("images/bc1.dds")[..];

let mut dds_cursor = std::io::Cursor::new(bc1_path);
let dds_file = ddsfile::Dds::read(&mut dds_cursor).unwrap();

let block_width = 4;
let block_size = 8;

queue.write_texture(
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
origin: wgpu::Origin3d {
x: 0,
y: 0,
z: i as u32,
},
origin: wgpu::Origin3d::ZERO,
},
&image,
&dds_file.data,
wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: 4 * image_width,
rows_per_image: 0,
bytes_per_row: block_size * ((IMAGE_SIZE + (block_width - 1)) / block_width),
rows_per_image: IMAGE_SIZE,
},
wgpu::Extent3d {
width: image_width,
height: image_height,
depth: 1,
width: IMAGE_SIZE,
height: IMAGE_SIZE,
depth: 6,
},
);
} else {
let paths: [&'static [u8]; 6] = [
&include_bytes!("images/posx.png")[..],
&include_bytes!("images/negx.png")[..],
&include_bytes!("images/posy.png")[..],
&include_bytes!("images/negy.png")[..],
&include_bytes!("images/posz.png")[..],
&include_bytes!("images/negz.png")[..],
];

let faces = paths
.iter()
.map(|png| {
let png = std::io::Cursor::new(png);
let decoder = png::Decoder::new(png);
let (info, mut reader) = decoder.read_info().expect("can read info");
let mut buf = vec![0; info.buffer_size()];
reader.next_frame(&mut buf).expect("can read png frame");
buf
})
.collect::<Vec<_>>();

for (i, image) in faces.iter().enumerate() {
log::debug!(
"Copying skybox image {} of size {},{} to gpu",
i,
IMAGE_SIZE,
IMAGE_SIZE,
);
queue.write_texture(
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
origin: wgpu::Origin3d {
x: 0,
y: 0,
z: i as u32,
},
},
&image,
wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: 4 * IMAGE_SIZE,
rows_per_image: 0,
},
wgpu::Extent3d {
width: IMAGE_SIZE,
height: IMAGE_SIZE,
depth: 1,
},
);
}
}

let texture_view = texture.create_view(&wgpu::TextureViewDescriptor {
label: None,
format: SKYBOX_FORMAT,
format: skybox_format,
dimension: wgpu::TextureViewDimension::Cube,
aspect: wgpu::TextureAspect::default(),
base_mip_level: 0,
Expand Down

0 comments on commit 6183e20

Please sign in to comment.