/***************************************************************************** * IDirect3DVertexBuffer7::Release * * Release for Vertex Buffers * * Returns: * The new refcount * *****************************************************************************/ static ULONG WINAPI IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface) { IDirect3DVertexBufferImpl *This = (IDirect3DVertexBufferImpl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", This, ref); if (ref == 0) { IWineD3DBuffer *curVB = NULL; UINT offset, stride; EnterCriticalSection(&ddraw_cs); /* D3D7 Vertex buffers don't stay bound in the device, they are passed as a parameter * to drawPrimitiveVB. DrawPrimitiveVB sets them as the stream source in wined3d, * and they should get unset there before they are destroyed */ IWineD3DDevice_GetStreamSource(This->ddraw->wineD3DDevice, 0 /* Stream number */, &curVB, &offset, &stride); if(curVB == This->wineD3DVertexBuffer) { IWineD3DDevice_SetStreamSource(This->ddraw->wineD3DDevice, 0 /* Steam number */, NULL /* stream data */, 0 /* Offset */, 0 /* stride */); } if(curVB) { IWineD3DBuffer_Release(curVB); /* For the GetStreamSource */ } IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration); IWineD3DBuffer_Release(This->wineD3DVertexBuffer); LeaveCriticalSection(&ddraw_cs); HeapFree(GetProcessHeap(), 0, This); return 0; } return ref; }
HRESULT d3d_vertex_buffer_init(IDirect3DVertexBufferImpl *buffer, IDirectDrawImpl *ddraw, D3DVERTEXBUFFERDESC *desc) { DWORD usage; HRESULT hr; buffer->lpVtbl = &d3d_vertex_buffer7_vtbl; buffer->IDirect3DVertexBuffer_vtbl = &d3d_vertex_buffer1_vtbl; buffer->ref = 1; buffer->ddraw = ddraw; buffer->Caps = desc->dwCaps; buffer->fvf = desc->dwFVF; usage = desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0; usage |= WINED3DUSAGE_STATICDECL; EnterCriticalSection(&ddraw_cs); hr = IWineD3DDevice_CreateVertexBuffer(ddraw->wineD3DDevice, get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices, usage, desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT, buffer, &ddraw_null_wined3d_parent_ops, &buffer->wineD3DVertexBuffer); if (FAILED(hr)) { WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr); LeaveCriticalSection(&ddraw_cs); if (hr == WINED3DERR_INVALIDCALL) return DDERR_INVALIDPARAMS; else return hr; } buffer->wineD3DVertexDeclaration = ddraw_find_decl(ddraw, desc->dwFVF); if (!buffer->wineD3DVertexDeclaration) { ERR("Failed to find vertex declaration for fvf %#x.\n", desc->dwFVF); IWineD3DBuffer_Release(buffer->wineD3DVertexBuffer); LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; } IWineD3DVertexDeclaration_AddRef(buffer->wineD3DVertexDeclaration); LeaveCriticalSection(&ddraw_cs); return D3D_OK; }
static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 iface) { IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; wined3d_mutex_lock(); IWineD3DBuffer_Release(This->wineD3DIndexBuffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(parentDevice); } return ref; }
static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface) { IDirect3DVertexBuffer9Impl *buffer = (IDirect3DVertexBuffer9Impl *)iface; ULONG refcount = InterlockedDecrement(&buffer->ref); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { IDirect3DDevice9Ex *device = buffer->parentDevice; wined3d_mutex_lock(); IWineD3DBuffer_Release(buffer->wineD3DVertexBuffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(device); } return refcount; }