diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp index d243498b4..188f3d68a 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp @@ -1024,15 +1024,20 @@ void GEVulkanDrawCall::createVulkanData() flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; extra_size = 200 * sizeof(VkDrawIndexedIndirectCommand); } + // Use VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + // or a staging buffer when buffer is small m_dynamic_data = new GEVulkanDynamicBuffer(flags, extra_size + sizeof(GEVulkanCameraUBO), GEVulkanDriver::getMaxFrameInFlight(), + GEVulkanDynamicBuffer::supportsHostTransfer() ? 0 : GEVulkanDriver::getMaxFrameInFlight()); flags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + // Using VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + // will be a lot slower when there are many objects (like particles) m_sbo_data = new GEVulkanDynamicBuffer(flags, getInitialSBOSize(), - GEVulkanDriver::getMaxFrameInFlight(), - GEVulkanDriver::getMaxFrameInFlight()); + GEVulkanDriver::getMaxFrameInFlight(), 0, + false/*enable_host_transfer*/); } // createVulkanData // ---------------------------------------------------------------------------- diff --git a/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.cpp b/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.cpp index 95510269f..642ec3347 100644 --- a/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.cpp +++ b/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.cpp @@ -14,9 +14,11 @@ int GEVulkanDynamicBuffer::m_supports_host_transfer = -1; GEVulkanDynamicBuffer::GEVulkanDynamicBuffer(VkBufferUsageFlags usage, size_t initial_size, unsigned host_buffer_size, - unsigned local_buffer_size) + unsigned local_buffer_size, + bool enable_host_transfer) + : m_usage(usage), + m_enable_host_transfer(enable_host_transfer) { - m_usage = usage; m_size = m_real_size = initial_size; m_host_buffer.resize(host_buffer_size, VK_NULL_HANDLE); @@ -51,8 +53,9 @@ start: host_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; host_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - if ((with_transfer && m_supports_host_transfer == 1) || - (with_transfer && m_supports_host_transfer == -1)) + if (((with_transfer && m_supports_host_transfer == 1) || + (with_transfer && m_supports_host_transfer == -1)) && + m_enable_host_transfer) { host_info.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT; @@ -66,7 +69,8 @@ start: return; } - if (with_transfer && m_supports_host_transfer == -1) + if (with_transfer && m_enable_host_transfer && + m_supports_host_transfer == -1) { vmaGetAllocationMemoryProperties(vk->getVmaAllocator(), host_memory, &prop); diff --git a/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.hpp b/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.hpp index a533c4bd2..257156560 100644 --- a/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.hpp +++ b/lib/graphics_engine/src/ge_vulkan_dynamic_buffer.hpp @@ -19,10 +19,12 @@ private: std::vector m_mapped_addr; - VkBufferUsageFlags m_usage; - size_t m_size, m_real_size; + const VkBufferUsageFlags m_usage; + + const bool m_enable_host_transfer; + static int m_supports_host_transfer; // ------------------------------------------------------------------------ void initHostBuffer(unsigned frame, bool with_transfer); @@ -34,7 +36,8 @@ public: // ------------------------------------------------------------------------ GEVulkanDynamicBuffer(VkBufferUsageFlags usage, size_t initial_size, unsigned host_buffer_size, - unsigned local_buffer_size); + unsigned local_buffer_size, + bool enable_host_transfer = true); // ------------------------------------------------------------------------ ~GEVulkanDynamicBuffer(); // ------------------------------------------------------------------------ @@ -60,6 +63,12 @@ public: std::vector& getLocalMemory() { return m_local_memory; } // ------------------------------------------------------------------------ std::vector& getMappedAddr() { return m_mapped_addr; } + // ------------------------------------------------------------------------ + /** This can only be called after creating an instance with + * local_buffer_size == 0 first, which is always done in + * GEVulkan2dRenderer::createTrisBuffers. */ + static bool supportsHostTransfer() + { return m_supports_host_transfer == 1; } }; // GEVulkanDynamicBuffer