diff --git a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h index 94b8da6e8f..0e71b96fbe 100644 --- a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h +++ b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h @@ -179,16 +179,27 @@ namespace rsx , m_batch_size(batch_size) {} - usz alloc() + usz alloc(u32 element_count = 1) { - if (!m_capacity) + if (m_capacity < element_count) { + ensure(element_count <= m_batch_size); m_address = m_container.alloc(ElementSize * m_batch_size); m_capacity = m_batch_size; } - m_capacity--; - return std::exchange(m_address, m_address + ElementSize); + m_capacity -= element_count; + return std::exchange(m_address, m_address + (ElementSize * element_count)); + } + + usz alloc_bytes(usz size = ElementSize) + { + return alloc(static_cast(size / ElementSize)); + } + + u32 capacity() const + { + return m_capacity; } private: diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index c5ee9164dc..606a8bdbe9 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -568,6 +568,16 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) m_vertex_env_ring_info, std::min(limits.maxUniformBufferRange / 96u, 1024u)); + m_transform_constants_allocator = std::make_unique>( + m_transform_constants_ring_info, + std::min(limits.maxUniformBufferRange / 16u, 8192u) + ); + + m_fragment_constants_allocator = std::make_unique>( + m_fragment_constants_ring_info, + std::min(limits.maxUniformBufferRange / 16u, 8192u) + ); + if (m_texbuffer_view_size < 0x800000) { // Warn, only possibly expected on macOS @@ -2006,7 +2016,7 @@ void VKGSRender::load_program_env() usz mem_offset = 0; auto alloc_storage = [&](usz size) -> std::pair { - mem_offset = m_transform_constants_ring_info.alloc<256>(size); + mem_offset = m_transform_constants_allocator->alloc_bytes(size); return std::make_pair(m_transform_constants_ring_info.map(mem_offset, size), size); }; @@ -2028,7 +2038,7 @@ void VKGSRender::load_program_env() // Fragment constants if (fragment_constants_size) { - m_fragment_constants_dynamic_offset = m_fragment_constants_ring_info.alloc<256>(fragment_constants_size); + m_fragment_constants_dynamic_offset = m_fragment_constants_allocator->alloc_bytes(fragment_constants_size); auto buf = m_fragment_constants_ring_info.map(m_fragment_constants_dynamic_offset, fragment_constants_size); m_prog_buffer->fill_fragment_constants_buffer({ reinterpret_cast(buf), fragment_constants_size }, diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index a8a6bb6745..6b7ea5af13 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -162,6 +162,8 @@ private: u64 m_stipple_array_dynamic_offset = 0; std::unique_ptr> m_vertex_env_allocator; + std::unique_ptr> m_transform_constants_allocator; + std::unique_ptr> m_fragment_constants_allocator; std::vector m_frame_context_storage; u32 m_max_async_frames = 0u;