Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the swapchain-preferred texture format by default #182

Merged
merged 3 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/custom-shader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn main() -> Result<(), Error> {
};
let mut world = World::new();
let mut time = 0.0;
let mut noise_renderer = NoiseRenderer::new(pixels.device(), WIDTH, HEIGHT);
let mut noise_renderer = NoiseRenderer::new(&pixels, WIDTH, HEIGHT);

event_loop.run(move |event, _, control_flow| {
// Draw the current frame
Expand Down Expand Up @@ -82,7 +82,7 @@ fn main() -> Result<(), Error> {
// Resize the window
if let Some(size) = input.window_resized() {
pixels.resize_surface(size.width, size.height);
noise_renderer.resize(pixels.device(), size.width, size.height);
noise_renderer.resize(&pixels, size.width, size.height);
}

// Update internal state and request a redraw
Expand Down
18 changes: 10 additions & 8 deletions examples/custom-shader/src/renderers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ pub(crate) struct NoiseRenderer {
}

impl NoiseRenderer {
pub(crate) fn new(device: &wgpu::Device, width: u32, height: u32) -> Self {
pub(crate) fn new(pixels: &pixels::Pixels, width: u32, height: u32) -> Self {
let device = pixels.device();
let shader = wgpu::include_wgsl!("../shaders/noise.wgsl");
let module = device.create_shader_module(&shader);

// Create a texture view that will be used as input
// This will be used as the render target for the default scaling renderer
let texture_view = create_texture_view(device, width, height);
let texture_view = create_texture_view(pixels, width, height);

// Create a texture sampler with nearest neighbor
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
Expand Down Expand Up @@ -137,7 +138,7 @@ impl NoiseRenderer {
module: &module,
entry_point: "fs_main",
targets: &[wgpu::ColorTargetState {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
format: pixels.render_texture_format(),
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent::REPLACE,
alpha: wgpu::BlendComponent::REPLACE,
Expand All @@ -162,10 +163,10 @@ impl NoiseRenderer {
&self.texture_view
}

pub(crate) fn resize(&mut self, device: &wgpu::Device, width: u32, height: u32) {
self.texture_view = create_texture_view(device, width, height);
pub(crate) fn resize(&mut self, pixels: &pixels::Pixels, width: u32, height: u32) {
self.texture_view = create_texture_view(pixels, width, height);
self.bind_group = create_bind_group(
device,
pixels.device(),
&self.bind_group_layout,
&self.texture_view,
&self.sampler,
Expand Down Expand Up @@ -203,7 +204,8 @@ impl NoiseRenderer {
}
}

fn create_texture_view(device: &wgpu::Device, width: u32, height: u32) -> wgpu::TextureView {
fn create_texture_view(pixels: &pixels::Pixels, width: u32, height: u32) -> wgpu::TextureView {
let device = pixels.device();
let texture_descriptor = wgpu::TextureDescriptor {
label: None,
size: pixels::wgpu::Extent3d {
Expand All @@ -214,7 +216,7 @@ fn create_texture_view(device: &wgpu::Device, width: u32, height: u32) -> wgpu::
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
format: pixels.render_texture_format(),
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
};

Expand Down
4 changes: 2 additions & 2 deletions examples/egui-winit/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub(crate) struct Gui {

impl Gui {
/// Create egui.
pub(crate) fn new(width: u32, height: u32, scale_factor: f64, context: &PixelsContext) -> Self {
pub(crate) fn new(width: u32, height: u32, scale_factor: f64, pixels: &pixels::Pixels) -> Self {
let platform = Platform::new(PlatformDescriptor {
physical_width: width,
physical_height: height,
Expand All @@ -32,7 +32,7 @@ impl Gui {
physical_height: height,
scale_factor: scale_factor as f32,
};
let rpass = RenderPass::new(&context.device, wgpu::TextureFormat::Bgra8UnormSrgb, 1);
let rpass = RenderPass::new(pixels.device(), pixels.render_texture_format(), 1);

Self {
start_time: Instant::now(),
Expand Down
7 changes: 1 addition & 6 deletions examples/egui-winit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,7 @@ fn main() -> Result<(), Error> {
let scale_factor = window.scale_factor();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
let pixels = Pixels::new(WIDTH, HEIGHT, surface_texture)?;
let gui = Gui::new(
window_size.width,
window_size.height,
scale_factor,
pixels.context(),
);
let gui = Gui::new(window_size.width, window_size.height, scale_factor, &pixels);

(pixels, gui)
};
Expand Down
3 changes: 1 addition & 2 deletions examples/imgui-winit/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ impl Gui {
// Create Dear ImGui WGPU renderer
let device = pixels.device();
let queue = pixels.queue();
let texture_format = wgpu::TextureFormat::Bgra8UnormSrgb;
let config = imgui_wgpu::RendererConfig {
texture_format,
texture_format: pixels.render_texture_format(),
..Default::default()
};
let renderer = imgui_wgpu::Renderer::new(&mut imgui, device, queue, config);
Expand Down
48 changes: 34 additions & 14 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct PixelsBuilder<'req, 'dev, 'win, W: HasRawWindowHandle> {
present_mode: wgpu::PresentMode,
surface_texture: SurfaceTexture<'win, W>,
texture_format: wgpu::TextureFormat,
render_texture_format: wgpu::TextureFormat,
render_texture_format: Option<wgpu::TextureFormat>,
}

impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W> {
Expand Down Expand Up @@ -58,7 +58,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
present_mode: wgpu::PresentMode::Fifo,
surface_texture,
texture_format: wgpu::TextureFormat::Rgba8UnormSrgb,
render_texture_format: wgpu::TextureFormat::Bgra8UnormSrgb,
render_texture_format: None,
}
}

Expand All @@ -82,8 +82,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>

/// Set which backends wgpu will attempt to use.
///
/// The default value of this is [`wgpu::BackendBit::PRIMARY`], which enables
/// the well supported backends for wgpu.
/// 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> {
self.backend = backend;
self
Expand Down Expand Up @@ -144,9 +143,12 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>

/// Set the texture format.
///
/// The default value is [`wgpu::TextureFormat::Rgba8UnormSrgb`], which is 4 unsigned bytes in
/// `RGBA` order using the SRGB color space. This is typically what you want when you are
/// working with color values from popular image editing tools or web apps.
/// The default value is `Rgba8UnormSrgb`, which is 4 unsigned bytes in `RGBA` order using the
/// sRGB color space. This is typically what you want when you are working with color values
/// from popular image editing tools or web apps.
///
/// This is the pixel format of the texture that most applications will interact with directly.
/// The format influences the structure of byte data that is returned by [`Pixels::get_frame`].
pub fn texture_format(
mut self,
texture_format: wgpu::TextureFormat,
Expand All @@ -157,14 +159,27 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>

/// Set the render texture format.
///
/// The default value is [`wgpu::TextureFormat::Bgra8UnormSrgb`], which is 4 unsigned bytes in
/// `BGRA` order using the SRGB color space. This format depends on the hardware/platform the
/// pixel buffer is rendered to/for.
/// The default value is chosen automatically by the swapchain (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
/// 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
/// 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.
pub fn render_texture_format(
mut self,
texture_format: wgpu::TextureFormat,
) -> PixelsBuilder<'req, 'dev, 'win, W> {
self.render_texture_format = texture_format;
self.render_texture_format = Some(texture_format);
self
}

Expand Down Expand Up @@ -196,13 +211,18 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
.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)
.unwrap_or(wgpu::TextureFormat::Bgra8UnormSrgb)
});

// Create swap chain
let surface_size = self.surface_texture.size;
let swap_chain = create_swap_chain(
&mut device,
&surface,
self.render_texture_format,
render_texture_format,
&surface_size,
present_mode,
);
Expand All @@ -217,7 +237,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
self.texture_format,
// Render texture values
&surface_size,
self.render_texture_format,
render_texture_format,
);

// Create the pixel buffer
Expand All @@ -241,9 +261,9 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
context,
surface_size,
present_mode,
render_texture_format,
pixels,
scaling_matrix_inverse,
render_texture_format: self.render_texture_format,
})
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,16 @@ impl Pixels {
&self.context.texture
}

/// Provides access to the internal [`PixelsContext`]
/// Provides access to the internal [`PixelsContext`].
pub fn context(&self) -> &PixelsContext {
&self.context
}

/// Get the render texture format.
///
/// This texture format may be chosen automatically by the swapchain. See
/// [`PixelsBuilder::render_texture_format`] for more information.
pub fn render_texture_format(&self) -> wgpu::TextureFormat {
self.render_texture_format
}
}