[PATCH] ddraw: Create a dynamic buffer if DDLOCK_DISCARDCONTENTS is used

Stefan Dösinger stefan at codeweavers.com
Mon Dec 3 16:11:36 CST 2012


D3d7 doesn't store vertex buffers anywhere, this makes recreating the
buffer feasible. The alternative is making all buffers dynamic, which
would disable color and POSITIONT conversion for d3d7 apps.
---
 dlls/ddraw/ddraw_private.h |    2 +
 dlls/ddraw/vertexbuffer.c  |   46 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 3a35c47..85f6ca3 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -527,6 +527,8 @@ struct d3d_vertex_buffer
     /*** Storage for D3D7 specific things ***/
     DWORD                Caps;
     DWORD                fvf;
+    DWORD                size;
+    BOOL                 dynamic;
 };
 
 HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **buffer, struct ddraw *ddraw,
diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c
index 39a977f..8c02b0a 100644
--- a/dlls/ddraw/vertexbuffer.c
+++ b/dlls/ddraw/vertexbuffer.c
@@ -185,6 +185,22 @@ static ULONG WINAPI d3d_vertex_buffer1_Release(IDirect3DVertexBuffer *iface)
  * IDirect3DVertexBuffer Methods
  *****************************************************************************/
 
+static HRESULT d3d_vertex_buffer_create_wined3d_buffer(struct d3d_vertex_buffer *buffer, BOOL dynamic,
+        struct wined3d_buffer **wined3d_buffer)
+{
+    DWORD usage = WINED3DUSAGE_STATICDECL;
+    DWORD pool = buffer->Caps & D3DVBCAPS_SYSTEMMEMORY ? WINED3D_POOL_SYSTEM_MEM : WINED3D_POOL_DEFAULT;
+
+    if (buffer->Caps & D3DVBCAPS_WRITEONLY)
+        usage |= WINED3DUSAGE_WRITEONLY;
+    if (dynamic)
+        usage |= WINED3DUSAGE_DYNAMIC;
+
+    return wined3d_buffer_create_vb(buffer->ddraw->wined3d_device,
+        buffer->size, usage, pool, buffer, &ddraw_null_wined3d_parent_ops,
+        wined3d_buffer);
+}
+
 /*****************************************************************************
  * IDirect3DVertexBuffer7::Lock
  *
@@ -225,8 +241,28 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface,
     if (flags & DDLOCK_NOOVERWRITE)
         wined3d_flags |= WINED3D_MAP_NOOVERWRITE;
     if (flags & DDLOCK_DISCARDCONTENTS)
+    {
         wined3d_flags |= WINED3D_MAP_DISCARD;
 
+        if (!buffer->dynamic)
+        {
+            struct wined3d_buffer *new_buffer;
+            wined3d_mutex_lock();
+            hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, TRUE, &new_buffer);
+            if (SUCCEEDED(hr))
+            {
+                buffer->dynamic = TRUE;
+                wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
+                buffer->wineD3DVertexBuffer = new_buffer;
+            }
+            else
+            {
+                WARN("Failed to create a dynamic buffer\n");
+            }
+            wined3d_mutex_unlock();
+        }
+    }
+
     wined3d_mutex_lock();
     if (data_size)
     {
@@ -534,7 +570,6 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf,
         struct ddraw *ddraw, D3DVERTEXBUFFERDESC *desc)
 {
     struct d3d_vertex_buffer *buffer;
-    DWORD usage;
     HRESULT hr = D3D_OK;
 
     TRACE("Vertex buffer description:\n");
@@ -554,16 +589,11 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf,
     buffer->ddraw = ddraw;
     buffer->Caps = desc->dwCaps;
     buffer->fvf = desc->dwFVF;
-
-    usage = desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0;
-    usage |= WINED3DUSAGE_STATICDECL;
+    buffer->size = get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices;
 
     wined3d_mutex_lock();
 
-    hr = wined3d_buffer_create_vb(ddraw->wined3d_device,
-            get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices,
-            usage, desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3D_POOL_SYSTEM_MEM : WINED3D_POOL_DEFAULT,
-            buffer, &ddraw_null_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
+    hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, FALSE, &buffer->wineD3DVertexBuffer);
     if (FAILED(hr))
     {
         WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr);
-- 
1.7.8.6




More information about the wine-patches mailing list