gl: Vendor-specific tuning

This commit is contained in:
kd-11 2019-10-12 13:32:49 +03:00 committed by kd-11
commit 42aa4c5000
2 changed files with 27 additions and 44 deletions

View file

@ -764,7 +764,8 @@ namespace gl
void allocate(GLsizeiptr size, const void* data_, memory_type type, GLenum usage) 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(); target target_ = current_target();
save_binding_state save(target_, *this); 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); glBufferStorage((GLenum)target_, size, data_, flags);
m_size = size; m_size = size;
} }

View file

@ -50,8 +50,7 @@ namespace gl
friend baseclass; friend baseclass;
fence m_fence; fence m_fence;
u32 pbo_id = 0; buffer pbo;
u32 pbo_size = 0;
gl::viewable_image* vram_texture = nullptr; gl::viewable_image* vram_texture = nullptr;
@ -66,23 +65,16 @@ namespace gl
const u32 vram_size = src->pitch() * src->height(); const u32 vram_size = src->pitch() * src->height();
const u32 buffer_size = align(vram_size, 4096); const u32 buffer_size = align(vram_size, 4096);
if (pbo_id) if (pbo)
{ {
if (pbo_size >= buffer_size) if (pbo.size() >= buffer_size)
return; return;
glDeleteBuffers(1, &pbo_id); pbo.remove();
pbo_id = 0;
pbo_size = 0;
} }
glGenBuffers(1, &pbo_id); pbo.create(buffer::target::pixel_pack, buffer_size, nullptr, buffer::memory_type::host_visible, GL_STREAM_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id);
glBufferStorage(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_MAP_READ_BIT);
glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE); glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE);
pbo_size = buffer_size;
} }
public: public:
@ -157,7 +149,7 @@ namespace gl
init_buffer(src); init_buffer(src);
glGetError(); glGetError();
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); pbo.bind(buffer::target::pixel_pack);
if (context == rsx::texture_upload_context::dma) if (context == rsx::texture_upload_context::dma)
{ {
@ -179,7 +171,7 @@ namespace gl
pixel_pack_settings pack_settings; pixel_pack_settings pack_settings;
pack_settings.alignment(1); 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); src->copy_to(nullptr, format, type, pack_settings);
real_pitch = src->pitch(); real_pitch = src->pitch();
@ -276,25 +268,6 @@ namespace gl
dma_transfer(cmd, target_texture, {}, {}, rsx_pitch); 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 * Flush
*/ */
@ -304,8 +277,9 @@ namespace gl
m_fence.wait_for_signal(); m_fence.wait_for_signal();
verify(HERE), (offset + size) <= pbo_size; verify(HERE), (offset + size) <= pbo.size();
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); pbo.bind(buffer::target::pixel_pack);
return glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset, size, GL_MAP_READ_BIT); return glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset, size, GL_MAP_READ_BIT);
} }
@ -373,21 +347,19 @@ namespace gl
*/ */
void destroy() 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 //Already destroyed
return; return;
if (pbo_id != 0) if (pbo)
{ {
//Destroy pbo cache since vram texture is managed elsewhere // Destroy pbo cache since vram texture is managed elsewhere
glDeleteBuffers(1, &pbo_id); pbo.remove();
scaled_texture.reset(); scaled_texture.reset();
} }
managed_texture.reset();
managed_texture.reset();
vram_texture = nullptr; vram_texture = nullptr;
pbo_id = 0;
pbo_size = 0;
if (!m_fence.is_empty()) if (!m_fence.is_empty())
{ {