Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- 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 e28b48e88d2..9ebaebab969 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 677286e981f..b4f512ed0af 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);