From: Zebediah Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44863 --- dlls/ddraw/ddraw_private.h | 1 + dlls/ddraw/device.c | 4 ++-- dlls/ddraw/vertexbuffer.c | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 1f0c94a9c6e..7d08ffea361 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -595,6 +595,7 @@ struct d3d_vertex_buffer DWORD size; BOOL dynamic; bool discarded; + bool sysmem; };
HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **buffer, struct ddraw *ddraw, diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index f64db3aa633..a744d361bd7 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -4128,7 +4128,7 @@ static HRESULT d3d_device7_DrawPrimitiveVB(IDirect3DDevice7 *iface, D3DPRIMITIVE
stride = get_flexible_vertex_size(vb_impl->fvf);
- if (vb_impl->Caps & D3DVBCAPS_SYSTEMMEMORY) + if (vb_impl->sysmem) { TRACE("Drawing from D3DVBCAPS_SYSTEMMEMORY vertex buffer, forwarding to DrawPrimitive().\n"); wined3d_mutex_lock(); @@ -4246,7 +4246,7 @@ static HRESULT d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
vb_impl->discarded = false;
- if (vb_impl->Caps & D3DVBCAPS_SYSTEMMEMORY) + if (vb_impl->sysmem) { TRACE("Drawing from D3DVBCAPS_SYSTEMMEMORY vertex buffer, forwarding to DrawIndexedPrimitive().\n"); wined3d_mutex_lock(); diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index 73cf0a37991..c02d7e6e354 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -120,7 +120,7 @@ static HRESULT d3d_vertex_buffer_create_wined3d_buffer(struct d3d_vertex_buffer if (dynamic) desc.usage |= WINED3DUSAGE_DYNAMIC; desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER; - if (buffer->Caps & D3DVBCAPS_SYSTEMMEMORY) + if (buffer->sysmem) desc.access = WINED3D_RESOURCE_ACCESS_CPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; else desc.access = WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; @@ -466,6 +466,19 @@ HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf, buffer->fvf = desc->dwFVF; buffer->size = get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices;
+ /* ddraw4 vertex buffers ignore DISCARD and NOOVERWRITE, even on + * pretransformed geometry, which means that a GPU-based buffer cannot + * perform well. + * + * While at least one contemporaneous card (Geforce 4) does seem to show a + * difference in its performance characteristics based on whether + * D3DVBCAPS_SYSTEMMEMORY is set, it also doesn't *improve* performance to + * use a non-SYSTEMMEMORY buffer with ddraw4. For wined3d it should always + * be better to use sysmem. + * + * This improves performance in Prince of Persia 3D. */ + buffer->sysmem = ((buffer->Caps & D3DVBCAPS_SYSTEMMEMORY) || buffer->version < 7); + wined3d_mutex_lock();
if (FAILED(hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, FALSE, &buffer->wined3d_buffer)))