Decouple render_texture_format from surface texture format (#249) (#257)

- Closes #249
This commit is contained in:
AnonymousDapper 2022-01-15 23:31:18 -05:00 committed by GitHub
parent 3968c9748a
commit ebf7179a89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 12 deletions

View file

@ -15,6 +15,7 @@ pub struct PixelsBuilder<'req, 'dev, 'win, W: HasRawWindowHandle> {
surface_texture: SurfaceTexture<'win, W>, surface_texture: SurfaceTexture<'win, W>,
texture_format: wgpu::TextureFormat, texture_format: wgpu::TextureFormat,
render_texture_format: Option<wgpu::TextureFormat>, render_texture_format: Option<wgpu::TextureFormat>,
surface_texture_format: Option<wgpu::TextureFormat>,
clear_color: wgpu::Color, clear_color: wgpu::Color,
} }
@ -68,6 +69,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
surface_texture, surface_texture,
texture_format: wgpu::TextureFormat::Rgba8UnormSrgb, texture_format: wgpu::TextureFormat::Rgba8UnormSrgb,
render_texture_format: None, render_texture_format: None,
surface_texture_format: None,
clear_color: wgpu::Color::BLACK, clear_color: wgpu::Color::BLACK,
} }
} }
@ -157,6 +159,21 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
/// Set the render texture format. /// Set the render texture format.
/// ///
/// This falls back on [`Pixels::surface_texture_format`] if not set.
///
/// The [`ScalingRenderer`] uses this format for its own render target.
/// This is really only useful if you are running a custom shader pipeline and need different formats
/// for the intermediary textures (such as `Rgba16Float` for HDR rendering).
/// 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) -> Self {
self.render_texture_format = Some(texture_format);
self
}
/// Set the surface texture format.
///
/// The default value is chosen automatically by the surface (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). /// `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 /// Setting this format correctly depends on the hardware/platform the pixel buffer is rendered
@ -167,14 +184,8 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
/// texture, but a view is provided to the `render_function` closure by [`Pixels::render_with`]. /// 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 /// The render texture can only be used as the final render target at the end of all
/// post-processing shaders. /// post-processing shaders.
/// pub fn surface_texture_format(mut self, texture_format: wgpu::TextureFormat) -> Self {
/// The [`ScalingRenderer`] also uses this format for its own render target. This is because it self.surface_texture_format = Some(texture_format);
/// 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.
pub fn render_texture_format(mut self, texture_format: wgpu::TextureFormat) -> Self {
self.render_texture_format = Some(texture_format);
self self
} }
@ -256,11 +267,12 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
.map_err(Error::DeviceNotFound)?; .map_err(Error::DeviceNotFound)?;
let present_mode = self.present_mode; let present_mode = self.present_mode;
let render_texture_format = self.render_texture_format.unwrap_or_else(|| { let surface_texture_format = self.surface_texture_format.unwrap_or_else(|| {
surface surface
.get_preferred_format(&adapter) .get_preferred_format(&adapter)
.unwrap_or(wgpu::TextureFormat::Bgra8UnormSrgb) .unwrap_or(wgpu::TextureFormat::Bgra8UnormSrgb)
}); });
let render_texture_format = self.render_texture_format.unwrap_or(surface_texture_format);
// Create the backing texture // Create the backing texture
let surface_size = self.surface_texture.size; let surface_size = self.surface_texture.size;
@ -299,6 +311,7 @@ impl<'req, 'dev, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'dev, 'win, W>
surface_size, surface_size,
present_mode, present_mode,
render_texture_format, render_texture_format,
surface_texture_format,
pixels, pixels,
scaling_matrix_inverse, scaling_matrix_inverse,
}; };

View file

@ -97,6 +97,7 @@ pub struct Pixels {
surface_size: SurfaceSize, surface_size: SurfaceSize,
present_mode: wgpu::PresentMode, present_mode: wgpu::PresentMode,
render_texture_format: wgpu::TextureFormat, render_texture_format: wgpu::TextureFormat,
surface_texture_format: wgpu::TextureFormat,
// Pixel buffer // Pixel buffer
pixels: Vec<u8>, pixels: Vec<u8>,
@ -480,7 +481,7 @@ impl Pixels {
&self.context.device, &self.context.device,
&wgpu::SurfaceConfiguration { &wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT, usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: self.render_texture_format, format: self.surface_texture_format,
width: self.surface_size.width, width: self.surface_size.width,
height: self.surface_size.height, height: self.surface_size.height,
present_mode: self.present_mode, present_mode: self.present_mode,
@ -607,10 +608,18 @@ impl Pixels {
&self.context &self.context
} }
/// Get the render texture format. /// Get the surface texture format.
/// ///
/// This texture format may be chosen automatically by the surface. See /// This texture format may be chosen automatically by the surface. See
/// [`PixelsBuilder::render_texture_format`] for more information. /// [`PixelsBuilder::surface_texture_format`] for more information.
pub fn surface_texture_format(&self) -> wgpu::TextureFormat {
self.surface_texture_format
}
/// Get the render texture format.
///
///
/// See [`PixelsBuilder::render_texture_format`] for more information.
pub fn render_texture_format(&self) -> wgpu::TextureFormat { pub fn render_texture_format(&self) -> wgpu::TextureFormat {
self.render_texture_format self.render_texture_format
} }