From: Matteo Bruni <mbruni@codeweavers.com> It matters a lot on Nvidia proprietary drivers, where binding to GL_UNIFORM_BUFFER makes a very significant difference. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56167 --- dlls/wined3d/context_gl.c | 16 ++++++++++------ dlls/wined3d/device.c | 18 +++++++++++++++--- dlls/wined3d/wined3d_gl.h | 1 + 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ee0335ca3c4..50ef9d25b50 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2664,6 +2664,7 @@ GLuint wined3d_context_gl_allocate_vram_chunk_buffer(struct wined3d_context_gl * { const struct wined3d_gl_info *gl_info = context_gl->gl_info; GLbitfield flags; + GLenum binding; GLuint id = 0; TRACE("context_gl %p, pool %u, size %Iu.\n", context_gl, pool, size); @@ -2674,12 +2675,13 @@ GLuint wined3d_context_gl_allocate_vram_chunk_buffer(struct wined3d_context_gl * checkGLcall("buffer object creation"); return 0; } - wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, id); + binding = wined3d_device_gl_get_memory_type_binding(pool); + wined3d_context_gl_bind_bo(context_gl, binding, id); flags = wined3d_device_gl_get_memory_type_flags(pool) | GL_DYNAMIC_STORAGE_BIT; if (flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) flags |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; - GL_EXTCALL(glBufferStorage(GL_PIXEL_UNPACK_BUFFER, size, NULL, flags)); + GL_EXTCALL(glBufferStorage(binding, size, NULL, flags)); checkGLcall("buffer object creation"); @@ -2701,14 +2703,15 @@ static void *wined3d_allocator_chunk_gl_map(struct wined3d_allocator_chunk_gl *c if (!chunk_gl->c.map_ptr) { unsigned int flags = wined3d_device_gl_get_memory_type_flags(chunk_gl->memory_type) & ~GL_CLIENT_STORAGE_BIT; + GLenum binding = wined3d_device_gl_get_memory_type_binding(chunk_gl->memory_type); flags |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; if (!(flags & GL_MAP_READ_BIT)) flags |= GL_MAP_UNSYNCHRONIZED_BIT; if (flags & GL_MAP_WRITE_BIT) flags |= GL_MAP_FLUSH_EXPLICIT_BIT; - wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer); - chunk_gl->c.map_ptr = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, + wined3d_context_gl_bind_bo(context_gl, binding, chunk_gl->gl_buffer); + chunk_gl->c.map_ptr = GL_EXTCALL(glMapBufferRange(binding, 0, WINED3D_ALLOCATOR_CHUNK_SIZE, flags)); if (!chunk_gl->c.map_ptr) { @@ -2731,6 +2734,7 @@ static void *wined3d_allocator_chunk_gl_map(struct wined3d_allocator_chunk_gl *c static void wined3d_allocator_chunk_gl_unmap(struct wined3d_allocator_chunk_gl *chunk_gl, struct wined3d_context_gl *context_gl) { + GLenum binding = wined3d_device_gl_get_memory_type_binding(chunk_gl->memory_type); const struct wined3d_gl_info *gl_info = context_gl->gl_info; TRACE("chunk_gl %p, context_gl %p.\n", chunk_gl, context_gl); @@ -2739,8 +2743,8 @@ static void wined3d_allocator_chunk_gl_unmap(struct wined3d_allocator_chunk_gl * if (!--chunk_gl->c.map_count) { - wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer); - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); + wined3d_context_gl_bind_bo(context_gl, binding, chunk_gl->gl_buffer); + GL_EXTCALL(glUnmapBuffer(binding)); chunk_gl->c.map_ptr = NULL; adapter_adjust_mapped_memory(context_gl->c.device->adapter, -WINED3D_ALLOCATOR_CHUNK_SIZE); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 974c195f76b..3feb7e0e4e2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1243,6 +1243,7 @@ static const struct wined3d_allocator_ops wined3d_allocator_gl_ops = static const struct { GLbitfield flags; + GLenum binding; } gl_memory_types[] = { @@ -1255,15 +1256,21 @@ gl_memory_types[] = {GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT}, {GL_CLIENT_STORAGE_BIT | GL_MAP_WRITE_BIT}, {GL_CLIENT_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT}, + + {0, GL_UNIFORM_BUFFER}, + {GL_MAP_READ_BIT, GL_UNIFORM_BUFFER}, + {GL_MAP_WRITE_BIT, GL_UNIFORM_BUFFER}, + {GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, GL_UNIFORM_BUFFER}, }; -static unsigned int wined3d_device_gl_find_memory_type(GLbitfield flags) +static unsigned int wined3d_device_gl_find_memory_type(GLbitfield flags, GLenum binding) { unsigned int i; for (i = 0; i < ARRAY_SIZE(gl_memory_types); ++i) { - if (gl_memory_types[i].flags == flags) + if (gl_memory_types[i].flags == flags + && (binding != GL_UNIFORM_BUFFER || gl_memory_types[i].binding == binding)) return i; } @@ -1276,6 +1283,11 @@ GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx) return gl_memory_types[memory_type_idx].flags; } +GLenum wined3d_device_gl_get_memory_type_binding(unsigned int memory_type_idx) +{ + return gl_memory_types[memory_type_idx].binding ? gl_memory_types[memory_type_idx].binding : GL_ARRAY_BUFFER; +} + static struct wined3d_allocator_block *wined3d_device_gl_allocate_memory(struct wined3d_device_gl *device_gl, struct wined3d_context_gl *context_gl, unsigned int memory_type, GLsizeiptr size, GLuint *id) { @@ -1336,7 +1348,7 @@ bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, struct win GLsizeiptr size, GLenum binding, GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo) { const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device_gl->d.adapter)->gl_info; - unsigned int memory_type_idx = wined3d_device_gl_find_memory_type(flags); + unsigned int memory_type_idx = wined3d_device_gl_find_memory_type(flags, binding); struct wined3d_allocator_block *memory = NULL; GLsizeiptr buffer_offset = 0; GLuint id = 0; diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 2c22c0a9c3c..00c82c7ac0a 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -920,6 +920,7 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object); void wined3d_device_gl_delete_opengl_contexts_cs(void *object); HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl); GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx); +GLenum wined3d_device_gl_get_memory_type_binding(unsigned int memory_type_idx); GLbitfield wined3d_resource_gl_map_flags(const struct wined3d_bo_gl *bo, DWORD d3d_flags); GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9811