Make things return errors where relevant

This commit is contained in:
Jarrod Doyle 2024-03-23 10:14:18 +00:00
parent 704f3519ef
commit 5d463daa1e
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
7 changed files with 56 additions and 40 deletions

View File

@ -1,4 +1,6 @@
use std::{sync::Arc, time::Instant};
use anyhow::Result;
use winit::{
dpi::PhysicalSize,
event::{Event, WindowEvent},
@ -18,16 +20,15 @@ pub struct App<'window> {
}
impl<'window> App<'window> {
pub async fn new(width: u32, height: u32, title: &str) -> Self {
pub async fn new(width: u32, height: u32, title: &str) -> Result<Self> {
log::info!("Initialising window...");
let size = PhysicalSize::new(width, height);
let event_loop = EventLoop::new().unwrap();
let event_loop = EventLoop::new()?;
let window = Arc::new(
winit::window::WindowBuilder::new()
.with_title(title)
.with_inner_size(size)
.build(&event_loop)
.unwrap(),
.build(&event_loop)?,
);
let render_ctx = gfx::Context::new(
@ -38,16 +39,16 @@ impl<'window> App<'window> {
..Default::default()
},
)
.await;
.await?;
Self {
Ok(Self {
title: title.to_owned(),
event_loop,
render_ctx,
}
})
}
pub fn run(mut self) {
pub fn run(mut self) -> Result<()> {
let mut camera_controller = camera::CameraController::new(
&self.render_ctx,
camera::Camera::new(
@ -81,7 +82,7 @@ impl<'window> App<'window> {
glam::uvec3(32, 32, 32),
);
let mut renderer = voxel::VoxelRenderer::new(&self.render_ctx, &camera_controller);
let mut renderer = voxel::VoxelRenderer::new(&self.render_ctx, &camera_controller)?;
let mut cumulative_dt = 0.0;
let mut frames_accumulated = 0.0;
@ -169,5 +170,7 @@ impl<'window> App<'window> {
// }
// }
});
Ok(())
}
}

View File

@ -1,5 +1,7 @@
use std::num::NonZeroU32;
use anyhow::{Context as _, Result};
use super::Context;
#[derive(Debug, Default)]
@ -123,13 +125,13 @@ impl<'a> BindGroupBuilder<'a> {
}
#[inline]
pub fn build(self, context: &Context) -> wgpu::BindGroup {
context
pub fn build(self, context: &Context) -> Result<wgpu::BindGroup> {
Ok(context
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
label: self.label,
layout: self.layout.unwrap(),
layout: self.layout.context("BindGroupBuilder has no layout.")?,
entries: self.entries.as_slice(),
})
}))
}
}

View File

