Module: wine Branch: master Commit: aa3a43f7698f7b0ac2e925e8da50fa9b1af77e6d URL: http://source.winehq.org/git/wine.git/?a=commit;h=aa3a43f7698f7b0ac2e925e8da...
Author: Stefan Dösinger stefan@codeweavers.com Date: Thu Aug 22 23:22:47 2013 +0200
wined3d: Don't lock the dst volume in device_update_volume.
---
dlls/wined3d/device.c | 27 +++++++++++++-------------- dlls/wined3d/volume.c | 36 +++++++++++++++++++++++++++--------- dlls/wined3d/wined3d_private.h | 3 +++ 3 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index fddf4da..ce0e083 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4092,29 +4092,28 @@ static HRESULT device_update_volume(struct wined3d_device *device, struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) { struct wined3d_map_desc src; - struct wined3d_map_desc dst; HRESULT hr; + struct wined3d_bo_address data; + struct wined3d_context *context;
TRACE("device %p, src_volume %p, dst_volume %p.\n", device, src_volume, dst_volume);
- /* TODO: Implement direct loading into the gl volume instead of using - * memcpy and dirtification to improve loading performance. */ if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) return hr; - if (FAILED(hr = wined3d_volume_map(dst_volume, &dst, NULL, WINED3D_MAP_DISCARD))) - { - wined3d_volume_unmap(src_volume); - return hr; - }
- memcpy(dst.data, src.data, dst_volume->resource.size); + context = context_acquire(device, NULL);
- hr = wined3d_volume_unmap(dst_volume); - if (FAILED(hr)) - wined3d_volume_unmap(src_volume); - else - hr = wined3d_volume_unmap(src_volume); + wined3d_volume_load(dst_volume, context, FALSE); + + data.buffer_object = 0; + data.addr = src.data; + wined3d_volume_upload_data(dst_volume, context, &data); + wined3d_volume_invalidate_location(dst_volume, ~WINED3D_LOCATION_TEXTURE_RGB); + + context_release(context); + + hr = wined3d_volume_unmap(src_volume);
return hr; } diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index d95fd91..71b2937 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -69,7 +69,7 @@ static void wined3d_volume_allocate_texture(const struct wined3d_volume *volume, }
/* Context activation is done by the caller. */ -static void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, +void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, const struct wined3d_bo_address *data) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -105,7 +105,7 @@ static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWOR TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); }
-static void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) +void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) { TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location)); volume->locations &= ~location; @@ -132,10 +132,31 @@ static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); }
+static DWORD volume_access_from_location(DWORD location) +{ + switch (location) + { + case WINED3D_LOCATION_DISCARDED: + return 0; + + case WINED3D_LOCATION_SYSMEM: + return WINED3D_RESOURCE_ACCESS_CPU; + + case WINED3D_LOCATION_TEXTURE_RGB: + return WINED3D_RESOURCE_ACCESS_GPU; + + default: + FIXME("Unhandled location %#x.\n", location); + return 0; + } +} + /* Context activation is done by the caller. */ static void wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) { + DWORD required_access = volume_access_from_location(location); + TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), wined3d_debug_location(volume->locations));
@@ -145,14 +166,11 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, return; }
- if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_GPU)) + if ((volume->resource.access_flags & required_access) != required_access) { - if (location & ~WINED3D_LOCATION_SYSMEM) - { - ERR("Trying to load a cpu-only access volume into %s.\n", - wined3d_debug_location(location)); - return; - } + ERR("Operation requires %#x access, but volume only has %#x.\n", + required_access, volume->resource.access_flags); + return; }
switch (location) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0bc84bf..71c50ef 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2077,6 +2077,9 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc
void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN; void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container) DECLSPEC_HIDDEN; +void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; +void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, + const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
struct wined3d_surface_dib {