Module: wine Branch: master Commit: 1691a6d7d0d763ccfda489a44fa3a1e7df223ad1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1691a6d7d0d763ccfda489a44f...
Author: Stefan Dösinger stefan@codeweavers.com Date: Thu Mar 11 12:23:19 2010 +0100
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 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 86d6fb4..37c3feb 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;