diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index bb57f7f71b..7636d1ad71 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -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" @@ -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" diff --git a/wgpu/examples/README.md b/wgpu/examples/README.md index 3d15569715..eefec40904 100644 --- a/wgpu/examples/README.md +++ b/wgpu/examples/README.md @@ -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 diff --git a/wgpu/examples/skybox/images/bc1.dds b/wgpu/examples/skybox/images/bc1.dds new file mode 100644 index 0000000000..8550815e7e Binary files /dev/null and b/wgpu/examples/skybox/images/bc1.dds differ diff --git a/wgpu/examples/skybox/main.rs b/wgpu/examples/skybox/main.rs index db336ebcae..84bc147411 100644 --- a/wgpu/examples/skybox/main.rs +++ b/wgpu/examples/skybox/main.rs @@ -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; type Uniforms = [Uniform; 2]; @@ -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, @@ -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]), @@ -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")[..], - ]; + let device_features = device.features(); - // 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::>(); + 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::>(); + + 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,