[PATCH] ddraw: Create a dynamic buffer if DDLOCK_DISCARDCONTENTS is used (try 2)

Stefan Dösinger stefan at codeweavers.com
Tue Dec 4 02:36:16 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.

Try 2: use enum wined3d_pool instead of DWORD.
---
 dlls/ddraw/ddraw_private.h |    2 +
 dlls/ddraw/vertexbuffer.c  |   51 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 45 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..1b5d7af 100644
--- a/dlls/ddraw/vertexbuffer.c
+++ b/dlls/ddraw/vertexbuffer.c
@@ -185,6 +185,27 @@ 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;
+    enum wined3d_pool pool;
+
+    if (buffer->Caps & D3DVBCAPS_SYSTEMMEMORY)
+        pool = WINED3D_POOL_SYSTEM_MEM;
+    else
+        pool = 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 +246,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 +575,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 +594,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