[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, &current_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