diff --git a/voxygen/src/render/error.rs b/voxygen/src/render/error.rs
index 124335fc99..cfb3daa0e6 100644
--- a/voxygen/src/render/error.rs
+++ b/voxygen/src/render/error.rs
@@ -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(),
diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs
index 2defab1924..c5cffa1e9b 100644
--- a/voxygen/src/render/renderer.rs
+++ b/voxygen/src/render/renderer.rs
@@ -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
diff --git a/voxygen/src/run.rs b/voxygen/src/run.rs
index 03460cff3b..25c847381f 100644
--- a/voxygen/src/run.rs
+++ b/voxygen/src/run.rs
@@ -175,7 +175,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
diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs
index 48b059b1ae..cbe0f711af 100644
--- a/voxygen/src/window.rs
+++ b/voxygen/src/window.rs
@@ -952,6 +952,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));
             },