From 1691a6d7d0d763ccfda489a44fa3a1e7df223ad1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Thu, 11 Mar 2010 12:23:19 +0100 Subject: [PATCH] wined3d: Use glMapBuffer for 1:1 uploads in PreLoad. This is needed to take advantage of asynchronous uploads with double buffered buffers --- dlls/wined3d/buffer.c | 66 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 86d6fb4cd6..37c3feb527 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -766,6 +766,59 @@ static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) return resource_get_priority((IWineD3DResource *)iface); } +/* The caller provides a GL context */ +static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) +{ + BYTE *map; + UINT start = 0, len = 0; + + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + checkGLcall("glBindBufferARB"); + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GLbitfield mapflags; + mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; + map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, + This->resource.size, mapflags)); + checkGLcall("glMapBufferRange"); + } + else + { + map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB)); + checkGLcall("glMapBufferARB"); + } + if (!map) + { + LEAVE_GL(); + ERR("Failed to map opengl buffer\n"); + return; + } + + while(This->modified_areas) + { + This->modified_areas--; + start = This->maps[This->modified_areas].offset; + len = This->maps[This->modified_areas].size; + + memcpy(map + start, This->resource.allocatedMemory + start, len); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { + GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRange"); + } + else if (This->flags & WINED3D_BUFFER_FLUSH) + { + GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRangeAPPLE"); + } + } + GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + checkGLcall("glUnmapBufferARB"); + LEAVE_GL(); +} + static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; @@ -896,18 +949,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) return; } - ENTER_GL(); - GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBufferARB"); - while(This->modified_areas) - { - This->modified_areas--; - start = This->maps[This->modified_areas].offset; - len = This->maps[This->modified_areas].size; - GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, len, This->resource.allocatedMemory + start)); - checkGLcall("glBufferSubDataARB"); - } - LEAVE_GL(); + buffer_direct_upload(This, context->gl_info); context_release(context); return; -- 2.33.8