From 92555b97ec3c43f604a7b3c9ead3df942fd1dbf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 15 Dec 2009 20:32:35 +0100 Subject: [PATCH 03/17] WineD3D: Prepare for dynamic vertex buffers Create them if the needed GL extensions are available, but don't convert. Even if the extensions are available, buffer conversion is usually too slow to make sense. Even without conversion, the classic VBO API doesn't have something similar to NOOVERWRITE locks, which makes VBOs much slower than drawing from sysmem. --- dlls/wined3d/buffer.c | 20 +++++++++++++------- dlls/wined3d/device.c | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index ff1ebd7..17ce8cb 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -730,15 +730,21 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) ++This->conversion_count; This->draw_count = 0; - if (This->conversion_count > VB_MAXDECLCHANGES) + if (This->conversion_count > VB_MAXDECLCHANGES || + (This->conversion_map && (This->resource.usage & WINED3DUSAGE_DYNAMIC))) { - FIXME("Too many declaration changes, stopping converting\n"); + FIXME("Too many declaration changes or converting dynamic buffer, stopping converting\n"); - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - This->buffer_object = 0; + buffer_get_sysmem(This); + /* buffer_get_sysmem can remove the BO from dynamic buffers */ + if(This->buffer_object) + { + ENTER_GL(); + GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); + checkGLcall("glDeleteBuffersARB"); + LEAVE_GL(); + This->buffer_object = 0; + } HeapFree(GetProcessHeap(), 0, This->conversion_shift); /* The stream source state handler might have read the memory of the vertex buffer already diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 0063aa9..c2cd64a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -444,6 +444,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetParent(IWineD3DDevice *iface, IUnkno return WINED3D_OK; } +static BOOL gl_support_dynamic_buffer(const struct wined3d_gl_info *gl_info) +{ + /* TODO: GL_APPLE_flush_buffer_range and GL_ARB_map_buffer_range */ + return FALSE; +} + static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, struct wined3d_buffer_desc *desc, const void *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops, IWineD3DBuffer **buffer) { @@ -487,6 +493,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac struct wined3d_buffer *object; HRESULT hr; BOOL conv; + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; if (Pool == WINED3DPOOL_SCRATCH) { @@ -540,8 +547,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n"); } else if(Pool == WINED3DPOOL_SYSTEMMEM) { TRACE("Not creating a vbo because the vertex buffer is in system memory\n"); - } else if(Usage & WINED3DUSAGE_DYNAMIC) { - TRACE("Not creating a vbo because the buffer has dynamic usage\n"); + } else if(!gl_support_dynamic_buffer(gl_info) && (Usage & WINED3DUSAGE_DYNAMIC)) { + TRACE("Not creating a vbo because the buffer has dynamic usage but GL doesn't support dynamic buffers\n"); } else if(!(Usage & WINED3DUSAGE_OPTIMIZE) && conv) { TRACE("Not creating a vbo because the fvf needs conversion, but VB optimization is disabled\n"); } else { @@ -557,6 +564,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct wined3d_buffer *object; HRESULT hr; + const struct wined3d_gl_info *gl_info = &This->adapter->gl_info; TRACE("(%p) Creating index buffer\n", This); @@ -580,7 +588,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface TRACE("Created buffer %p.\n", object); - if (Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) + if (Pool != WINED3DPOOL_SYSTEMMEM + && (gl_support_dynamic_buffer(gl_info) || !(Usage & WINED3DUSAGE_DYNAMIC)) && This->adapter->gl_info.supported[ARB_VERTEX_BUFFER_OBJECT]) { object->flags |= WINED3D_BUFFER_CREATEBO; -- 1.6.4.4