From 8dc5b2717b8d6f03fea46dd3ba8c21785f0dcb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 17 Dec 2009 20:15:41 +0100 Subject: [PATCH 04/20] WineD3D: Set WINED3D_BUFFER_CREATEBO in buffer_init() --- dlls/wined3d/buffer.c | 40 +++++++++++++++++++++++++++++++++++++- dlls/wined3d/device.c | 42 ++++----------------------------------- dlls/wined3d/wined3d_private.h | 3 +- 3 files changed, 46 insertions(+), 39 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index b8c9df9..8a15445 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1066,10 +1066,12 @@ static const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, - const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) + const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops, + BOOL conversion_hint) { const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &device->adapter->gl_info); HRESULT hr; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; if (!size) { @@ -1091,6 +1093,42 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format_desc->format), buffer->resource.allocatedMemory, buffer); + /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + + * drawStridedFast (half-life 2 and others). + * + * Basically converting the vertices in the buffer is quite expensive, and observations + * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. + * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. + * + * Direct3D7 has another problem: Its vertexbuffer api doesn't offer a way to specify + * the range of vertices being locked, so each lock will require the whole buffer to be transformed. + * Moreover geometry data in dx7 is quite simple, so drawStridedSlow isn't a big hit. A plus + * is that the vertex buffers fvf can be trusted in dx7. So only create non-converted vbos for + * dx7 apps(WINED3DUSAGE_OPTIMIZE and conversion_hint). + * There is a IDirect3DVertexBuffer7::Optimize call after which the buffer can't be locked any + * more. In this call we can convert dx7 buffers too. + */ + if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) + { + TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n"); + } + else if(buffer->resource.pool == WINED3DPOOL_SYSTEMMEM) + { + TRACE("Not creating a vbo because the vertex buffer is in system memory\n"); + } + else if(buffer->resource.usage & WINED3DUSAGE_DYNAMIC) + { + TRACE("Not creating a vbo because the buffer has dynamic usage\n"); + } + else if(!(buffer->resource.usage & WINED3DUSAGE_OPTIMIZE) && conversion_hint) + { + TRACE("Not creating a vbo because the fvf needs conversion, but VB optimization is disabled\n"); + } + else + { + buffer->flags |= WINED3D_BUFFER_CREATEBO; + } + if (data) { BYTE *ptr; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1c0f43e..11fb77b 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -463,7 +463,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, str FIXME("Ignoring access flags (pool)\n"); hr = buffer_init(object, This, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN, - WINED3DPOOL_MANAGED, GL_ARRAY_BUFFER_ARB, data, parent, parent_ops); + WINED3DPOOL_MANAGED, GL_ARRAY_BUFFER_ARB, data, parent, parent_ops, FALSE); if (FAILED(hr)) { WARN("Failed to initialize buffer, hr %#x.\n", hr); @@ -506,8 +506,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac return WINED3DERR_OUTOFVIDEOMEMORY; } + conv = ((FVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) || (FVF & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR)); hr = buffer_init(object, This, Size, Usage, WINED3DFMT_VERTEXDATA, - Pool, GL_ARRAY_BUFFER_ARB, NULL, parent, parent_ops); + Pool, GL_ARRAY_BUFFER_ARB, NULL, parent, parent_ops, conv); if (FAILED(hr)) { WARN("Failed to initialize buffer, hr %#x.\n", hr); @@ -519,34 +520,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac TRACE("FVF %#x, Pool %#x.\n", FVF, Pool); *ppVertexBuffer = (IWineD3DBuffer *)object; - /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + - * drawStridedFast (half-life 2). - * - * Basically converting the vertices in the buffer is quite expensive, and observations - * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. - * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. - * - * Direct3D7 has another problem: Its vertexbuffer api doesn't offer a way to specify - * the range of vertices being locked, so each lock will require the whole buffer to be transformed. - * Moreover geometry data in dx7 is quite simple, so drawStridedSlow isn't a big hit. A plus - * is that the vertex buffers fvf can be trusted in dx7. So only create non-converted vbos for - * dx7 apps. - * There is a IDirect3DVertexBuffer7::Optimize call after which the buffer can't be locked any - * more. In this call we can convert dx7 buffers too. - */ - conv = ((FVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) || (FVF & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR)); - if (!This->adapter->gl_info.supported[ARB_VERTEX_BUFFER_OBJECT]) - { - 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(!(Usage & WINED3DUSAGE_OPTIMIZE) && conv) { - TRACE("Not creating a vbo because the fvf needs conversion, but VB optimization is disabled\n"); - } else { - object->flags |= WINED3D_BUFFER_CREATEBO; - } return WINED3D_OK; } @@ -570,7 +543,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface } hr = buffer_init(object, This, Length, Usage | WINED3DUSAGE_STATICDECL, - WINED3DFMT_UNKNOWN, Pool, GL_ELEMENT_ARRAY_BUFFER_ARB, NULL, parent, parent_ops); + WINED3DFMT_UNKNOWN, Pool, GL_ELEMENT_ARRAY_BUFFER_ARB, NULL, + parent, parent_ops, FALSE); if (FAILED(hr)) { WARN("Failed to initialize buffer, hr %#x\n", hr); @@ -580,12 +554,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface TRACE("Created buffer %p.\n", object); - if (Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) - && This->adapter->gl_info.supported[ARB_VERTEX_BUFFER_OBJECT]) - { - object->flags |= WINED3D_BUFFER_CREATEBO; - } - *ppIndexBuffer = (IWineD3DBuffer *) object; return WINED3D_OK; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b74868d..e5e0ae1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2382,7 +2382,8 @@ const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer BYTE *buffer_get_sysmem(struct wined3d_buffer *This) DECLSPEC_HIDDEN; HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, GLenum bind_hint, - const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + const char *data, IUnknown *parent, const struct wined3d_parent_ops *parent_ops, + BOOL conversion_hint) DECLSPEC_HIDDEN; /* IWineD3DRendertargetView */ struct wined3d_rendertarget_view -- 1.6.4.4