diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 51e5055c4ab..1f03833e0ed 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2550,6 +2550,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * unsigned int row_pitch, slice_pitch; struct wined3d_context *context; struct wined3d_bo_address addr; + unsigned int location; if (op->flags & ~WINED3D_BLT_RAW) { @@ -2582,11 +2583,16 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * context = context_acquire(cs->c.device, NULL, 0); + location = src_texture->resource.map_binding; + if (location == WINED3D_LOCATION_SYSMEM + && wined3d_texture_can_use_pbo(src_texture, &context->device->adapter->d3d_info)) + location = WINED3D_LOCATION_BUFFER; + if (!wined3d_texture_load_location(src_texture, op->src_sub_resource_idx, - context, src_texture->resource.map_binding)) + context, location)) { ERR("Failed to load source sub-resource into %s.\n", - wined3d_debug_location(src_texture->resource.map_binding)); + wined3d_debug_location(location)); context_release(context); goto error; } @@ -2607,7 +2613,7 @@ static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void * goto error; } - wined3d_texture_get_memory(src_texture, op->src_sub_resource_idx, &addr, src_texture->resource.map_binding); + wined3d_texture_get_memory(src_texture, op->src_sub_resource_idx, &addr, location); wined3d_texture_get_pitch(src_texture, op->src_sub_resource_idx % src_texture->level_count, &row_pitch, &slice_pitch); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index d3de37e75db..99a2efa1525 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -47,12 +47,20 @@ struct wined3d_rect_f float b; }; -static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_d3d_info *d3d_info) +BOOL wined3d_texture_can_use_pbo(const struct wined3d_texture *texture, const struct wined3d_d3d_info *d3d_info) { if (!d3d_info->pbo || texture->resource.format->conv_byte_count || (texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED))) return FALSE; + return TRUE; +} + +static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_d3d_info *d3d_info) +{ + if (!wined3d_texture_can_use_pbo(texture, d3d_info)) + return FALSE; + /* Use a PBO for dynamic textures and read-only staging textures. */ return (!(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU) && texture->resource.usage & WINED3DUSAGE_DYNAMIC) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index df9cfc284b9..85e8261e840 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4402,6 +4402,8 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +BOOL wined3d_texture_can_use_pbo(const struct wined3d_texture *texture, const struct wined3d_d3d_info *d3d_info) + DECLSPEC_HIDDEN; void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, HWND window, RECT *rect) DECLSPEC_HIDDEN;