@ -1,5 +1,6 @@
use std::sync::Arc;
use anyhow::{Context as _, Result};
use winit::{
dpi::PhysicalSize, event::WindowEvent, event_loop::EventLoopWindowTarget, window::Window,
};
@ -16,7 +17,7 @@ pub struct Context<'window> {
}
impl<'window> Context<'window> {
pub async fn new(window: Arc<Window>, limits: wgpu::Limits) -> Self {
pub async fn new(window: Arc<Window>, limits: wgpu::Limits) -> Result<Self> {
log::info!("Initialising WGPU context...");
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::VULKAN,
@ -29,7 +30,7 @@ impl<'window> Context<'window> {
// - A GPU device to draw to the surface
// - A draw command queue
log::info!("Initialising window surface...");
let surface = instance.create_surface(window.clone()).unwrap();
let surface = instance.create_surface(window.clone())?;
log::info!("Requesting GPU adapter...");
let adapter = instance
@ -39,7 +40,7 @@ impl<'window> Context<'window> {
compatible_surface: Some(&surface),
})
.await
.unwrap();
.context("Failed to find suitable GPU adapter")?;
log::info!("Checking GPU adapter meets requirements");
log::info!("Requesting GPU device...");
@ -52,17 +53,16 @@ impl<'window> Context<'window> {
},
None,
)
.await
.unwrap();
.await?;
log::info!("Configuring window surface...");
let size = window.inner_size();
let surface_config = surface
.get_default_config(&adapter, size.width, size.height)
.unwrap();
.context("Surface configuration unsupported by adapter")?;
surface.configure(&device, &surface_config);
Self {
Ok(Self {
window,
instance,
size,
@ -71,7 +71,7 @@ impl<'window> Context<'window> {
adapter,
device,
queue,
}
})
}
pub fn resize_surface(&mut self, new_size: PhysicalSize<u32>) {

View File

@ -1,6 +1,8 @@
use std::time::Duration;
use anyhow::Result;
pub trait Renderer {
fn update(&mut self, dt: &Duration, context: &super::Context);
fn render(&self, context: &super::Context);
fn update(&mut self, dt: &Duration, context: &super::Context) -> Result<()>;
fn render(&self, context: &super::Context) -> Result<()>;
}

View File

@ -1,7 +1,8 @@
// TODO: Support mip-mapping and multi-sampling
use anyhow::Result;
use super::{BindGroupBuilder, BindGroupLayoutBuilder, Context};
// TODO: Support mip-mapping and multi-sampling
#[derive(Debug, Clone)]
pub struct TextureAttributes {
pub size: wgpu::Extent3d,
@ -98,7 +99,7 @@ impl TextureBuilder {
}
#[inline]
pub fn build(self, context: &Context) -> Texture {
pub fn build(self, context: &Context) -> Result<Texture> {
Texture::new(context, self.attributes)
}
}
@ -114,7 +115,7 @@ pub struct Texture {
}
impl Texture {
pub fn new(context: &Context, attributes: TextureAttributes) -> Self {
pub fn new(context: &Context, attributes: TextureAttributes) -> Result<Self> {
let texture = context.device.create_texture(&wgpu::TextureDescriptor {
label: None,
size: attributes.size,
@ -163,16 +164,16 @@ impl Texture {
.with_layout(&bind_group_layout)
.with_entry(wgpu::BindingResource::TextureView(&view))
.with_entry(wgpu::BindingResource::Sampler(&sampler))
.build(context);
.build(context)?;
Self {
Ok(Self {
attributes,
texture,
view,
sampler,
bind_group_layout,
bind_group,
}
})
}
pub fn update(&self, context: &Context, data: &[u8]) {

View File

@ -3,7 +3,10 @@ mod gfx;
mod math;
mod voxel;
fn main() {
use anyhow::Result;
fn main() -> Result<()> {
env_logger::init();
pollster::block_on(core::App::new(1280, 720, "Epic")).run();
pollster::block_on(core::App::new(1280, 720, "Epic"))?.run()?;
Ok(())
}

View File

@ -1,5 +1,7 @@
use std::time::Duration;
use anyhow::Result;
use crate::{core, gfx};
#[derive(Debug)]
@ -15,7 +17,7 @@ pub struct VoxelRenderer {
}
impl VoxelRenderer {
pub fn new(context: &gfx::Context, camera_controller: &core::CameraController) -> Self {
pub fn new(context: &gfx::Context, camera_controller: &core::CameraController) -> Result<Self> {
log::info!("Creating render shader...");
let shader_descriptor = wgpu::include_wgsl!("../../assets/shaders/shader.wgsl");
let shader = context.device.create_shader_module(shader_descriptor);
@ -30,7 +32,7 @@ impl VoxelRenderer {
| wgpu::TextureUsages::STORAGE_BINDING,
)
.with_shader_visibility(wgpu::ShaderStages::FRAGMENT | wgpu::ShaderStages::COMPUTE)
.build(context);
.build(context)?;
log::info!("Creating render pipeline...");
let render_pipeline =
@ -100,7 +102,7 @@ impl VoxelRenderer {
.get_brickgrid_unpack_buffer()
.as_entire_binding(),
)
.build(context);
.build(context)?;
let unpack_pipeline =
context
.device
@ -147,7 +149,7 @@ impl VoxelRenderer {
.with_entry(brickmap_manager.get_shading_buffer().as_entire_binding())
.with_entry(brickmap_manager.get_feedback_buffer().as_entire_binding())
.with_entry(camera_controller.get_buffer().as_entire_binding())
.build(context);
.build(context)?;
let raycast_pipeline =
context
.device
@ -164,7 +166,7 @@ impl VoxelRenderer {
entry_point: "compute",
});
Self {
Ok(Self {
clear_color: wgpu::Color::BLACK,
render_texture,
render_pipeline,
@ -173,13 +175,13 @@ impl VoxelRenderer {
raycast_bind_group,
unpack_pipeline,
unpack_bind_group,
}
})
}
}
impl gfx::Renderer for VoxelRenderer {
fn render(&self, context: &gfx::Context) {
let frame = context.surface.get_current_texture().unwrap();
fn render(&self, context: &gfx::Context) -> Result<()> {
let frame = context.surface.get_current_texture()?;
let view = frame
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
@ -231,9 +233,12 @@ impl gfx::Renderer for VoxelRenderer {
context.queue.submit(Some(encoder.finish()));
frame.present();
Ok(())
}
fn update(&mut self, _dt: &Duration, _context: &gfx::Context) {}
fn update(&mut self, _dt: &Duration, _context: &gfx::Context) -> Result<()> {
Ok(())
}
}
impl VoxelRenderer {