diff --git a/src/headset/emulated_headset.cpp b/src/headset/emulated_headset.cpp
index 9ef4bf68a9f7d2c796365b8a0f3aacee1618fb73..3bd74ecdad9d65e96c617d1c9c4a0d113dc0546c 100644
--- a/src/headset/emulated_headset.cpp
+++ b/src/headset/emulated_headset.cpp
@@ -230,12 +230,18 @@ void EmulatedHeadset::destroy_framebuffer()
 {
     for (lava::image::ptr& framebuffer : this->framebuffers)
     {
-        framebuffer->destroy(true);
-        framebuffer = nullptr;
+        if (framebuffer != nullptr)
+        {
+            framebuffer->destroy(true);
+            framebuffer = nullptr;
+        }
     }
 
-    this->framebuffer_array->destroy();
-    this->framebuffer_array = nullptr;
+    if (this->framebuffer_array != nullptr)
+    {
+        this->framebuffer_array->destroy();
+        this->framebuffer_array = nullptr;
+    }
 }
 
 void EmulatedHeadset::compute_matrices(Eye eye)
diff --git a/src/headset/headset.cpp b/src/headset/headset.cpp
index a90f140b34c2a676c78e7a86cc81a6b95aaa2cfe..52e0f0aa3b128479601980cecb2f47c1317751a9 100644
--- a/src/headset/headset.cpp
+++ b/src/headset/headset.cpp
@@ -24,6 +24,11 @@ bool Headset::on_setup_device(lava::device::create_param& parameters)
     return true;
 }
 
+void Headset::on_shutdown()
+{
+
+}
+
 void Headset::submit_metadata(const FrameMetadata& metadata)
 {
 
diff --git a/src/headset/headset.hpp b/src/headset/headset.hpp
index 77aca53b5905fdcfd35317cbb25b9d1161984ba8..2e8eceddb442c2d796356970ccc926420d891442 100644
--- a/src/headset/headset.hpp
+++ b/src/headset/headset.hpp
@@ -69,9 +69,13 @@ public:
     virtual bool on_create() = 0;
 
     // This function is called during the shutdown of the application and every time the active stereo strategy changes.
-    // A headset can use this function to destroy all reqources that it has created.
+    // A headset can use this function to destroy all resources that it has created.
     virtual void on_destroy() = 0;
 
+    // This function is only called during the shutdown of the application.
+    // A headset can use this function to destroy all remaining resources.
+    virtual void on_shutdown();
+
     // This function is called every frame when the interface needs to be rendered.
     // A headset can use this function to manage its own interface.
     virtual bool on_interface() = 0;
diff --git a/src/headset/openvr_headset.cpp b/src/headset/openvr_headset.cpp
index 5e4da384bcbda186fe9b619f14ddb892f7848154..5a2e89afc6b2aa78e5b71bbdaa5dd245b43c863b 100644
--- a/src/headset/openvr_headset.cpp
+++ b/src/headset/openvr_headset.cpp
@@ -68,7 +68,10 @@ bool OpenVRHeadset::on_create()
 void OpenVRHeadset::on_destroy()
 {
     this->destroy_framebuffer();
+}
 
+void OpenVRHeadset::on_shutdown()
+{
     vr::VR_Shutdown();
 }
 
@@ -159,7 +162,7 @@ void OpenVRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f
     
     if (error != vr::VRCompositorError_None)
     {
-        lava::log()->error("Can't submit image to OpenVR. Error code '{}'", error);
+        lava::log()->error("Can't submit image to OpenVR. Maybe due to headset standby. Error code '{}'", error);
     }
 }
 
@@ -246,12 +249,18 @@ void OpenVRHeadset::destroy_framebuffer()
 {
     for (lava::image::ptr& framebuffer : this->framebuffers)
     {
-        framebuffer->destroy(true);
-        framebuffer = nullptr;
+        if (framebuffer != nullptr)
+        {
+            framebuffer->destroy(true);
+            framebuffer = nullptr;
+        }
     }
 
-    this->framebuffer_array->destroy();
-    this->framebuffer_array = nullptr;
+    if (this->framebuffer_array != nullptr)
+    {
+        this->framebuffer_array->destroy();
+        this->framebuffer_array = nullptr;
+    }
 }
 
 void OpenVRHeadset::compute_matrices(Eye eye)
diff --git a/src/headset/openvr_headset.hpp b/src/headset/openvr_headset.hpp
index 42e1f4771c32f9f10f39872aa32d00cedceb93ca..cc2580113802048010aee851f3ab9a2a3affb56d 100644
--- a/src/headset/openvr_headset.hpp
+++ b/src/headset/openvr_headset.hpp
@@ -22,6 +22,7 @@ public:
 
     bool on_create() override;
     void on_destroy() override;
+    void on_shutdown() override;
 
     bool on_interface() override;
     bool on_update(lava::delta delta_time) override;
diff --git a/src/headset/openxr_headset.cpp b/src/headset/openxr_headset.cpp
index a5b263aec215ed2eafdf60dece88b3c5cdb6086c..4d298260afaf710e5896d0bf3fa0d164ce1fa216 100644
--- a/src/headset/openxr_headset.cpp
+++ b/src/headset/openxr_headset.cpp
@@ -129,6 +129,7 @@ bool OpenXRHeadset::on_setup_instance(lava::frame_config& config)
     }
 
     this->instance_extensions = OpenXRHeadset::split_string(extension_string);
