diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index e928493f4b..f382061c58 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -509,7 +509,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) // This first set is bound persistently, so grow notifications are enabled. m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_default, "attrib buffer", 0x400000, VK_TRUE); m_fragment_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_low_latency, "fragment env buffer", 0x10000, VK_TRUE); - m_vertex_env_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_low_latency, "vertex env buffer", 0x10000, VK_TRUE); + m_vertex_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_default, "vertex env buffer", 0x10000, VK_TRUE); m_fragment_texture_params_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_low_latency, "fragment texture params buffer", 0x10000, VK_TRUE); m_vertex_layout_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_low_latency, "vertex layout buffer", 0x10000, VK_TRUE); m_fragment_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, vk::heap_pool_low_latency, "fragment constants buffer", 0x10000, VK_TRUE); @@ -563,6 +563,11 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) const auto& limits = m_device->gpu().get_limits(); m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000u); + // Initialize bulk allocators + m_vertex_env_allocator = std::make_unique>( + m_vertex_env_ring_info, + std::min(limits.maxUniformBufferRange / 96u, 1024u)); + if (m_texbuffer_view_size < 0x800000) { // Warn, only possibly expected on macOS @@ -1951,7 +1956,9 @@ void VKGSRender::load_program_env() if (update_vertex_env) { // Vertex state. Note, we're now on std430 alignment here, not hardware alignment. - const auto [mem, buf] = m_vertex_env_ring_info.alloc_and_map<16, char>(96); + // Use the bulk allocator here + const auto mem = m_vertex_env_allocator->alloc(); + auto buf = m_vertex_env_ring_info.map(mem, 96); m_draw_processor.fill_scale_offset_data(buf, false); m_draw_processor.fill_user_clip_data(buf + 64); @@ -1962,6 +1969,9 @@ void VKGSRender::load_program_env() m_vertex_env_ring_info.unmap(); m_vertex_env_dynamic_offset = mem; + + m_vertex_env_buffer_info = m_vertex_env_ring_info.window<256>(m_vertex_env_dynamic_offset, 96, gpu_limits.maxUniformBufferRange); + m_vertex_env_dynamic_offset -= m_vertex_env_buffer_info.offset; } if (update_instancing_data) @@ -2288,6 +2298,11 @@ void VKGSRender::patch_transform_constants(rsx::context* /*ctx*/, u32 index, u32 rsx::io_buffer iobuf(allocate_mem); upload_transform_constants(iobuf); + + if (!iobuf.empty()) + { + m_transform_constants_ring_info.unmap(); + } } void VKGSRender::init_buffers(rsx::framebuffer_creation_context context, bool) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index da1491afcc..a8a6bb6745 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -161,6 +161,8 @@ private: u64 m_texture_parameters_dynamic_offset = 0; u64 m_stipple_array_dynamic_offset = 0; + std::unique_ptr> m_vertex_env_allocator; + std::vector m_frame_context_storage; u32 m_max_async_frames = 0u; // Temp frame context to use if the real frame queue is overburdened. Only used for storage diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index 375d35e942..0186045dd1 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -75,6 +75,8 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) OS << "#version 450\n\n" + "#extension GL_EXT_scalar_block_layout : require\n" + "#extension GL_EXT_uniform_buffer_unsized_array : require\n" "#extension GL_ARB_separate_shader_objects : enable\n\n"; glsl::insert_subheader_block(OS); @@ -88,7 +90,7 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) "#define get_user_clip_config() get_vertex_context().user_clip_configuration_bits\n\n"; OS << - "layout(std430, set=0, binding=" << vk_prog->binding_table.context_buffer_location << ") readonly restrict buffer VertexContextBuffer\n" + "layout(std430, set=0, binding=" << vk_prog->binding_table.context_buffer_location << ") uniform VertexContextBuffer\n" "{\n" " vertex_context_t vertex_contexts[];\n" "};\n\n"; @@ -96,7 +98,7 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) const vk::glsl::program_input context_input { .domain = glsl::glsl_vertex_program, - .type = vk::glsl::input_type_storage_buffer, + .type = vk::glsl::input_type_uniform_buffer, .set = vk::glsl::binding_set_index_vertex, .location = vk_prog->binding_table.context_buffer_location, .name = "VertexContextBuffer"