Skip to content

Commit

Permalink
Add builder methods for VSync and setting wgpu backend (#78)
Browse files Browse the repository at this point in the history
* Add builder methods for VSync and setting wgpu backends

* enable_vsync sets the VSync mode
* wgpu_backend sets the wgpu BackendBit struct
* Made RequestAdapterOptions use compatible_surface by default

* Internally store wgpu::PresentMode for enabling vsync

This doesn't expose the PresentMode for the external api, because
the variants of PresentMode aren't very obvious to people without
wgpu experience.  Mailbox corresponds to VSync enabled, and
Immediate corresponds to VSync disabled.
  • Loading branch information
Aeledfyr authored May 20, 2020
1 parent 809d3f6 commit b43336d
Showing 1 changed file with 42 additions and 10 deletions.
52 changes: 42 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub struct Pixels {
queue: Rc<RefCell<wgpu::Queue>>,
swap_chain: wgpu::SwapChain,
surface_texture: SurfaceTexture,
present_mode: wgpu::PresentMode,

// List of render passes
renderers: Vec<BoxedRenderPass>,
Expand All @@ -59,11 +60,13 @@ pub struct Pixels {

/// A builder to help create customized pixel buffers.
pub struct PixelsBuilder<'req> {
request_adapter_options: wgpu::RequestAdapterOptions<'req>,
request_adapter_options: Option<wgpu::RequestAdapterOptions<'req>>,
device_descriptor: wgpu::DeviceDescriptor,
backend: wgpu::BackendBit,
width: u32,
height: u32,
pixel_aspect_ratio: f64,
present_mode: wgpu::PresentMode,
surface_texture: SurfaceTexture,
texture_format: wgpu::TextureFormat,
renderer_factories: Vec<RenderPassFactory>,
Expand Down Expand Up @@ -166,7 +169,7 @@ impl Pixels {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: self.surface_texture.width,
height: self.surface_texture.height,
present_mode: wgpu::PresentMode::Mailbox,
present_mode: self.present_mode,
},
);

Expand Down Expand Up @@ -301,14 +304,13 @@ impl<'req> PixelsBuilder<'req> {
assert!(height > 0);

PixelsBuilder {
request_adapter_options: wgpu::RequestAdapterOptions {
compatible_surface: None,
power_preference: wgpu::PowerPreference::Default,
},
request_adapter_options: None,
device_descriptor: wgpu::DeviceDescriptor::default(),
backend: wgpu::BackendBit::PRIMARY,
width,
height,
pixel_aspect_ratio: 1.0,
present_mode: wgpu::PresentMode::Mailbox,
surface_texture,
texture_format: wgpu::TextureFormat::Rgba8UnormSrgb,
renderer_factories: Vec::new(),
Expand All @@ -320,7 +322,7 @@ impl<'req> PixelsBuilder<'req> {
mut self,
request_adapter_options: wgpu::RequestAdapterOptions<'req>,
) -> PixelsBuilder {
self.request_adapter_options = request_adapter_options;
self.request_adapter_options = Some(request_adapter_options);
self
}

Expand All @@ -333,6 +335,15 @@ impl<'req> PixelsBuilder<'req> {
self
}

/// 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.
pub const fn wgpu_backend(mut self, backend: wgpu::BackendBit) -> PixelsBuilder<'req> {
self.backend = backend;
self
}

/// Set the pixel aspect ratio to simulate non-square pixels.
///
/// This setting enables a render pass that horizontally scales the pixel buffer by the given
Expand All @@ -350,6 +361,18 @@ impl<'req> PixelsBuilder<'req> {
self
}

/// Enable or disable vsync.
///
/// Vsync is enabled by default.
pub fn enable_vsync(mut self, enable_vsync: bool) -> PixelsBuilder<'req> {
self.present_mode = if enable_vsync {
wgpu::PresentMode::Mailbox
} else {
wgpu::PresentMode::Immediate
};
self
}

/// Set the texture format.
///
/// The default value is [`wgpu::TextureFormat::Rgba8UnormSrgb`], which is 4 unsigned bytes in
Expand Down Expand Up @@ -427,10 +450,16 @@ impl<'req> PixelsBuilder<'req> {
pub fn build(self) -> Result<Pixels, Error> {
// TODO: Use `options.pixel_aspect_ratio` to stretch the scaled texture
let adapter = futures_executor::block_on(wgpu::Adapter::request(
&self.request_adapter_options,
wgpu::BackendBit::PRIMARY,
&self
.request_adapter_options
.unwrap_or(wgpu::RequestAdapterOptions {
compatible_surface: Some(&self.surface_texture.surface),
power_preference: wgpu::PowerPreference::Default,
}),
self.backend,
))
.ok_or(Error::AdapterNotFound)?;

let (device, queue) =
futures_executor::block_on(adapter.request_device(&self.device_descriptor));
let device = Rc::new(device);
Expand Down Expand Up @@ -464,6 +493,8 @@ impl<'req> PixelsBuilder<'req> {
let mut pixels = Vec::with_capacity(capacity);
pixels.resize_with(capacity, Default::default);

let present_mode = self.present_mode;

// Create swap chain
let surface_texture = self.surface_texture;
let swap_chain = device.create_swap_chain(
Expand All @@ -473,7 +504,7 @@ impl<'req> PixelsBuilder<'req> {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: surface_texture.width,
height: surface_texture.height,
present_mode: wgpu::PresentMode::Mailbox,
present_mode,
},
);

Expand Down Expand Up @@ -501,6 +532,7 @@ impl<'req> PixelsBuilder<'req> {
queue,
swap_chain,
surface_texture,
present_mode,
renderers,
texture,
texture_extent,
Expand Down

0 comments on commit b43336d

Please # to comment.