[PATCH 3/3] wined3d: Make the callers of surface_load_location responsible for preparing the destination location.
Stefan Dösinger
stefan at codeweavers.com
Tue Nov 3 16:55:14 CST 2015
The reason for making the callers of surface_blt_fbo responsible for
this as opposed to putting it in surface_blt_fbo is that most callers of
surface_blt_fbo are inside surface_load_location and thus already have
the destination prepared and check for a valid (and thus prepared)
source location.
---
dlls/wined3d/context.c | 1 +
dlls/wined3d/device.c | 10 ++++------
dlls/wined3d/drawprim.c | 10 ++--------
dlls/wined3d/surface.c | 25 +++++++++++++++++--------
dlls/wined3d/swapchain.c | 3 +++
5 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 978f7d7..35e560b 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2286,6 +2286,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n");
/* The currently active context is the necessary context to access the swapchain's onscreen buffers */
+ wined3d_surface_prepare(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB);
swapchain->render_to_fbo = TRUE;
swapchain_update_draw_bindings(swapchain);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 4806e3d..5d0aabf 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -322,10 +322,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(fb->render_targets[i]);
if (rt && rt->resource.format->id != WINED3DFMT_NULL)
{
+ wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding);
if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect))
surface_load_location(rt, context, rt->container->resource.draw_binding);
- else
- wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding);
}
}
@@ -4005,10 +4004,9 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
gl_info = context->gl_info;
/* Only load the surface for partial updates. */
- if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width
- && src_rect.bottom == sub_resource->height)
- wined3d_texture_prepare_texture(texture, context, FALSE);
- else
+ wined3d_texture_prepare_texture(texture, context, FALSE);
+ if (dst_point.x || dst_point.y || src_rect.right != sub_resource->width
+ || src_rect.bottom != sub_resource->height)
surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 3761830..b6c2718 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -625,15 +625,12 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]);
if (target && target->resource.format->id != WINED3DFMT_NULL)
{
+ wined3d_surface_prepare(target, context, target->container->resource.draw_binding);
if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
{
surface_load_location(target, context, target->container->resource.draw_binding);
surface_invalidate_location(target, ~target->container->resource.draw_binding);
}
- else
- {
- wined3d_surface_prepare(target, context, target->container->resource.draw_binding);
- }
}
}
@@ -648,6 +645,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
: WINED3D_LOCATION_DRAWABLE;
struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil);
+ wined3d_surface_prepare(ds, context, location);
if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE])
{
RECT current_rect, draw_rect, r;
@@ -665,11 +663,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co
IntersectRect(&r, &draw_rect, ¤t_rect);
if (!EqualRect(&r, &draw_rect))
surface_load_ds_location(ds, context, location);
- else
- wined3d_surface_prepare(ds, context, location);
}
- else
- wined3d_surface_prepare(ds, context, location);
}
if (!context_apply_draw_state(context, device))
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index beb0a8e..babde4b 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -721,6 +721,7 @@ static void surface_unmap(struct wined3d_surface *surface)
if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container)
{
context = context_acquire(device, surface);
+ wined3d_surface_prepare(surface, context, surface->container->resource.draw_binding);
surface_load_location(surface, context, surface->container->resource.draw_binding);
context_release(context);
}
@@ -786,11 +787,12 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device,
/* Make sure the locations are up-to-date. Loading the destination
* surface isn't required if the entire surface is overwritten. */
+ wined3d_surface_prepare(src_surface, context, dst_location);
surface_load_location(src_surface, context, src_location);
+
+ wined3d_surface_prepare(dst_surface, context, dst_location);
if (!surface_is_full_rect(dst_surface, dst_rect))
surface_load_location(dst_surface, context, dst_location);
- else
- wined3d_surface_prepare(dst_surface, context, dst_location);
gl_info = context->gl_info;
@@ -832,7 +834,9 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device,
}
/* Blit between surface locations. Onscreen on different swapchains is not supported.
- * Depth / stencil is not supported. Context activation is done by the caller. */
+ * Depth / stencil is not supported. Context activation is done by the caller.
+ *
+ * The caller is responsible for allocating src_location and dst_location. */
static void surface_blt_fbo(const struct wined3d_device *device,
struct wined3d_context *old_ctx, enum wined3d_texture_filter_type filter,
struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect_in,
@@ -1622,9 +1626,8 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
/* Only load the surface for partial updates. For newly allocated texture
* the texture wouldn't be the current location, and we'd upload zeroes
* just to overwrite them again. */
- if (update_w == dst_w && update_h == dst_h)
- wined3d_texture_prepare_texture(dst_surface->container, context, FALSE);
- else
+ wined3d_texture_prepare_texture(dst_surface->container, context, FALSE);
+ if (update_w != dst_w || update_h != dst_h)
surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB);
wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE);
@@ -1758,6 +1761,7 @@ void surface_load(struct wined3d_surface *surface, struct wined3d_context *conte
}
TRACE("Reloading because surface is dirty.\n");
+ wined3d_surface_prepare(surface, context, location);
surface_load_location(surface, context, location);
surface_evict_sysmem(surface);
}
@@ -2607,6 +2611,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
{
if (surface->flags & SFLAG_CLIENT)
{
+ /* WINED3D_LOCATION_SYSMEM is already prepared because of client storage. */
surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM);
surface_release_client_storage(surface);
}
@@ -2672,6 +2677,7 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
if (device->d3d_initialized)
context = context_acquire(device, NULL);
+ /* The map binding is already prepared either because it is user memory or PIN_SYSMEM is set. */
surface_load_location(surface, context, surface->resource.map_binding);
surface_invalidate_location(surface, WINED3D_LOCATION_DIB);
if (context)
@@ -3820,7 +3826,10 @@ static void surface_load_sysmem(struct wined3d_surface *surface,
}
if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
+ {
+ wined3d_surface_prepare(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
+ }
/* Download the surface to system memory. */
if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
@@ -3856,6 +3865,7 @@ static HRESULT surface_load_drawable(struct wined3d_surface *surface,
}
surface_get_rect(surface, NULL, &r);
+ wined3d_surface_prepare(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_blt_to_drawable(surface->resource.device, context,
WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r);
@@ -4092,8 +4102,6 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co
return WINED3DERR_DEVICELOST;
}
- wined3d_surface_prepare(surface, context, location);
-
switch (location)
{
case WINED3D_LOCATION_DIB:
@@ -5275,6 +5283,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
context = context_acquire(device, NULL);
+ wined3d_surface_prepare(src_surface, context, src_surface->container->resource.draw_binding);
wined3d_surface_prepare(dst_surface, context, dst_surface->container->resource.draw_binding);
surface_blt_fbo(device, context, filter,
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index e965bda..6ffd0fb 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -315,6 +315,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
if (backbuffer->resource.multisample_type)
{
location = WINED3D_LOCATION_RB_RESOLVED;
+ wined3d_surface_prepare(backbuffer, context, location);
surface_load_location(backbuffer, context, location);
}
@@ -517,6 +518,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT
*/
if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
+ wined3d_surface_prepare(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_load_location(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB);
surface_invalidate_location(back_buffer, WINED3D_LOCATION_DRAWABLE);
swapchain->render_to_fbo = TRUE;
@@ -524,6 +526,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT
}
else
{
+ wined3d_surface_prepare(back_buffer, context, back_buffer->container->resource.draw_binding);
surface_load_location(back_buffer, context, back_buffer->container->resource.draw_binding);
}
--
2.4.10
More information about the wine-patches
mailing list