Update to wgpu 0.10 (#187)
- It would be nice to return an error from the render function - imgui-winit is still a WIP (open PR: https://github.com/Yatekii/imgui-wgpu-rs/pull/66) - Update README Co-authored-by: Mohammed Alyousef <mohammed.alyousef@neurosrg.com>
This commit is contained in:
parent
480764ed5a
commit
e08c91bfd2
|
@ -24,7 +24,7 @@ pollster = "0.2"
|
|||
raw-window-handle = "0.3"
|
||||
thiserror = "1.0"
|
||||
ultraviolet = "0.8"
|
||||
wgpu = "0.9"
|
||||
wgpu = "0.10"
|
||||
|
||||
[dev-dependencies]
|
||||
pixels-mocks = { path = "internals/pixels-mocks" }
|
||||
|
|
13
README.md
13
README.md
|
@ -19,7 +19,8 @@ The Minimum Supported Rust Version for `pixels` will always be made available in
|
|||
|
||||
## Features
|
||||
|
||||
- Built on modern graphics APIs powered by [`wgpu`](https://crates.io/crates/wgpu): DirectX 12, Vulkan, Metal. OpenGL support is a work in progress.
|
||||
- Built on modern graphics APIs powered by [`wgpu`](https://crates.io/crates/wgpu): Vulkan, Metal, DirectX 12, OpenGL ES3.
|
||||
- DirectX 11, WebGL2, and WebGPU support are a work in progress.
|
||||
- Use your own custom shaders for special effects.
|
||||
- Hardware accelerated scaling on perfect pixel boundaries.
|
||||
- Supports non-square pixel aspect ratios. (WIP)
|
||||
|
@ -38,6 +39,16 @@ The Minimum Supported Rust Version for `pixels` will always be made available in
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Cargo resolver
|
||||
|
||||
Starting with [`wgpu` 0.10](https://github.com/gfx-rs/wgpu/blob/06316c1bac8b78ac04d762cfb1a886bd1d453b30/CHANGELOG.md#v010-2021-08-18), the [resolver version](https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions) needs to be set in your `Cargo.toml` to avoid build errors:
|
||||
|
||||
```toml
|
||||
resolver = "2"
|
||||
```
|
||||
|
||||
### Driver issues
|
||||
|
||||
The most common issue is having an outdated graphics driver installed on the host machine. `pixels`
|
||||
requests a low power (aka integrated) GPU by default. If the examples are not working for any reason, you may try setting the `PIXELS_HIGH_PERF` environment variable (the value does not matter, e.g. `PIXELS_HIGH_PERF=1` is fine) to see if that addresses the issue on your host machine.
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@ impl NoiseRenderer {
|
|||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("NoiseRenderer vertex buffer"),
|
||||
contents: vertex_data_slice,
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let vertex_buffer_layout = wgpu::VertexBufferLayout {
|
||||
array_stride: (vertex_data_slice.len() / vertex_data.len()) as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
step_mode: wgpu::VertexStepMode::Vertex,
|
||||
attributes: &[
|
||||
wgpu::VertexAttribute {
|
||||
format: wgpu::VertexFormat::Float32x2,
|
||||
|
@ -71,7 +71,7 @@ impl NoiseRenderer {
|
|||
let time_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("NoiseRenderer u_Time"),
|
||||
contents: &0.0_f32.to_ne_bytes(),
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
|
||||
// Create bind group
|
||||
|
@ -80,7 +80,7 @@ impl NoiseRenderer {
|
|||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
multisampled: false,
|
||||
|
@ -90,7 +90,7 @@ impl NoiseRenderer {
|
|||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler {
|
||||
filtering: true,
|
||||
comparison: false,
|
||||
|
@ -99,7 +99,7 @@ impl NoiseRenderer {
|
|||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
|
@ -143,7 +143,7 @@ impl NoiseRenderer {
|
|||
color: wgpu::BlendComponent::REPLACE,
|
||||
alpha: wgpu::BlendComponent::REPLACE,
|
||||
}),
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
@ -217,7 +217,7 @@ fn create_texture_view(pixels: &pixels::Pixels, width: u32, height: u32) -> wgpu
|
|||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: pixels.render_texture_format(),
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||
};
|
||||
|
||||
device
|
||||
|
|
|
@ -10,9 +10,9 @@ optimize = ["log/release_max_level_warn"]
|
|||
default = ["optimize"]
|
||||
|
||||
[dependencies]
|
||||
egui = "0.13"
|
||||
egui_wgpu_backend = "0.10"
|
||||
egui_winit_platform = { version = "0.9", features = ["webbrowser"] }
|
||||
egui = "0.14"
|
||||
egui_wgpu_backend = "0.12"
|
||||
egui_winit_platform = { version = "0.10", features = ["webbrowser"] }
|
||||
env_logger = "0.9"
|
||||
log = "0.4"
|
||||
pixels = { path = "../.." }
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use egui::{ClippedMesh, FontDefinitions};
|
||||
use egui_wgpu_backend::{RenderPass, ScreenDescriptor};
|
||||
use egui_wgpu_backend::{BackendError, RenderPass, ScreenDescriptor};
|
||||
use egui_winit_platform::{Platform, PlatformDescriptor};
|
||||
use pixels::{wgpu, PixelsContext};
|
||||
use std::time::Instant;
|
||||
use winit::window::Window;
|
||||
|
||||
/// Manages all state required for rendering egui over `Pixels`.
|
||||
pub(crate) struct Gui {
|
||||
|
@ -63,7 +64,7 @@ impl Gui {
|
|||
}
|
||||
|
||||
/// Prepare egui.
|
||||
pub(crate) fn prepare(&mut self) {
|
||||
pub(crate) fn prepare(&mut self, window: &Window) {
|
||||
self.platform
|
||||
.update_time(self.start_time.elapsed().as_secs_f64());
|
||||
|
||||
|
@ -74,7 +75,7 @@ impl Gui {
|
|||
self.ui(&self.platform.context());
|
||||
|
||||
// End the egui frame and create all paint jobs to prepare for rendering.
|
||||
let (_output, paint_commands) = self.platform.end_frame();
|
||||
let (_output, paint_commands) = self.platform.end_frame(Some(window));
|
||||
self.paint_jobs = self.platform.context().tessellate(paint_commands);
|
||||
}
|
||||
|
||||
|
@ -112,7 +113,7 @@ impl Gui {
|
|||
encoder: &mut wgpu::CommandEncoder,
|
||||
render_target: &wgpu::TextureView,
|
||||
context: &PixelsContext,
|
||||
) {
|
||||
) -> Result<(), BackendError> {
|
||||
// Upload all resources to the GPU.
|
||||
self.rpass.update_texture(
|
||||
&context.device,
|
||||
|
@ -135,6 +136,6 @@ impl Gui {
|
|||
&self.paint_jobs,
|
||||
&self.screen_descriptor,
|
||||
None,
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ fn main() -> Result<(), Error> {
|
|||
world.draw(pixels.get_frame());
|
||||
|
||||
// Prepare egui
|
||||
gui.prepare();
|
||||
gui.prepare(&window);
|
||||
|
||||
// Render everything together
|
||||
let render_result = pixels.render_with(|encoder, render_target, context| {
|
||||
|
@ -67,7 +67,8 @@ fn main() -> Result<(), Error> {
|
|||
context.scaling_renderer.render(encoder, render_target);
|
||||
|
||||
// Render egui
|
||||
gui.render(encoder, render_target, context);
|
||||
gui.render(encoder, render_target, context)
|
||||
.expect("egui render error");
|
||||
});
|
||||
|
||||
// Basic error handling
|
||||
|
|
|
@ -12,7 +12,7 @@ default = ["optimize"]
|
|||
[dependencies]
|
||||
env_logger = "0.9"
|
||||
imgui = "0.7"
|
||||
imgui-wgpu = "0.16"
|
||||
imgui-wgpu = { git = "https://github.com/kylc/imgui-wgpu-rs.git", rev = "fbbc0cfc7de25a4821980cb2170195c7b3b0fcf4" }
|
||||
imgui-winit-support = { version = "0.7.1", default-features = false, features = ["winit-25"] }
|
||||
log = "0.4"
|
||||
pixels = { path = "../.." }
|
||||
|
|
|
@ -5,12 +5,10 @@
|
|||
use fltk::{app, enums::Event, prelude::*, window::Window};
|
||||
use log::error;
|
||||
use pixels::{Error, Pixels, SurfaceTexture};
|
||||
use std::{thread, time::Duration};
|
||||
|
||||
const WIDTH: u32 = 600;
|
||||
const HEIGHT: u32 = 400;
|
||||
const CIRCLE_RADIUS: i16 = 64;
|
||||
const SLEEP: u64 = 16;
|
||||
|
||||
/// Representation of the application state. In this example, a circle will bounce around the screen.
|
||||
struct World {
|
||||
|
@ -59,10 +57,9 @@ fn main() -> Result<(), Error> {
|
|||
{
|
||||
app.quit();
|
||||
}
|
||||
win.redraw();
|
||||
|
||||
// Calls to redraw in the event loop require an explicit sleep
|
||||
thread::sleep(Duration::from_millis(SLEEP));
|
||||
app::flush();
|
||||
app::awake();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::env;
|
|||
pub struct PixelsBuilder<'req, 'dev, 'win, W: HasRawWindowHandle> {
|
||||
request_adapter_options: Option<wgpu::RequestAdapterOptions<'req>>,
|
||||
device_descriptor: wgpu::DeviceDescriptor<'dev>,
|
||||
backend: wgpu::BackendBit,
|
||||
backend: wgpu::Backends,
|
||||
width: u32,
|
||||
height: u32,
|
||||
_pixel_aspect_ratio: f64,
|
||||
|
@ -51,7 +51,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
PixelsBuilder {
|
||||
request_adapter_options: None,
|
||||
device_descriptor: wgpu::DeviceDescriptor::default(),
|
||||
backend: wgpu::BackendBit::PRIMARY,
|
||||
backend: wgpu::Backends::PRIMARY,
|
||||
width,
|
||||
height,
|
||||
_pixel_aspect_ratio: 1.0,
|
||||
|
@ -83,7 +83,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
/// Set which backends wgpu will attempt to use.
|
||||
///
|
||||
/// The default value is `PRIMARY`, which enables the well supported backends for wgpu.
|
||||
pub fn wgpu_backend(mut self, backend: wgpu::BackendBit) -> PixelsBuilder<'req, 'dev, 'win, W> {
|
||||
pub fn wgpu_backend(mut self, backend: wgpu::Backends) -> PixelsBuilder<'req, 'dev, 'win, W> {
|
||||
self.backend = backend;
|
||||
self
|
||||
}
|
||||
|
@ -159,19 +159,19 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
|
||||
/// Set the render texture format.
|
||||
///
|
||||
/// The default value is chosen automatically by the swapchain (if it can) with a fallback to
|
||||
/// The default value is chosen automatically by the surface (if it can) with a fallback to
|
||||
/// `Bgra8UnormSrgb` (which is 4 unsigned bytes in `BGRA` order using the sRGB color space).
|
||||
/// Setting this format correctly depends on the hardware/platform the pixel buffer is rendered
|
||||
/// to. The chosen format can be retrieved later with [`Pixels::render_texture_format`].
|
||||
///
|
||||
/// This method controls the format of the swapchain frame buffer, which has strict texture
|
||||
/// This method controls the format of the surface frame buffer, which has strict texture
|
||||
/// format requirements. Applications will never interact directly with the pixel data of this
|
||||
/// texture, but a view is provided to the `render_function` closure by [`Pixels::render_with`].
|
||||
/// The render texture can only be used as the final render target at the end of all
|
||||
/// post-processing shaders.
|
||||
///
|
||||
/// The [`ScalingRenderer`] also uses this format for its own render target. This is because it
|
||||
/// assumes the render target is always the swapchain current frame. This needs to be kept in
|
||||
/// assumes the render target is always the surface current frame. This needs to be kept in
|
||||
/// mind when writing custom shaders for post-processing effects. There is a full example of a
|
||||
/// [custom-shader](https://github.com/parasyte/pixels/tree/master/examples/custom-shader)
|
||||
/// available that demonstrates how to deal with this.
|
||||
|
@ -206,28 +206,19 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
));
|
||||
let adapter = pollster::block_on(adapter).ok_or(Error::AdapterNotFound)?;
|
||||
|
||||
let (mut device, queue) =
|
||||
let (device, queue) =
|
||||
pollster::block_on(adapter.request_device(&self.device_descriptor, None))
|
||||
.map_err(Error::DeviceNotFound)?;
|
||||
|
||||
let present_mode = self.present_mode;
|
||||
let render_texture_format = self.render_texture_format.unwrap_or_else(|| {
|
||||
adapter
|
||||
.get_swap_chain_preferred_format(&surface)
|
||||
surface
|
||||
.get_preferred_format(&adapter)
|
||||
.unwrap_or(wgpu::TextureFormat::Bgra8UnormSrgb)
|
||||
});
|
||||
|
||||
// Create swap chain
|
||||
let surface_size = self.surface_texture.size;
|
||||
let swap_chain = create_swap_chain(
|
||||
&mut device,
|
||||
&surface,
|
||||
render_texture_format,
|
||||
&surface_size,
|
||||
present_mode,
|
||||
);
|
||||
|
||||
// Create the backing texture
|
||||
let surface_size = self.surface_texture.size;
|
||||
let (scaling_matrix_inverse, texture_extent, texture, scaling_renderer, pixels_buffer_size) =
|
||||
create_backing_texture(
|
||||
&device,
|
||||
|
@ -249,7 +240,6 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
device,
|
||||
queue,
|
||||
surface,
|
||||
swap_chain,
|
||||
texture,
|
||||
texture_extent,
|
||||
texture_format: self.texture_format,
|
||||
|
@ -257,34 +247,18 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
|
|||
scaling_renderer,
|
||||
};
|
||||
|
||||
Ok(Pixels {
|
||||
let pixels = Pixels {
|
||||
context,
|
||||
surface_size,
|
||||
present_mode,
|
||||
render_texture_format,
|
||||
pixels,
|
||||
scaling_matrix_inverse,
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
pixels.reconfigure_surface();
|
||||
|
||||
pub(crate) fn create_swap_chain(
|
||||
device: &mut wgpu::Device,
|
||||
surface: &wgpu::Surface,
|
||||
format: wgpu::TextureFormat,
|
||||
surface_size: &SurfaceSize,
|
||||
present_mode: wgpu::PresentMode,
|
||||
) -> wgpu::SwapChain {
|
||||
device.create_swap_chain(
|
||||
surface,
|
||||
&wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
format,
|
||||
width: surface_size.width,
|
||||
height: surface_size.height,
|
||||
present_mode,
|
||||
},
|
||||
)
|
||||
Ok(pixels)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_backing_texture(
|
||||
|
@ -321,7 +295,7 @@ pub(crate) fn create_backing_texture(
|
|||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: backing_texture_format,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||
});
|
||||
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
|
@ -366,7 +340,8 @@ const fn get_texture_format_size(texture_format: wgpu::TextureFormat) -> f32 {
|
|||
| Rg8Unorm
|
||||
| Rg8Snorm
|
||||
| Rg8Uint
|
||||
| Rg8Sint => 2.0, // 16.0 / 8.0
|
||||
| Rg8Sint
|
||||
| Rgb9e5Ufloat => 2.0, // 16.0 / 8.0
|
||||
|
||||
// 32-bit formats, 8 bits per component
|
||||
R32Uint
|
||||
|
@ -426,10 +401,8 @@ const fn get_texture_format_size(texture_format: wgpu::TextureFormat) -> f32 {
|
|||
| Bc6hRgbSfloat
|
||||
| Bc7RgbaUnorm
|
||||
| Bc7RgbaUnormSrgb
|
||||
| Etc2RgbA8Unorm
|
||||
| Etc2RgbA8UnormSrgb
|
||||
| EtcRgUnorm
|
||||
| EtcRgSnorm
|
||||
| EacRgUnorm
|
||||
| EacRgSnorm
|
||||
| Astc4x4RgbaUnorm
|
||||
| Astc4x4RgbaUnormSrgb => 1.0, // 4.0 * 4.0 / 16.0
|
||||
|
||||
|
|
63
src/lib.rs
63
src/lib.rs
|
@ -31,11 +31,10 @@
|
|||
pub use crate::builder::PixelsBuilder;
|
||||
pub use crate::renderers::ScalingRenderer;
|
||||
pub use raw_window_handle;
|
||||
use std::num::NonZeroU32;
|
||||
pub use wgpu;
|
||||
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use std::num::NonZeroU32;
|
||||
use thiserror::Error;
|
||||
pub use wgpu;
|
||||
|
||||
mod builder;
|
||||
mod renderers;
|
||||
|
@ -67,7 +66,6 @@ pub struct PixelsContext {
|
|||
pub queue: wgpu::Queue,
|
||||
|
||||
surface: wgpu::Surface,
|
||||
swap_chain: wgpu::SwapChain,
|
||||
|
||||
/// This is the texture that your raw data is copied to by [`Pixels::render`] or
|
||||
/// [`Pixels::render_with`].
|
||||
|
@ -114,9 +112,9 @@ pub enum Error {
|
|||
/// Equivalent to [`wgpu::RequestDeviceError`]
|
||||
#[error("No wgpu::Device found.")]
|
||||
DeviceNotFound(wgpu::RequestDeviceError),
|
||||
/// Equivalent to [`wgpu::SwapChainError`]
|
||||
#[error("The GPU failed to acquire a swapchain frame.")]
|
||||
Swapchain(wgpu::SwapChainError),
|
||||
/// Equivalent to [`wgpu::SurfaceError`]
|
||||
#[error("The GPU failed to acquire a surface frame.")]
|
||||
Surface(wgpu::SurfaceError),
|
||||
}
|
||||
|
||||
impl<'win, W: HasRawWindowHandle> SurfaceTexture<'win, W> {
|
||||
|
@ -265,8 +263,8 @@ impl Pixels {
|
|||
.transform
|
||||
.inversed();
|
||||
|
||||
// Recreate the swap chain
|
||||
self.recreate_swap_chain();
|
||||
// Reconfigure the surface
|
||||
self.reconfigure_surface();
|
||||
|
||||
// Update state for all render passes
|
||||
self.context
|
||||
|
@ -278,7 +276,7 @@ impl Pixels {
|
|||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error when [`wgpu::SwapChain::get_current_frame`] fails.
|
||||
/// Returns an error when [`wgpu::Surface::get_current_frame`] fails.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -310,13 +308,13 @@ impl Pixels {
|
|||
/// Draw this pixel buffer to the configured [`SurfaceTexture`] using a custom user-provided
|
||||
/// render function.
|
||||
///
|
||||
/// Provides access to a [`wgpu::CommandEncoder`], a [`wgpu::TextureView`] from the swapchain
|
||||
/// Provides access to a [`wgpu::CommandEncoder`], a [`wgpu::TextureView`] from the surface
|
||||
/// which you can use to render to the screen, and a [`PixelsContext`] with all of the internal
|
||||
/// `wgpu` context.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error when [`wgpu::SwapChain::get_current_frame`] fails.
|
||||
/// Returns an error when [`wgpu::Surface::get_current_frame`] fails.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -348,18 +346,18 @@ impl Pixels {
|
|||
{
|
||||
let frame = self
|
||||
.context
|
||||
.swap_chain
|
||||
.surface
|
||||
.get_current_frame()
|
||||
.or_else(|err| match err {
|
||||
wgpu::SwapChainError::Outdated => {
|
||||
// Recreate the swap chain to mitigate race condition on drawing surface resize.
|
||||
wgpu::SurfaceError::Outdated => {
|
||||
// Reconfigure the surface to mitigate race condition on window resize.
|
||||
// See https://github.com/parasyte/pixels/issues/121
|
||||
self.recreate_swap_chain();
|
||||
self.context.swap_chain.get_current_frame()
|
||||
self.reconfigure_surface();
|
||||
self.context.surface.get_current_frame()
|
||||
}
|
||||
err => Err(err),
|
||||
})
|
||||
.map_err(Error::Swapchain)?;
|
||||
.map_err(Error::Surface)?;
|
||||
let mut encoder =
|
||||
self.context
|
||||
.device
|
||||
|
@ -375,6 +373,7 @@ impl Pixels {
|
|||
texture: &self.context.texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
},
|
||||
&self.pixels,
|
||||
wgpu::ImageDataLayout {
|
||||
|
@ -385,23 +384,31 @@ impl Pixels {
|
|||
self.context.texture_extent,
|
||||
);
|
||||
|
||||
let view = frame
|
||||
.output
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
// Call the users render function.
|
||||
(render_function)(&mut encoder, &frame.output.view, &self.context);
|
||||
(render_function)(&mut encoder, &view, &self.context);
|
||||
|
||||
self.context.queue.submit(Some(encoder.finish()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Recreate the swap chain.
|
||||
/// Reconfigure the surface.
|
||||
///
|
||||
/// Call this when the surface or presentation mode needs to be changed.
|
||||
pub(crate) fn recreate_swap_chain(&mut self) {
|
||||
self.context.swap_chain = builder::create_swap_chain(
|
||||
&mut self.context.device,
|
||||
&self.context.surface,
|
||||
self.render_texture_format,
|
||||
&self.surface_size,
|
||||
self.present_mode,
|
||||
pub(crate) fn reconfigure_surface(&self) {
|
||||
self.context.surface.configure(
|
||||
&self.context.device,
|
||||
&wgpu::SurfaceConfiguration {
|
||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||
format: self.render_texture_format,
|
||||
width: self.surface_size.width,
|
||||
height: self.surface_size.height,
|
||||
present_mode: self.present_mode,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -532,7 +539,7 @@ impl Pixels {
|
|||
|
||||
/// Get the render texture format.
|
||||
///
|
||||
/// This texture format may be chosen automatically by the swapchain. See
|
||||
/// This texture format may be chosen automatically by the surface. See
|
||||
/// [`PixelsBuilder::render_texture_format`] for more information.
|
||||
pub fn render_texture_format(&self) -> wgpu::TextureFormat {
|
||||
self.render_texture_format
|
||||
|
|
|
@ -54,11 +54,11 @@ impl ScalingRenderer {
|
|||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("pixels_scaling_renderer_vertex_buffer"),
|
||||
contents: vertex_data_slice,
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let vertex_buffer_layout = wgpu::VertexBufferLayout {
|
||||
array_stride: (vertex_data_slice.len() / vertex_data.len()) as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
step_mode: wgpu::VertexStepMode::Vertex,
|
||||
attributes: &[
|
||||
wgpu::VertexAttribute {
|
||||
format: wgpu::VertexFormat::Float32x2,
|
||||
|
@ -82,7 +82,7 @@ impl ScalingRenderer {
|
|||
let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("pixels_scaling_renderer_matrix_uniform_buffer"),
|
||||
contents: transform_bytes,
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
|
||||
// Create bind group
|
||||
|
@ -91,7 +91,7 @@ impl ScalingRenderer {
|
|||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
multisampled: false,
|
||||
|
@ -101,7 +101,7 @@ impl ScalingRenderer {
|
|||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler {
|
||||
filtering: true,
|
||||
comparison: false,
|
||||
|
@ -110,7 +110,7 @@ impl ScalingRenderer {
|
|||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
visibility: wgpu::ShaderStages::VERTEX,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
|
@ -169,7 +169,7 @@ impl ScalingRenderer {
|
|||
color: wgpu::BlendComponent::REPLACE,
|
||||
alpha: wgpu::BlendComponent::REPLACE,
|
||||
}),
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
}],
|
||||
}),
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue