Cleanly separate the two texture dimensions
- The pixel buffer dimensions - The surface texture dimensions
This commit is contained in:
parent
44f5b67c9e
commit
2ec43fccd1
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -683,12 +683,19 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"env_logger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"raw-window-handle 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pixels-mocks 0.1.0",
|
||||
"vk-shader-macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wgpu 0.3.0 (git+https://github.com/gfx-rs/wgpu-rs?rev=697393df4793e1a58578209885036114adfb9213)",
|
||||
"winit 0.20.0-alpha3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pixels-mocks"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"raw-window-handle 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.16"
|
||||
|
|
|
@ -17,5 +17,10 @@ wgpu = { git = "https://github.com/gfx-rs/wgpu-rs", rev = "697393df4793e1a585782
|
|||
[dev-dependencies]
|
||||
env_logger = "0.7"
|
||||
log = { version = "0.4", features = ["release_max_level_warn"] }
|
||||
raw-window-handle = "0.1"
|
||||
pixels-mocks = { path = "pixels-mocks" }
|
||||
winit = "0.20.0-alpha3"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"pixels-mocks",
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use pixels::{Error, Pixels};
|
||||
use pixels::{Error, Pixels, SurfaceTexture};
|
||||
use winit::event;
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
|
||||
|
@ -6,14 +6,16 @@ fn main() -> Result<(), Error> {
|
|||
env_logger::init();
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
let (window, surface) = {
|
||||
let (window, surface, width, height) = {
|
||||
let window = winit::window::Window::new(&event_loop).unwrap();
|
||||
let surface = wgpu::Surface::create(&window);
|
||||
let size = window.inner_size().to_physical(window.hidpi_factor());
|
||||
|
||||
(window, surface)
|
||||
(window, surface, size.width as u32, size.height as u32)
|
||||
};
|
||||
|
||||
let mut fb = Pixels::new(320, 240, &surface)?;
|
||||
let surface_texture = SurfaceTexture::new(width, height, &surface);
|
||||
let mut fb = Pixels::new(320, 240, surface_texture)?;
|
||||
|
||||
event_loop.run(move |event, _, control_flow| match event {
|
||||
event::Event::WindowEvent { event, .. } => match event {
|
||||
|
|
9
pixels-mocks/Cargo.toml
Normal file
9
pixels-mocks/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "pixels-mocks"
|
||||
version = "0.1.0"
|
||||
authors = ["Jay Oster <jay@kodewerx.org>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
raw-window-handle = "0.1"
|
24
pixels-mocks/src/lib.rs
Normal file
24
pixels-mocks/src/lib.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
pub struct RWH;
|
||||
|
||||
unsafe impl raw_window_handle::HasRawWindowHandle for RWH {
|
||||
fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
|
||||
#[cfg(target_os = "macos")]
|
||||
return raw_window_handle::RawWindowHandle::MacOS(
|
||||
raw_window_handle::macos::MacOSHandle::empty(),
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
))]
|
||||
return raw_window_handle::RawWindowHandle::X11(raw_window_handle::unix::X11Handle::empty());
|
||||
#[cfg(target_os = "windows")]
|
||||
return raw_window_handle::RawWindowHandle::Windows(
|
||||
raw_window_handle::windows::WindowsHandle::empty(),
|
||||
);
|
||||
#[cfg(target_os = "ios")]
|
||||
return raw_window_handle::RawWindowHandle::IOS(raw_window_handle::ios::IOSHandle::empty());
|
||||
}
|
||||
}
|
171
src/lib.rs
171
src/lib.rs
|
@ -17,6 +17,14 @@ use std::fmt;
|
|||
use vk_shader_macros::include_glsl;
|
||||
pub use wgpu;
|
||||
|
||||
/// A logical texture for a window surface.
|
||||
#[derive(Debug)]
|
||||
pub struct SurfaceTexture<'a> {
|
||||
surface: &'a wgpu::Surface,
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
/// Represents a 2D frame buffer with an explicit image resolution.
|
||||
#[derive(Debug)]
|
||||
pub struct Pixels {
|
||||
|
@ -32,6 +40,8 @@ pub struct Pixels {
|
|||
pub struct PixelsOptions {
|
||||
request_adapter_options: wgpu::RequestAdapterOptions,
|
||||
device_descriptor: wgpu::DeviceDescriptor,
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
/// All the ways in which creating a frame buffer can fail.
|
||||
|
@ -41,38 +51,55 @@ pub enum Error {
|
|||
AdapterNotFound,
|
||||
}
|
||||
|
||||
impl<'a> SurfaceTexture<'a> {
|
||||
/// Create a logical texture for a window surface.
|
||||
///
|
||||
/// It is recommended (but not required) that the `width` and `height` are
|
||||
/// equivalent to the physical dimentions of the `surface`. E.g. scaled by
|
||||
/// the HiDPI factor.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use pixels::SurfaceTexture;
|
||||
/// use wgpu::Surface;
|
||||
/// use winit::event_loop::EventLoop;
|
||||
/// use winit::window::Window;
|
||||
///
|
||||
/// let event_loop = EventLoop::new();
|
||||
/// let window = Window::new(&event_loop).unwrap();
|
||||
/// let surface = Surface::create(&window);
|
||||
/// let size = window.inner_size().to_physical(window.hidpi_factor());
|
||||
///
|
||||
/// let width = size.width as u32;
|
||||
/// let height = size.height as u32;
|
||||
///
|
||||
/// let surface_texture = SurfaceTexture::new(width, height, &surface);
|
||||
/// # Ok::<(), pixels::Error>(())
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics when `width` or `height` are 0.
|
||||
pub fn new(width: u32, height: u32, surface: &'a wgpu::Surface) -> SurfaceTexture<'a> {
|
||||
assert!(width > 0);
|
||||
assert!(height > 0);
|
||||
|
||||
SurfaceTexture {
|
||||
surface,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use pixels::Pixels;
|
||||
/// # struct RWH();
|
||||
/// # unsafe impl raw_window_handle::HasRawWindowHandle for RWH {
|
||||
/// # fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
|
||||
/// # #[cfg(target_os = "macos")]
|
||||
/// # return raw_window_handle::RawWindowHandle::MacOS(
|
||||
/// # raw_window_handle::macos::MacOSHandle::empty()
|
||||
/// # );
|
||||
/// # #[cfg(any(
|
||||
/// # target_os = "linux",
|
||||
/// # target_os = "dragonfly",
|
||||
/// # target_os = "freebsd",
|
||||
/// # target_os = "netbsd",
|
||||
/// # target_os = "openbsd"))]
|
||||
/// # return raw_window_handle::RawWindowHandle::X11(
|
||||
/// # raw_window_handle::unix::X11Handle::empty()
|
||||
/// # );
|
||||
/// # #[cfg(target_os = "windows")]
|
||||
/// # return raw_window_handle::RawWindowHandle::Windows(
|
||||
/// # raw_window_handle::windows::WindowsHandle::empty()
|
||||
/// # );
|
||||
/// # #[cfg(target_os = "ios")]
|
||||
/// # return raw_window_handle::RawWindowHandle::IOS(
|
||||
/// # raw_window_handle::ios::IOSHandle::empty()
|
||||
/// # );
|
||||
/// # }
|
||||
/// # }
|
||||
/// # let surface = wgpu::Surface::create(&RWH());
|
||||
/// let fb = Pixels::new(320, 240, &surface)?;
|
||||
/// # let surface = wgpu::Surface::create(&pixels_mocks::RWH);
|
||||
/// # let surface_texture = pixels::SurfaceTexture::new(1024, 768, &surface);
|
||||
/// let fb = Pixels::new(320, 240, surface_texture)?;
|
||||
/// # Ok::<(), pixels::Error>(())
|
||||
/// ```
|
||||
impl Pixels {
|
||||
|
@ -81,8 +108,12 @@ impl Pixels {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error when a `wgpu::Adapter` cannot be found.
|
||||
pub fn new(width: u32, height: u32, surface: &wgpu::Surface) -> Result<Pixels, Error> {
|
||||
Pixels::new_with_options(width, height, surface, PixelsOptions::new())
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics when `width` or `height` are 0.
|
||||
pub fn new(width: u32, height: u32, surface_texture: SurfaceTexture) -> Result<Pixels, Error> {
|
||||
Pixels::new_with_options(surface_texture, PixelsOptions::new(width, height))
|
||||
}
|
||||
|
||||
/// Create a frame buffer instance with the given options.
|
||||
|
@ -92,11 +123,11 @@ impl Pixels {
|
|||
/// Returns an error when a `wgpu::Adapter` cannot be found or shaders
|
||||
/// are invalid SPIR-V.
|
||||
pub fn new_with_options(
|
||||
width: u32,
|
||||
height: u32,
|
||||
surface: &wgpu::Surface,
|
||||
surface_texture: SurfaceTexture,
|
||||
options: PixelsOptions,
|
||||
) -> Result<Pixels, Error> {
|
||||
// TODO: Create a texture with the dimensions specified in `options`
|
||||
|
||||
let adapter = wgpu::Adapter::request(&options.request_adapter_options)
|
||||
.ok_or(Error::AdapterNotFound)?;
|
||||
let (device, queue) = adapter.request_device(&options.device_descriptor);
|
||||
|
@ -148,12 +179,12 @@ impl Pixels {
|
|||
});
|
||||
|
||||
let swap_chain = device.create_swap_chain(
|
||||
&surface,
|
||||
surface_texture.surface,
|
||||
&wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
width,
|
||||
height,
|
||||
width: surface_texture.width,
|
||||
height: surface_texture.height,
|
||||
present_mode: wgpu::PresentMode::Vsync,
|
||||
},
|
||||
);
|
||||
|
@ -200,43 +231,30 @@ impl Pixels {
|
|||
///
|
||||
/// ```no_run
|
||||
/// # use pixels::PixelsOptions;
|
||||
/// # struct RWH();
|
||||
/// # unsafe impl raw_window_handle::HasRawWindowHandle for RWH {
|
||||
/// # fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
|
||||
/// # #[cfg(target_os = "macos")]
|
||||
/// # return raw_window_handle::RawWindowHandle::MacOS(
|
||||
/// # raw_window_handle::macos::MacOSHandle::empty()
|
||||
/// # );
|
||||
/// # #[cfg(any(
|
||||
/// # target_os = "linux",
|
||||
/// # target_os = "dragonfly",
|
||||
/// # target_os = "freebsd",
|
||||
/// # target_os = "netbsd",
|
||||
/// # target_os = "openbsd"))]
|
||||
/// # return raw_window_handle::RawWindowHandle::X11(
|
||||
/// # raw_window_handle::unix::X11Handle::empty()
|
||||
/// # );
|
||||
/// # #[cfg(target_os = "windows")]
|
||||
/// # return raw_window_handle::RawWindowHandle::Windows(
|
||||
/// # raw_window_handle::windows::WindowsHandle::empty()
|
||||
/// # );
|
||||
/// # #[cfg(target_os = "ios")]
|
||||
/// # return raw_window_handle::RawWindowHandle::IOS(
|
||||
/// # raw_window_handle::ios::IOSHandle::empty()
|
||||
/// # );
|
||||
/// # }
|
||||
/// # }
|
||||
/// # fn main() -> Result<(), pixels::Error> {
|
||||
/// # let surface = wgpu::Surface::create(&RWH());
|
||||
/// let fb = PixelsOptions::new()
|
||||
/// .build(320, 240, &surface)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// # let surface = wgpu::Surface::create(&pixels_mocks::RWH);
|
||||
/// # let surface_texture = pixels::SurfaceTexture::new(1024, 768, &surface);
|
||||
/// let fb = PixelsOptions::new(320, 240)
|
||||
/// # // TODO: demonstrate adding a render pass here
|
||||
/// # //.render_pass(...)
|
||||
/// .build(surface_texture)?;
|
||||
/// # Ok::<(), pixels::Error>(())
|
||||
/// ```
|
||||
impl PixelsOptions {
|
||||
/// Create a builder that can be finalized into a frame buffer instance.
|
||||
pub fn new() -> PixelsOptions {
|
||||
PixelsOptions::default()
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics when `width` or `height` are 0.
|
||||
pub fn new(width: u32, height: u32) -> PixelsOptions {
|
||||
assert!(width > 0);
|
||||
assert!(height > 0);
|
||||
|
||||
PixelsOptions {
|
||||
request_adapter_options: wgpu::RequestAdapterOptions::default(),
|
||||
device_descriptor: wgpu::DeviceDescriptor::default(),
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add options for requesting a `wgpu::Adapter`.
|
||||
|
@ -257,17 +275,8 @@ impl PixelsOptions {
|
|||
///
|
||||
/// Returns an error when a `wgpu::Adapter` cannot be found or shaders
|
||||
/// are invalid SPIR-V.
|
||||
pub fn build(self, width: u32, height: u32, surface: &wgpu::Surface) -> Result<Pixels, Error> {
|
||||
Pixels::new_with_options(width, height, surface, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PixelsOptions {
|
||||
fn default() -> PixelsOptions {
|
||||
PixelsOptions {
|
||||
request_adapter_options: wgpu::RequestAdapterOptions::default(),
|
||||
device_descriptor: wgpu::DeviceDescriptor::default(),
|
||||
}
|
||||
pub fn build(self, surface_texture: SurfaceTexture) -> Result<Pixels, Error> {
|
||||
Pixels::new_with_options(surface_texture, self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue