diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 487d8b4160..b0153a5023 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -336,6 +336,9 @@ void BufferCacheRuntime::Finish() {
 
 void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
                                     std::span<const VideoCommon::BufferCopy> copies, bool barrier) {
+    if (dst_buffer == VK_NULL_HANDLE || src_buffer == VK_NULL_HANDLE) {
+        return;
+    }
     static constexpr VkMemoryBarrier READ_BARRIER{
         .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
         .pNext = nullptr,
@@ -394,6 +397,9 @@ void BufferCacheRuntime::PostCopyBarrier() {
 }
 
 void BufferCacheRuntime::ClearBuffer(VkBuffer dest_buffer, u32 offset, size_t size, u32 value) {
+    if (dest_buffer == VK_NULL_HANDLE) {
+        return;
+    }
     static constexpr VkMemoryBarrier READ_BARRIER{
         .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
         .pNext = nullptr,
@@ -473,6 +479,11 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset
             cmdbuf.BindVertexBuffers2EXT(index, 1, &buffer, &vk_offset, &vk_size, &vk_stride);
         });
     } else {
+        if (!device.HasNullDescriptor() && buffer == VK_NULL_HANDLE) {
+            ReserveNullBuffer();
+            buffer = *null_buffer;
+            offset = 0;
+        }
         scheduler.Record([index, buffer, offset](vk::CommandBuffer cmdbuf) {
             cmdbuf.BindVertexBuffer(index, buffer, offset);
         });
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 5c5bfa18d9..8e77f5aa3f 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -1487,6 +1487,9 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
 
         max_push_descriptors = push_descriptor.maxPushDescriptors;
     }
+
+    has_null_descriptor = true;
+
     return extensions;
 }
 
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 920a8f4e30..6042046e12 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -397,6 +397,10 @@ public:
         return must_emulate_bgr565;
     }
 
+    bool HasNullDescriptor() const {
+        return has_null_descriptor;
+    }
+
     u32 GetMaxVertexInputAttributes() const {
         return max_vertex_input_attributes;
     }
@@ -511,6 +515,7 @@ private:
     bool supports_d24_depth{};                   ///< Supports D24 depth buffers.
     bool cant_blit_msaa{};                       ///< Does not support MSAA<->MSAA blitting.
     bool must_emulate_bgr565{};                  ///< Emulates BGR565 by swizzling RGB565 format.
+    bool has_null_descriptor{};                  ///< Has support for null descriptors.
     u32 max_vertex_input_attributes{};           ///< Max vertex input attributes in pipeline
     u32 max_vertex_input_bindings{};             ///< Max vertex input buffers in pipeline