Henri Verbeet : d3d9: Avoid calling wined3d_device_process_vertices() with unmappable source buffers.

Alexandre Julliard julliard at winehq.org
Tue Jan 8 17:46:48 CST 2019


Module: wine
Branch: master
Commit: 36180aa1958273320630c85fd5d7dfc75c5ffb4b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=36180aa1958273320630c85fd5d7dfc75c5ffb4b

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Jan  8 19:52:47 2019 +0330

d3d9: Avoid calling wined3d_device_process_vertices() with unmappable source buffers.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3d9/device.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 dlls/d3d9/tests/visual.c |  4 ++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index e28b48e..9ebaeba 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -3082,15 +3082,55 @@ static HRESULT WINAPI d3d9_device_ProcessVertices(IDirect3DDevice9Ex *iface,
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct d3d9_vertexbuffer *dst_impl = unsafe_impl_from_IDirect3DVertexBuffer9(dst_buffer);
     struct d3d9_vertex_declaration *decl_impl = unsafe_impl_from_IDirect3DVertexDeclaration9(declaration);
+    struct d3d9_vertexbuffer *d3d9_buffer;
+    struct wined3d_buffer *wined3d_buffer;
+    unsigned int i, offset, stride, map;
     HRESULT hr;
 
     TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n",
             iface, src_start_idx, dst_idx, vertex_count, dst_buffer, declaration, flags);
 
     wined3d_mutex_lock();
+
+    /* Note that an alternative approach would be to simply create these
+     * buffers with WINED3D_RESOURCE_ACCESS_MAP_R and update them here like we
+     * do for draws. In some regards that would be easier, but it seems less
+     * than optimal to upload data to the GPU only to subsequently download it
+     * again. */
+    map = device->sysmem_vb;
+    while (map)
+    {
+        i = ffs(map) - 1;
+        map ^= 1u << i;
+
+        if (FAILED(wined3d_device_get_stream_source(device->wined3d_device,
+                i, &wined3d_buffer, &offset, &stride)))
+            ERR("Failed to get stream source.\n");
+        d3d9_buffer = wined3d_buffer_get_parent(wined3d_buffer);
+        if (FAILED(wined3d_device_set_stream_source(device->wined3d_device,
+                i, d3d9_buffer->wined3d_buffer, offset, stride)))
+            ERR("Failed to set stream source.\n");
+    }
+
     hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, vertex_count,
             dst_impl->wined3d_buffer, decl_impl ? decl_impl->wined3d_declaration : NULL,
             flags, dst_impl->fvf);
+
+    map = device->sysmem_vb;
+    while (map)
+    {
+        i = ffs(map) - 1;
+        map ^= 1u << i;
+
+        if (FAILED(wined3d_device_get_stream_source(device->wined3d_device,
+                i, &wined3d_buffer, &offset, &stride)))
+            ERR("Failed to get stream source.\n");
+        d3d9_buffer = wined3d_buffer_get_parent(wined3d_buffer);
+        if (FAILED(wined3d_device_set_stream_source(device->wined3d_device,
+                i, d3d9_buffer->draw_buffer, offset, stride)))
+            ERR("Failed to set stream source.\n");
+    }
+
     wined3d_mutex_unlock();
 
     return hr;
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 677286e..b4f512e 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -24327,12 +24327,12 @@ static void test_sysmem_draw(void)
             0, D3DFVF_XYZRHW, D3DPOOL_SYSTEMMEM, &dst_vb, NULL);
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DDevice9_ProcessVertices(device, 0, 0, ARRAY_SIZE(quad), dst_vb, NULL, 0);
-    todo_wine ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     hr = IDirect3DVertexBuffer9_Lock(dst_vb, 0, 0, (void **)&dst_data, 0);
     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
     for (i = 0; i < ARRAY_SIZE(quad); ++i)
     {
-        todo_wine ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
+        ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
                 -quad[i].position.y * 240.0f + 240.0f, 0.0f, 1.0f, 1),
                 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
                 i, dst_data[i].x, dst_data[i].y, dst_data[i].z, dst_data[i].w);




More information about the wine-cvs mailing list