[PATCH 04/10] wined3d: Keep track of a surface's "draw location".

Henri Verbeet hverbeet at codeweavers.com
Tue Aug 23 13:08:08 CDT 2011


We currently use surface locations in two different ways. On the one hand,
they're used for the actual locations. I.e., SFLAG_INSYSMEM for system memory,
SFLAG_INTEXTURE for the texture, etc. On the other hand, we also use them in
the sense of "whatever location is suitable for this usage". So we use e.g.
SFLAG_INTEXTURE if we want to texture from something, and SFLAG_INDRAWABLE if
we want to draw to something, even if the actual location we want to draw to
would be the texture. This works more or less ok since this is mainly an issue
for offscreen surfaces rendered using FBOs, which are never loaded into the GL
Drawable, so we just replace SFLAG_INDRAWABLE with SFLAG_INTEXTURE for
offscreen surfaces in that case. However, this would become very ugly if we
wanted to draw to a renderbuffer instead for some some surfaces. This patch is
the first step in separating the two concepts.
---
 dlls/wined3d/context.c         |    1 +
 dlls/wined3d/device.c          |    1 +
 dlls/wined3d/drawprim.c        |    6 +++---
 dlls/wined3d/surface.c         |    9 +++++++++
 dlls/wined3d/swapchain.c       |   13 +++++++++++++
 dlls/wined3d/wined3d_private.h |    3 +++
 6 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 9a67536..42d26bc 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1930,6 +1930,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context,
     /* The currently active context is the necessary context to access the swapchain's onscreen buffers */
     surface_load_location(context->current_rt, SFLAG_INTEXTURE, NULL);
     swapchain->render_to_fbo = TRUE;
+    swapchain_update_draw_bindings(swapchain);
     context_set_render_offscreen(context, TRUE);
 }
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 39219bf..cdc1827 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5880,6 +5880,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     stateblock_init_default_state(device->stateBlock);
 
     swapchain_update_render_to_fbo(swapchain);
+    swapchain_update_draw_bindings(swapchain);
 
     hr = create_primary_opengl_context(device, swapchain);
     wined3d_swapchain_decref(swapchain);
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 5f2198e..ea2dd8f 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -591,8 +591,8 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId
             struct wined3d_surface *target = device->fb.render_targets[i];
             if (target)
             {
-                surface_load_location(target, SFLAG_INDRAWABLE, NULL);
-                surface_modify_location(target, SFLAG_INDRAWABLE, TRUE);
+                surface_load_location(target, target->draw_binding, NULL);
+                surface_modify_location(target, target->draw_binding, TRUE);
             }
         }
     }
@@ -638,7 +638,7 @@ void drawPrimitive(struct wined3d_device *device, UINT index_count, UINT StartId
             if (state->render_states[WINED3DRS_ZWRITEENABLE])
             {
                 surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy);
-                surface_modify_location(ds, SFLAG_INDRAWABLE, TRUE);
+                surface_modify_location(ds, ds->draw_binding, TRUE);
             }
         }
     }
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 3cd424e..cc581d2 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -100,6 +100,14 @@ static void surface_cleanup(struct wined3d_surface *surface)
     resource_cleanup(&surface->resource);
 }
 
+void surface_update_draw_binding(struct wined3d_surface *surface)
+{
+    if (!surface_is_offscreen(surface) || wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+        surface->draw_binding = SFLAG_INDRAWABLE;
+    else
+        surface->draw_binding = SFLAG_INTEXTURE;
+}
+
 void surface_set_container(struct wined3d_surface *surface, enum wined3d_container_type type, void *container)
 {
     TRACE("surface %p, container %p.\n", surface, container);
@@ -131,6 +139,7 @@ void surface_set_container(struct wined3d_surface *surface, enum wined3d_contain
 
     surface->container.type = type;
     surface->container.u.base = container;
+    surface_update_draw_binding(surface);
 }
 
 struct blt_info
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 6edb043..20c2323 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -518,6 +518,7 @@ static HRESULT swapchain_gl_present(struct wined3d_swapchain *swapchain, const R
         surface_load_location(swapchain->back_buffers[0], SFLAG_INTEXTURE, NULL);
         surface_modify_location(swapchain->back_buffers[0], SFLAG_INDRAWABLE, FALSE);
         swapchain->render_to_fbo = TRUE;
+        swapchain_update_draw_bindings(swapchain);
     }
 
     if (swapchain->render_to_fbo)
@@ -1245,3 +1246,15 @@ HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain)
 
     return swapchain->backup_dc;
 }
+
+void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain)
+{
+    UINT i;
+
+    surface_update_draw_binding(swapchain->front_buffer);
+
+    for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
+    {
+        surface_update_draw_binding(swapchain->back_buffers[i]);
+    }
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 80517e3..754d49e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1996,6 +1996,7 @@ struct wined3d_surface
     struct wined3d_subresource_container container;
     struct wined3d_palette *palette; /* D3D7 style palette handling */
     PALETTEENTRY              *palette9; /* D3D8/9 style palette handling */
+    DWORD draw_binding;
 
     DWORD flags;
 
@@ -2080,6 +2081,7 @@ void surface_set_container(struct wined3d_surface *surface,
 void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
 void surface_set_texture_target(struct wined3d_surface *surface, GLenum target) DECLSPEC_HIDDEN;
 void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
+void surface_update_draw_binding(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
 void surface_upload_data(const struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
         const struct wined3d_format *format, const RECT *src_rect, UINT src_w, const POINT *dst_point,
         BOOL srgb, const struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
@@ -2442,6 +2444,7 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r
 struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
 
 #define DEFAULT_REFRESH_RATE 0
-- 
1.7.3.4




More information about the wine-patches mailing list