wined3d: Vertex buffer can be locked multiple times.

This commit is contained in:
Stefan Dösinger 2006-06-27 13:11:13 +02:00 committed by Alexandre Julliard
parent 54c85d3d04
commit cea41b0a0f
4 changed files with 48 additions and 12 deletions

View File

@ -267,6 +267,20 @@ static void test_refcount(void)
hr = IDirect3DDevice8_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain ); hr = IDirect3DDevice8_CreateAdditionalSwapChain( pDevice, &d3dpp, &pSwapChain );
CHECK_CALL( hr, "CreateAdditionalSwapChain", pDevice, refcount+1 ); 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: cleanup:
if (pDevice) IUnknown_Release( pDevice ); if (pDevice) IUnknown_Release( pDevice );

View File

@ -214,20 +214,22 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface,
HRESULT hr; HRESULT hr;
TRACE("(%p)->(%08lx,%p,%p)\n", This, Flags, Data, Size); TRACE("(%p)->(%08lx,%p,%p)\n", This, Flags, Data, Size);
/* Get the size, for returning it, and for locking */ if(*Size)
hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
&Desc);
if(hr != D3D_OK)
{ {
ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr); /* Get the size, for returning it, and for locking */
return hr; 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, return IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer,
0 /* OffsetToLock */, 0 /* OffsetToLock */,
Desc.Size, 0 /* SizeToLock, 0 == Full lock */,
(BYTE **) Data, (BYTE **) Data,
Flags); Flags);
} }

View File

@ -145,8 +145,9 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
checkGLcall("glBindBufferARB"); checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory)); GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
checkGLcall("glUnmapBuffer glBufferSubDataARB"); checkGLcall("glBufferSubDataARB");
LEAVE_GL(); LEAVE_GL();
/* Lock directly into the VBO in the future */
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory); HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
This->resource.allocatedMemory = NULL; This->resource.allocatedMemory = NULL;
This->Flags &= ~VBFLAG_DIRTY; This->Flags &= ~VBFLAG_DIRTY;
@ -334,12 +335,21 @@ static HRESULT WINAPI IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface
BYTE *data; BYTE *data;
TRACE("(%p)->%d, %d, %p, %08lx\n", This, OffsetToLock, SizeToLock, ppbData, Flags); TRACE("(%p)->%d, %d, %p, %08lx\n", This, OffsetToLock, SizeToLock, ppbData, Flags);
InterlockedIncrement(&This->lockcount);
if(This->Flags & VBFLAG_DIRTY) { if(This->Flags & VBFLAG_DIRTY) {
if(This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock; 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 { } else {
This->dirtystart = OffsetToLock; This->dirtystart = OffsetToLock;
This->dirtyend = OffsetToLock + SizeToLock; if(SizeToLock)
This->dirtyend = OffsetToLock + SizeToLock;
else
This->dirtyend = OffsetToLock + This->resource.size;
} }
if(This->resource.allocatedMemory) { if(This->resource.allocatedMemory) {
@ -375,7 +385,16 @@ static HRESULT WINAPI IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface
} }
HRESULT WINAPI IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) { HRESULT WINAPI IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) {
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface; IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
LONG lockcount;
TRACE("(%p)\n", This); 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) { if(!This->resource.allocatedMemory) {
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo)); GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));

View File

@ -633,6 +633,7 @@ typedef struct IWineD3DVertexBufferImpl
UINT stream; UINT stream;
UINT dirtystart, dirtyend; UINT dirtystart, dirtyend;
LONG lockcount;
/* Last description of the buffer */ /* Last description of the buffer */
WineDirect3DVertexStridedData strided; WineDirect3DVertexStridedData strided;