+    this->instance_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); //NOTE: For some reason this extension is not added
 
     for (const std::string& extension : this->instance_extensions)
     {
@@ -273,6 +274,10 @@ void OpenXRHeadset::on_destroy()
 
     xrDestroySpace(this->space);
     xrDestroySession(this->session);
+}
+
+void OpenXRHeadset::on_shutdown()
+{
     xrDestroyInstance(this->instance);
 }
 
@@ -325,7 +330,7 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f
         {
             VkImageMemoryBarrier frame_barrier = lava::image_memory_barrier(frame_image->get(), frame_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
             frame_barrier.srcAccessMask = 0;
-            frame_barrier.dstAccessMask = 0;
+            frame_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
             frame_barrier.subresourceRange = frame_image->get_subresource_range();
 
             image_barriers.push_back(frame_barrier);
@@ -333,7 +338,7 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f
 
         VkImageMemoryBarrier swapchain_begin_barrier = lava::image_memory_barrier(swapchain_image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
         swapchain_begin_barrier.srcAccessMask = 0;
-        swapchain_begin_barrier.dstAccessMask = 0;
+        swapchain_begin_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
         swapchain_begin_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
         swapchain_begin_barrier.subresourceRange.baseMipLevel = 0;
         swapchain_begin_barrier.subresourceRange.levelCount = 1;
@@ -342,7 +347,7 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f
 
         image_barriers.push_back(swapchain_begin_barrier);
 
-        vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, image_barriers.size(), image_barriers.data());
+        vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, image_barriers.size(), image_barriers.data());
 
         VkImageCopy copy_region;
         copy_region.srcSubresource = frame_image->get_subresource_layers(),
@@ -362,8 +367,9 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f
 
         vkCmdCopyImage(command_buffer, frame_image->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchain_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
 
-        VkImageMemoryBarrier swapchain_end_barrier = lava::image_memory_barrier(swapchain_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-        swapchain_end_barrier.srcAccessMask = 0;
+        //NOTE: For some reason the image layout has to be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL even though the OpenXR specification says that it has to be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        VkImageMemoryBarrier swapchain_end_barrier = lava::image_memory_barrier(swapchain_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
+        swapchain_end_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
         swapchain_end_barrier.dstAccessMask = 0;
         swapchain_end_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
         swapchain_end_barrier.subresourceRange.baseMipLevel = 0;
@@ -371,7 +377,7 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f
         swapchain_end_barrier.subresourceRange.baseArrayLayer = 0;
         swapchain_end_barrier.subresourceRange.layerCount = 1;
 
-        vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &swapchain_end_barrier);
+        vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &swapchain_end_barrier);
 
         this->release_image(frame_id);
 
@@ -471,12 +477,18 @@ void OpenXRHeadset::destroy_framebuffers()
 {
     for (lava::image::ptr& framebuffer : this->framebuffers)
     {
-        framebuffer->destroy(true);
-        framebuffer = nullptr;
+        if (framebuffer != nullptr)
+        {
+            framebuffer->destroy(true);
+            framebuffer = nullptr;
+        }
     }
 
-    this->framebuffer_array->destroy();
-    this->framebuffer_array = nullptr;
+    if (this->framebuffer_array != nullptr)
+    {
+        this->framebuffer_array->destroy();
+        this->framebuffer_array = nullptr;
+    }
 }
 
 bool OpenXRHeadset::create_swapchains()
diff --git a/src/headset/openxr_headset.hpp b/src/headset/openxr_headset.hpp
index f0adbde8cbcd03eacfb17d487a15ac8b81816f3f..659a4cf40c852411cc68871fc6ebbfa2a570736b 100644
--- a/src/headset/openxr_headset.hpp
+++ b/src/headset/openxr_headset.hpp
@@ -22,6 +22,7 @@ public:
 
     bool on_create() override;
     void on_destroy() override;
+    void on_shutdown() override;
 
     bool on_interface() override;
     bool on_update(lava::delta delta_time) override;
diff --git a/src/headset/remote_headset.cpp b/src/headset/remote_headset.cpp
index 00c9c0059dcffcc70253fbfe1f9e594de696c385..addc043455fc44affb5ce8afa8207e6e467076f9 100644
--- a/src/headset/remote_headset.cpp
+++ b/src/headset/remote_headset.cpp
@@ -364,8 +364,11 @@ void RemoteHeadset::destroy_framebuffers()
 
     this->framebuffers.clear();
 
-    this->framebuffer_array->destroy();
-    this->framebuffer_array = nullptr;
+    if (this->framebuffer_array != nullptr)
+    {
+        this->framebuffer_array->destroy();
+        this->framebuffer_array = nullptr;
+    }
 }
 
 bool RemoteHeadset::create_encoders()
diff --git a/src/vr_application.cpp b/src/vr_application.cpp
index f719dc9be530dc91a264bc5f0e74b8d970219666..f2b841fd45affc2a8b5be04cfd4dc577c2c84fc3 100644
--- a/src/vr_application.cpp
+++ b/src/vr_application.cpp
@@ -456,6 +456,11 @@ void VRApplication::on_destroy()
 {  
     this->destroy_config();
 
+    if (this->headset != nullptr)
+    {
+        this->headset->on_shutdown();
+    }
+
     if (this->pass_timer != nullptr)
     {
         this->pass_timer->write_to_file(this->app->device);