Expose new API method render_texture_format(). (#123)

This method is needed to let the user of the API configure the texture
format of the target texture/render texture that the surface texture is
rendered on. This texture format is hardware/platform dependent.

For example, this method makes it possible to use the pixels crate on
Android because Android seems not to use the previously hard-coded
texture format wgpu::TextureFormat::Bgra8UnormSrgb.
This commit is contained in:
schnippl0r 2020-12-11 03:40:06 +01:00 committed by GitHub
parent e5f92519f1
commit fb243b8973
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 4 deletions

View file

@ -92,6 +92,7 @@ pub struct Pixels<W: HasRawWindowHandle> {
context: PixelsContext, context: PixelsContext,
surface_size: SurfaceSize, surface_size: SurfaceSize,
present_mode: wgpu::PresentMode, present_mode: wgpu::PresentMode,
render_texture_format: wgpu::TextureFormat,
_phantom: std::marker::PhantomData<W>, _phantom: std::marker::PhantomData<W>,
// Pixel buffer // Pixel buffer
@ -113,6 +114,7 @@ pub struct PixelsBuilder<'req, 'win, W: HasRawWindowHandle> {
present_mode: wgpu::PresentMode, present_mode: wgpu::PresentMode,
surface_texture: SurfaceTexture<'win, W>, surface_texture: SurfaceTexture<'win, W>,
texture_format: wgpu::TextureFormat, texture_format: wgpu::TextureFormat,
render_texture_format: wgpu::TextureFormat,
} }
/// All the ways in which creating a pixel buffer can fail. /// All the ways in which creating a pixel buffer can fail.
@ -222,7 +224,7 @@ impl<'win, W: HasRawWindowHandle> Pixels<W> {
&self.context.surface, &self.context.surface,
&wgpu::SwapChainDescriptor { &wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb, format: self.render_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,
@ -511,6 +513,7 @@ impl<'req, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'win, W> {
present_mode: wgpu::PresentMode::Fifo, present_mode: wgpu::PresentMode::Fifo,
surface_texture, surface_texture,
texture_format: wgpu::TextureFormat::Rgba8UnormSrgb, texture_format: wgpu::TextureFormat::Rgba8UnormSrgb,
render_texture_format: wgpu::TextureFormat::Bgra8UnormSrgb,
} }
} }
@ -601,6 +604,19 @@ impl<'req, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'win, W> {
self self
} }
/// 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.
pub fn render_texture_format(
mut self,
texture_format: wgpu::TextureFormat,
) -> PixelsBuilder<'req, 'win, W> {
self.render_texture_format = texture_format;
self
}
/// Create a pixel buffer from the options builder. /// Create a pixel buffer from the options builder.
/// ///
/// # Errors /// # Errors
@ -663,7 +679,7 @@ impl<'req, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'win, W> {
&surface, &surface,
&wgpu::SwapChainDescriptor { &wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb, format: self.render_texture_format,
width: surface_size.width, width: surface_size.width,
height: surface_size.height, height: surface_size.height,
present_mode, present_mode,
@ -677,7 +693,12 @@ impl<'req, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'win, W> {
.transform .transform
.inversed(); .inversed();
let scaling_renderer = ScalingRenderer::new(&device, &texture_view, &texture_extent); let scaling_renderer = ScalingRenderer::new(
&device,
&texture_view,
&texture_extent,
self.render_texture_format,
);
let context = PixelsContext { let context = PixelsContext {
device, device,
@ -697,6 +718,7 @@ impl<'req, 'win, W: HasRawWindowHandle> PixelsBuilder<'req, 'win, W> {
_phantom: std::marker::PhantomData, _phantom: std::marker::PhantomData,
pixels, pixels,
scaling_matrix_inverse, scaling_matrix_inverse,
render_texture_format: self.render_texture_format,
}) })
} }
} }

View file

@ -9,6 +9,7 @@ pub struct ScalingRenderer {
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
width: f32, width: f32,
height: f32, height: f32,
render_texture_format: wgpu::TextureFormat,
} }
impl ScalingRenderer { impl ScalingRenderer {
@ -16,6 +17,7 @@ impl ScalingRenderer {
device: &wgpu::Device, device: &wgpu::Device,
texture_view: &wgpu::TextureView, texture_view: &wgpu::TextureView,
texture_size: &wgpu::Extent3d, texture_size: &wgpu::Extent3d,
render_texture_format: wgpu::TextureFormat,
) -> Self { ) -> Self {
let vs_module = device.create_shader_module(wgpu::include_spirv!("../shaders/vert.spv")); let vs_module = device.create_shader_module(wgpu::include_spirv!("../shaders/vert.spv"));
let fs_module = device.create_shader_module(wgpu::include_spirv!("../shaders/frag.spv")); let fs_module = device.create_shader_module(wgpu::include_spirv!("../shaders/frag.spv"));
@ -126,7 +128,7 @@ impl ScalingRenderer {
}), }),
primitive_topology: wgpu::PrimitiveTopology::TriangleList, primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[wgpu::ColorStateDescriptor { color_states: &[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8UnormSrgb, format: render_texture_format,
color_blend: wgpu::BlendDescriptor::REPLACE, color_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE, alpha_blend: wgpu::BlendDescriptor::REPLACE,
write_mask: wgpu::ColorWrite::ALL, write_mask: wgpu::ColorWrite::ALL,
@ -147,6 +149,7 @@ impl ScalingRenderer {
render_pipeline, render_pipeline,
width: texture_size.width as f32, width: texture_size.width as f32,
height: texture_size.height as f32, height: texture_size.height as f32,
render_texture_format,
} }
} }