diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 13d0c5788..33d53e9c9 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -47,6 +47,13 @@ namespace dxvk { } + bool DxvkBuffer::canRelocate() const { + return !m_storage->flags().test(DxvkAllocationFlag::Imported) + && !m_bufferInfo.mapPtr + && !(m_info.usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) + && !(m_info.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT); + } + Rc DxvkBuffer::createView( const DxvkBufferViewKey& info) { diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index b1123c4e2..46fa83903 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -342,12 +342,13 @@ namespace dxvk { } /** - * \brief Checks whether the buffer is imported - * \returns \c true if the buffer is imported + * \brief Checks whether the buffer can be relocated + * + * Buffers that require a stable GPU or CPU address cannot be + * moved, unless it's done explicitly done by the client API. + * \returns \c true if the backend can safely relocate the buffer */ - bool isForeign() const { - return m_storage->flags().test(DxvkAllocationFlag::Imported); - } + bool canRelocate() const; /** * \brief Creates or retrieves a buffer view diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 9b0b4cfa5..b55a15ada 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -6478,20 +6478,8 @@ namespace dxvk { if (copySize != buffer->info().size || copySize > 0x40000) return false; - // Don't discard host-visible buffers since that may interfere with the frontend - if (buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - return false; - - // Don't discard sparse buffers - if (buffer->info().flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) - return false; - - // Don't discard imported buffers - if (buffer->isForeign()) - return false; - - // Don't discard buffers that need a stable device address - if (buffer->info().usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) + // Check if the buffer is safe to move at all + if (!buffer->canRelocate()) return false; // Suspend the current render pass if transform feedback is active prior to