From c401c0f9db9e8a11aa0358511d5b99c56cc1ec8a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 23 Apr 2025 03:55:58 +0300 Subject: [PATCH] vk: Get rid of multidraw indirection buffer --- rpcs3/Emu/RSX/VK/VKDraw.cpp | 29 ++++++++++------------------- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 6 ------ rpcs3/Emu/RSX/VK/VKGSRender.h | 2 +- 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index f66c72c4c2..4a34d45fbf 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -939,17 +939,8 @@ void VKGSRender::emit_geometry(u32 sub_index) else if (m_device->get_multidraw_support()) { const auto subranges = draw_call.get_subranges(); - const auto subranges_count = ::size32(subranges); - auto [offset, ptr] = m_draw_indirect_count_ring_info.alloc_and_map<4, VkMultiDrawInfoEXT>(subranges_count); - - auto _ptr = ptr; - for (const auto& range : subranges) - { - _ptr->firstVertex = range.first; - _ptr->vertexCount = range.count; - _ptr++; - } - _vkCmdDrawMultiEXT(*m_current_command_buffer, subranges_count, ptr, 1, 0, sizeof(VkMultiDrawInfoEXT)); + auto ptr = reinterpret_cast(& subranges.front().first); + _vkCmdDrawMultiEXT(*m_current_command_buffer, ::size32(subranges), ptr, 1, 0, sizeof(rsx::draw_range_t)); } else { @@ -981,21 +972,21 @@ void VKGSRender::emit_geometry(u32 sub_index) { const auto subranges = draw_call.get_subranges(); const auto subranges_count = ::size32(subranges); - auto [offset, ptr] = m_draw_indirect_count_ring_info.alloc_and_map<4, VkMultiDrawIndexedInfoEXT>(subranges_count); + const auto allocation_size = subranges_count * 3; - auto _ptr = ptr; + m_multidraw_parameters_buffer.resize(allocation_size); + auto _ptr = m_multidraw_parameters_buffer.data(); u32 vertex_offset = 0; + for (const auto& range : subranges) { const auto count = get_index_count(draw_call.primitive, range.count); - _ptr->vertexOffset = 0; - _ptr->firstIndex = vertex_offset; - _ptr->indexCount = count; - - _ptr++; + *_ptr++ = 0; + *_ptr++ = vertex_offset; + *_ptr++ = count; vertex_offset += count; } - _vkCmdDrawMultiIndexedEXT(*m_current_command_buffer, subranges_count, ptr, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), nullptr); + _vkCmdDrawMultiIndexedEXT(*m_current_command_buffer, subranges_count, reinterpret_cast(_ptr), 1, 0, sizeof(u32) * 3, nullptr); } else { diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index f59663f856..68c6783e7f 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -558,12 +558,6 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) }); } - if (m_device->get_multidraw_support().supported) - { - m_draw_indirect_count_ring_info.create(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, 16 * 0x100000, "multidraw indirect buffer", 1024); - vk::data_heap_manager::register_ring_buffer(m_draw_indirect_count_ring_info); - } - // Initialize optional allocation information with placeholders m_vertex_env_buffer_info = { m_vertex_env_ring_info.heap->value, 0, 16 }; m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, 0, 16 }; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 600a7b306d..2fe1314f13 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -130,7 +130,6 @@ private: vk::data_heap m_texture_upload_buffer_ring_info; // Texture upload heap vk::data_heap m_raster_env_ring_info; // Raster control such as polygon and line stipple vk::data_heap m_instancing_buffer_ring_info; // Instanced rendering data (constants indirection table + instanced constants) - vk::data_heap m_draw_indirect_count_ring_info; // Buffer holding first-count data for multidraw support vk::data_heap m_fragment_instructions_buffer; vk::data_heap m_vertex_instructions_buffer; @@ -148,6 +147,7 @@ private: VkDescriptorBufferInfo m_vertex_instructions_buffer_info {}; VkDescriptorBufferInfo m_fragment_instructions_buffer_info {}; + rsx::simple_array m_multidraw_parameters_buffer; u64 m_xform_constants_dynamic_offset = 0; // We manage transform_constants dynamic offset manually to alleviate performance penalty of doing a hot-patch of constants. std::array frame_context_storage;