Stefan Dösinger : wined3d: Vertex buffer can be locked multiple times.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jun 27 15:49:11 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: cea41b0a0ff4a68c9c0507cdec604c142c493e53
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=cea41b0a0ff4a68c9c0507cdec604c142c493e53

Author: Stefan Dösinger <stefandoesinger at gmx.at>
Date:   Tue Jun 27 13:11:13 2006 +0200

wined3d: Vertex buffer can be locked multiple times.

---

 dlls/d3d8/tests/device.c       |   14 ++++++++++++++
 dlls/ddraw/vertexbuffer.c      |   20 +++++++++++---------
 dlls/wined3d/vertexbuffer.c    |   25 ++++++++++++++++++++++---
 dlls/wined3d/wined3d_private.h |    1 +
 4 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index f754fe1..d821340 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -267,6 +267,20 @@ static void test_refcount(void)
     hr = IDirect3DDevice8_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
     CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, refcount+1 );
 
+    if(pVertexBuffer)
+    {
+        BYTE *data;
+        /* Vertex buffers can be locked multiple times */
+        hr = IDirect3DVertexBuffer8_Lock(pVertexBuffer, 0, 0, &data, 0);
+        ok(hr == D3D_OK, "IDirect3DVertexBuffer8::Lock failed with %08lx\n", hr);
+        hr = IDirect3DVertexBuffer8_Lock(pVertexBuffer, 0, 0, &data, 0);
+        ok(hr == D3D_OK, "IDirect3DVertexBuffer8::Lock failed with %08lx\n", hr);
+        hr = IDirect3DVertexBuffer8_Unlock(pVertexBuffer);
+        ok(hr == D3D_OK, "IDirect3DVertexBuffer8::Unlock failed with %08lx\n", hr);
+        hr = IDirect3DVertexBuffer8_Unlock(pVertexBuffer);
+        ok(hr == D3D_OK, "IDirect3DVertexBuffer8::Unlock failed with %08lx\n", hr);
+    }
+
 cleanup:
     if (pDevice)              IUnknown_Release( pDevice );
 
diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c
index a24bfc4..01db5d5 100644
--- a/dlls/ddraw/vertexbuffer.c
+++ b/dlls/ddraw/vertexbuffer.c
@@ -214,20 +214,22 @@ IDirect3DVertexBufferImpl_Lock(IDirect3D
     HRESULT hr;
     TRACE("(%p)->(%08lx,%p,%p)\n", This, Flags, Data, Size);
 
-    /* Get the size, for returning it, and for locking */
-    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
-                                      &Desc);
-    if(hr != D3D_OK)
+    if(*Size)
     {
-        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr);
-        return hr;
+        /* Get the size, for returning it, and for locking */
+        hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
+                                          &Desc);
+        if(hr != D3D_OK)
+        {
+            ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr);
+            return hr;
+        }
+        *Size = Desc.Size;
     }
 
-    if(Size) *Size = Desc.Size;
-
     return IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer,
                                      0 /* OffsetToLock */,
-                                     Desc.Size,
+                                     0 /* SizeToLock, 0 == Full lock */,
                                      (BYTE **) Data,
                                      Flags);
 }
diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c
index c669a6b..b58591c 100644
--- a/dlls/wined3d/vertexbuffer.c
+++ b/dlls/wined3d/vertexbuffer.c
@@ -145,8 +145,9 @@ static void     WINAPI IWineD3DVertexBuf
                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
                 checkGLcall("glBindBufferARB");
                 GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
-                checkGLcall("glUnmapBuffer glBufferSubDataARB");
+                checkGLcall("glBufferSubDataARB");
                 LEAVE_GL();
+                /* Lock directly into the VBO in the future */
                 HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
                 This->resource.allocatedMemory = NULL;
                 This->Flags &= ~VBFLAG_DIRTY;
@@ -334,12 +335,21 @@ static HRESULT  WINAPI IWineD3DVertexBuf
     BYTE *data;
     TRACE("(%p)->%d, %d, %p, %08lx\n", This, OffsetToLock, SizeToLock, ppbData, Flags);
 
+    InterlockedIncrement(&This->lockcount);
+
     if(This->Flags & VBFLAG_DIRTY) {
         if(This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
-        if(This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
+        if(SizeToLock) {
+            if(This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
+        } else {
+            This->dirtyend = This->resource.size;
+        }
     } else {
         This->dirtystart = OffsetToLock;
-        This->dirtyend = OffsetToLock + SizeToLock;
+        if(SizeToLock)
+            This->dirtyend = OffsetToLock + SizeToLock;
+        else
+            This->dirtyend = OffsetToLock + This->resource.size;
     }
 
     if(This->resource.allocatedMemory) {
@@ -375,7 +385,16 @@ static HRESULT  WINAPI IWineD3DVertexBuf
 }
 HRESULT  WINAPI IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) {
     IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
+    LONG lockcount;
     TRACE("(%p)\n", This);
+
+    lockcount = InterlockedDecrement(&This->lockcount);
+    if(lockcount > 0) {
+        /* Delay loading the buffer until everything is unlocked */
+        TRACE("Ignoring the unlock\n");
+        return D3D_OK;
+    }
+
     if(!This->resource.allocatedMemory) {
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index cbb92f5..d55b810 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -633,6 +633,7 @@ typedef struct IWineD3DVertexBufferImpl
     UINT                      stream;
 
     UINT                      dirtystart, dirtyend;
+    LONG                      lockcount;
 
     /* Last description of the buffer */
     WineDirect3DVertexStridedData strided;




More information about the wine-cvs mailing list