This commit is contained in:
Imbris 2020-11-30 02:27:36 -05:00 committed by Avi Weinstock
parent 0f569266aa
commit 90a1371673
4 changed files with 63 additions and 5 deletions

View File

@ -11,6 +11,7 @@ pub enum RenderError {
}
use std::fmt;
// TODO: just impl and use Display?
impl fmt::Debug for RenderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@ -18,7 +19,11 @@ impl fmt::Debug for RenderError {
f.debug_tuple("RequestDeviceError").field(err).finish()
},
Self::MappingError(err) => f.debug_tuple("MappingError").field(err).finish(),
Self::SwapChainError(err) => f.debug_tuple("SwapChainError").field(err).finish(),
Self::SwapChainError(err) => f
.debug_tuple("SwapChainError")
// Use Display formatting for this error since they have nice descriptions
.field(&format!("{}", err))
.finish(),
Self::CustomError(err) => f.debug_tuple("CustomError").field(err).finish(),
Self::CouldNotFindAdapter => f.debug_tuple("CouldNotFindAdapter").finish(),
Self::ErrorInitializingCompiler => f.debug_tuple("ErrorInitializingCompiler").finish(),

View File

@ -151,6 +151,7 @@ pub struct Renderer {
queue: wgpu::Queue,
swap_chain: wgpu::SwapChain,
sc_desc: wgpu::SwapChainDescriptor,
surface: wgpu::Surface,
win_depth_view: wgpu::TextureView,
@ -372,6 +373,7 @@ impl Renderer {
queue,
swap_chain,
sc_desc,
surface,
win_depth_view,
@ -437,6 +439,13 @@ impl Renderer {
pub fn on_resize(&mut self, dims: Vec2<u32>) -> Result<(), RenderError> {
// Avoid panics when creating texture with w,h of 0,0.
if dims.x != 0 && dims.y != 0 {
// Resize swap chain
self.resolution = dims;
self.sc_desc.width = dims.x;
self.sc_desc.height = dims.y;
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
// Resize other render targets
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view) =
Self::create_rt_views(&mut self.device, (dims.x, dims.y), &self.mode)?;
self.win_depth_view = win_depth_view;
@ -456,8 +465,6 @@ impl Renderer {
},
}
}
self.resolution = dims;
}
Ok(())
@ -797,14 +804,58 @@ impl Renderer {
/// Perform all queued draw calls for this frame and clean up discarded
/// items.
pub fn flush(&mut self) {
pub fn flush(&mut self) -> Result<(), RenderError> {
span!(_guard, "flush", "Renderer::flush");
let frame = match self.swap_chain.get_current_frame() {
Ok(frame) => frame.output,
// If lost recreate the swap chain
Err(err @ wgpu::SwapChainError::Lost) => {
warn!("{}. Recreating swap chain. A frame will be missed", err);
return self.on_resize(self.resolution);
},
Err(err @ wgpu::SwapChainError::Timeout) => {
warn!("{}. This will probably be resolved on the next frame", err);
return Ok(());
},
Err(err @ wgpu::SwapChainError::Outdated) => {
warn!("{}. This will probably be resolved on the next frame", err);
return Ok(());
},
Err(err @ wgpu::SwapChainError::OutOfMemory) => return Err(err.into()),
};
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("A render encoder"),
});
{
let _render_pas = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color {
r: 0.1,
g: 0.7,
b: 0.3,
a: 1.0,
}),
store: true,
},
}],
depth_stencil_attachment: None,
});
}
self.queue.submit(std::iter::once(encoder.finish()));
self.device.poll(wgpu::Maintain::Poll);
// If the shaders files were changed attempt to recreate the shaders
if self.shaders.reloaded() {
self.recreate_pipelines();
}
Ok(())
}
/// Recreate the pipelines

View File

@ -174,7 +174,8 @@ fn handle_main_events_cleared(
// Render the screen using the global renderer
last.render(renderer, &global_state.settings);
// Finish the frame.
// global_state.window.renderer_mut().flush();
// TODO: do this as part of dropping rendering thing
global_state.window.renderer_mut().flush().unwrap();
// // Display the frame on the window.
// global_state
// .window

View File

@ -949,6 +949,7 @@ impl Window {
.push(Event::Resize(Vec2::new(width as u32, height as u32)));
},
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
// TODO: is window resized event emitted? or do we need to handle that here?
self.scale_factor = scale_factor;
self.events.push(Event::ScaleFactorChanged(scale_factor));
},