diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 3a35c478537..85f6ca3884b 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 39a977fc367..1b5d7af86d2 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);