From 42aa4c5000f6d1023d8ef31be915983f540b989a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 12 Oct 2019 13:32:49 +0300 Subject: [PATCH] gl: Vendor-specific tuning --- rpcs3/Emu/RSX/GL/GLHelpers.h | 13 ++++++- rpcs3/Emu/RSX/GL/GLTextureCache.h | 58 ++++++++----------------------- 2 files changed, 27 insertions(+), 44 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 02e9b8bf83..d35fce0c7a 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -764,7 +764,8 @@ namespace gl void allocate(GLsizeiptr size, const void* data_, memory_type type, GLenum usage) { - if (get_driver_caps().ARB_buffer_storage_supported) + if (const auto& caps = get_driver_caps(); + caps.ARB_buffer_storage_supported) { target target_ = current_target(); save_binding_state save(target_, *this); @@ -789,6 +790,16 @@ namespace gl } } + if ((flags & GL_MAP_READ_BIT) && !caps.vendor_AMD) + { + // This flag stops NVIDIA from allocating read-only memory in VRAM. + // NOTE: On AMD, allocating client-side memory via CLIENT_STORAGE_BIT or + // making use of GL_AMD_pinned_memory brings everything down to a crawl. + // Afaict there is no reason for this; disabling pixel pack/unpack operations does not alleviate the problem. + // The driver seems to eventually figure out the optimal storage location by itself. + flags |= GL_CLIENT_STORAGE_BIT; + } + glBufferStorage((GLenum)target_, size, data_, flags); m_size = size; } diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 98c8c655db..729beb4c5c 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -50,8 +50,7 @@ namespace gl friend baseclass; fence m_fence; - u32 pbo_id = 0; - u32 pbo_size = 0; + buffer pbo; gl::viewable_image* vram_texture = nullptr; @@ -66,23 +65,16 @@ namespace gl const u32 vram_size = src->pitch() * src->height(); const u32 buffer_size = align(vram_size, 4096); - if (pbo_id) + if (pbo) { - if (pbo_size >= buffer_size) + if (pbo.size() >= buffer_size) return; - glDeleteBuffers(1, &pbo_id); - pbo_id = 0; - pbo_size = 0; + pbo.remove(); } - glGenBuffers(1, &pbo_id); - - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); - glBufferStorage(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_MAP_READ_BIT); + pbo.create(buffer::target::pixel_pack, buffer_size, nullptr, buffer::memory_type::host_visible, GL_STREAM_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE); - - pbo_size = buffer_size; } public: @@ -157,7 +149,7 @@ namespace gl init_buffer(src); glGetError(); - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); + pbo.bind(buffer::target::pixel_pack); if (context == rsx::texture_upload_context::dma) { @@ -179,7 +171,7 @@ namespace gl pixel_pack_settings pack_settings; pack_settings.alignment(1); - pack_settings.swap_bytes(pack_unpack_swap_bytes); + //pack_settings.swap_bytes(pack_unpack_swap_bytes); src->copy_to(nullptr, format, type, pack_settings); real_pitch = src->pitch(); @@ -276,25 +268,6 @@ namespace gl dma_transfer(cmd, target_texture, {}, {}, rsx_pitch); } - void fill_texture(gl::texture* tex) - { - if (!synchronized) - { - //LOG_WARNING(RSX, "Request to fill texture rejected because contents were not read"); - return; - } - - u32 min_width = std::min((u16)tex->width(), width); - u32 min_height = std::min((u16)tex->height(), height); - - glBindTexture(GL_TEXTURE_2D, tex->id()); - glPixelStorei(GL_UNPACK_SWAP_BYTES, pack_unpack_swap_bytes); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_id); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, min_width, min_height, (GLenum)format, (GLenum)type, nullptr); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE); - } - - /** * Flush */ @@ -304,8 +277,9 @@ namespace gl m_fence.wait_for_signal(); - verify(HERE), (offset + size) <= pbo_size; - glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); + verify(HERE), (offset + size) <= pbo.size(); + pbo.bind(buffer::target::pixel_pack); + return glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset, size, GL_MAP_READ_BIT); } @@ -373,21 +347,19 @@ namespace gl */ void destroy() { - if (!is_locked() && pbo_id == 0 && vram_texture == nullptr && m_fence.is_empty() && !managed_texture) + if (!is_locked() && !pbo && vram_texture == nullptr && m_fence.is_empty() && !managed_texture) //Already destroyed return; - if (pbo_id != 0) + if (pbo) { - //Destroy pbo cache since vram texture is managed elsewhere - glDeleteBuffers(1, &pbo_id); + // Destroy pbo cache since vram texture is managed elsewhere + pbo.remove(); scaled_texture.reset(); } - managed_texture.reset(); + managed_texture.reset(); vram_texture = nullptr; - pbo_id = 0; - pbo_size = 0; if (!m_fence.is_empty()) {