Compare commits

...

3 Commits

2 changed files with 93 additions and 6 deletions

View File

@ -2,7 +2,11 @@ use std::sync::Arc;
use thiserror::Error; use thiserror::Error;
use winit::{ use winit::{
dpi::PhysicalSize, event::WindowEvent, event_loop::EventLoopWindowTarget, window::Window, dpi::PhysicalSize,
error::{EventLoopError, OsError},
event::WindowEvent,
event_loop::{EventLoop, EventLoopWindowTarget},
window::{Window, WindowBuilder},
}; };
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -15,6 +19,10 @@ pub enum ContextError {
Adapter, Adapter,
#[error("Device request failed: {0}")] #[error("Device request failed: {0}")]
Device(#[from] wgpu::RequestDeviceError), Device(#[from] wgpu::RequestDeviceError),
#[error("Event loop creation failed: {0}")]
EventLoop(#[from] EventLoopError),
#[error("Window creation failed: {0}")]
Os(#[from] OsError),
} }
pub struct Context<'window> { pub struct Context<'window> {
@ -29,10 +37,15 @@ pub struct Context<'window> {
} }
impl<'window> Context<'window> { impl<'window> Context<'window> {
pub async fn new(window: Arc<Window>, limits: wgpu::Limits) -> Result<Self, ContextError> { pub async fn new(
window: Arc<Window>,
backends: wgpu::Backends,
required_features: wgpu::Features,
required_limits: wgpu::Limits,
) -> Result<Self, ContextError> {
log::info!("Initialising WGPU context..."); log::info!("Initialising WGPU context...");
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::VULKAN, backends,
dx12_shader_compiler: Default::default(), dx12_shader_compiler: Default::default(),
..Default::default() ..Default::default()
}); });
@ -63,8 +76,8 @@ impl<'window> Context<'window> {
.request_device( .request_device(
&wgpu::DeviceDescriptor { &wgpu::DeviceDescriptor {
label: None, label: None,
required_features: wgpu::Features::empty(), required_features,
required_limits: limits, required_limits,
}, },
None, None,
) )
@ -126,3 +139,75 @@ impl<'window> Context<'window> {
handled handled
} }
} }
pub struct ContextBuilder {
title: String,
vsync: bool,
resolution: PhysicalSize<u32>,
backends: wgpu::Backends,
features: wgpu::Features,
limits: wgpu::Limits,
}
impl Default for ContextBuilder {
fn default() -> Self {
Self {
title: "Crawl".to_string(),
vsync: true,
resolution: PhysicalSize::new(1280, 720),
backends: Default::default(),
features: Default::default(),
limits: Default::default(),
}
}
}
impl ContextBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn with_title(mut self, title: &str) -> Self {
self.title = title.to_string();
self
}
pub fn with_vsync(mut self, vsync: bool) -> Self {
self.vsync = vsync;
self
}
pub fn with_resolution(mut self, width: u32, height: u32) -> Self {
self.resolution = PhysicalSize::new(width, height);
self
}
pub fn with_backends(mut self, backends: wgpu::Backends) -> Self {
self.backends = backends;
self
}
pub fn with_features(mut self, features: wgpu::Features) -> Self {
self.features = features;
self
}
pub fn with_limits(mut self, limits: wgpu::Limits) -> Self {
self.limits = limits;
self
}
pub async fn build(self) -> Result<(Context<'static>, EventLoop<()>), ContextError> {
let event_loop = EventLoop::new()?;
let window = Arc::new(
WindowBuilder::new()
.with_title(self.title)
.with_inner_size(self.resolution)
.build(&event_loop)?,
);
let context = Context::new(window, self.backends, self.features, self.limits).await?;
Ok((context, event_loop))
}
}

View File

@ -6,6 +6,8 @@ mod texture;
pub use self::{ pub use self::{
bind_group::{BindGroupBuilder, BindGroupLayoutBuilder}, bind_group::{BindGroupBuilder, BindGroupLayoutBuilder},
buffer::{BufferExt, BulkBufferBuilder}, buffer::{BufferExt, BulkBufferBuilder},
context::Context, context::{Context, ContextBuilder},
texture::{Texture, TextureBuilder}, texture::{Texture, TextureBuilder},
}; };
pub use {wgpu, winit};