Stefan Dösinger : wined3d: Move FBO application into a state handler.

Alexandre Julliard julliard at winehq.org
Tue Jul 5 12:59:07 CDT 2011


Module: wine
Branch: master
Commit: d321959dd7ba21b555f27d32937c911fa61117a6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d321959dd7ba21b555f27d32937c911fa61117a6

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sat Jul  2 11:24:37 2011 +0200

wined3d: Move FBO application into a state handler.

---

 dlls/wined3d/context.c         |  116 ++++++++++++++++++++++++---------------
 dlls/wined3d/state.c           |    3 +
 dlls/wined3d/utils.c           |    2 +
 dlls/wined3d/wined3d_private.h |    9 +++-
 4 files changed, 84 insertions(+), 46 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index c46b526..cddd5f0 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2161,79 +2161,96 @@ BOOL context_apply_clear_state(struct wined3d_context *context, struct wined3d_d
     return TRUE;
 }
 
-/* Context activation is done by the caller. */
-BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
+static inline DWORD find_draw_buffers_mask(struct wined3d_context *context, struct wined3d_device *device)
 {
-    const struct StateEntry *state_table = device->StateTable;
-    const struct wined3d_fb_state *fb = &device->fb;
+    struct wined3d_shader *ps = device->stateBlock->state.pixel_shader;
+    struct wined3d_surface **rts = device->fb.render_targets;
+    DWORD rt_mask, rt_mask_bits;
     unsigned int i;
-    DWORD rt_mask;
 
-    if (!context_validate_rt_config(context->gl_info->limits.buffers,
-            fb->render_targets, fb->depth_stencil))
-        return FALSE;
+    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return context_generate_rt_mask_no_fbo(device, rts[0]);
+    else if (!context->render_offscreen) return context_generate_rt_mask_from_surface(rts[0]);
 
-    /* Preload resources before FBO setup. Texture preload in particular may
-     * result in changes to the current FBO, due to using e.g. FBO blits for
-     * updating a resource location. */
-    device_update_tex_unit_map(device);
-    device_preload_textures(device);
-    if (isStateDirty(context, STATE_VDECL) || isStateDirty(context, STATE_STREAMSRC))
-        device_update_stream_info(device, context->gl_info);
+    rt_mask = ps ? ps->reg_maps.rt_mask : 1;
+    rt_mask &= device->valid_rt_mask;
+    rt_mask_bits = rt_mask;
+    i = 0;
+    while (rt_mask_bits)
+    {
+        rt_mask_bits &= ~(1 << i);
+        if (!rts[i] || rts[i]->resource.format->id == WINED3DFMT_NULL)
+            rt_mask &= ~(1 << i);
+
+        i++;
+    }
+
+    return rt_mask;
+}
+
+/* GL locking and context activation are done by the caller */
+void context_state_fb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
+{
+    struct wined3d_device *device = stateblock->device;
+    const struct wined3d_fb_state *fb = &device->fb;
+    DWORD rt_mask = find_draw_buffers_mask(context, device);
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
-        context_validate_onscreen_formats(device, context, fb->depth_stencil);
-
         if (!context->render_offscreen)
         {
-            ENTER_GL();
             context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, SFLAG_INDRAWABLE);
-            LEAVE_GL();
-            rt_mask = context_generate_rt_mask_from_surface(fb->render_targets[0]);
         }
         else
         {
-            const struct wined3d_shader *ps = device->stateBlock->state.pixel_shader;
-            DWORD rt_mask_bits;
-            struct wined3d_surface **rts = fb->render_targets;
-
-            ENTER_GL();
             context_apply_fbo_state(context, GL_FRAMEBUFFER, fb->render_targets, fb->depth_stencil, SFLAG_INTEXTURE);
             glReadBuffer(GL_NONE);
             checkGLcall("glReadBuffer");
-            LEAVE_GL();
-            rt_mask = ps ? ps->reg_maps.rt_mask : 1;
-            rt_mask &= device->valid_rt_mask;
-            rt_mask_bits = rt_mask;
-            i = 0;
-            while (rt_mask_bits)
-            {
-                rt_mask_bits &= ~(1 << i);
-                if (!rts[i] || rts[i]->resource.format->id == WINED3DFMT_NULL)
-                    rt_mask &= ~(1 << i);
-
-                i++;
-            }
         }
     }
-    else
-    {
-        rt_mask = context_generate_rt_mask_no_fbo(device, fb->render_targets[0]);
-    }
 
-    ENTER_GL();
     if (context->draw_buffers_mask != rt_mask)
     {
         context_apply_draw_buffers(context, rt_mask);
         context->draw_buffers_mask = rt_mask;
     }
+}
 
-    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+/* GL locking and context activation are done by the caller */
+void context_state_drawbuf(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
+{
+    DWORD rt_mask;
+    struct wined3d_device *device = stateblock->device;
+
+    if (isStateDirty(context, STATE_FRAMEBUFFER)) return;
+
+    rt_mask = find_draw_buffers_mask(context, device);
+    if (context->draw_buffers_mask != rt_mask)
     {
-        context_check_fbo_status(context, GL_FRAMEBUFFER);
+        context_apply_draw_buffers(context, rt_mask);
+        context->draw_buffers_mask = rt_mask;
     }
+}
 
+/* Context activation is done by the caller. */
+BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
+{
+    const struct StateEntry *state_table = device->StateTable;
+    const struct wined3d_fb_state *fb = &device->fb;
+    unsigned int i;
+
+    if (!context_validate_rt_config(context->gl_info->limits.buffers,
+            fb->render_targets, fb->depth_stencil))
+        return FALSE;
+
+    /* Preload resources before FBO setup. Texture preload in particular may
+     * result in changes to the current FBO, due to using e.g. FBO blits for
+     * updating a resource location. */
+    device_update_tex_unit_map(device);
+    device_preload_textures(device);
+    if (isStateDirty(context, STATE_VDECL) || isStateDirty(context, STATE_STREAMSRC))
+        device_update_stream_info(device, context->gl_info);
+
+    ENTER_GL();
     if (context->last_was_blit)
     {
         device->frag_pipe->enable_extension(TRUE);
@@ -2247,6 +2264,15 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
         context->isStateDirty[idx] &= ~(1 << shift);
         state_table[rep].apply(rep, device->stateBlock, context);
     }
+
+    /* FIXME */
+    state_table[STATE_FRAMEBUFFER].apply(STATE_FRAMEBUFFER, device->stateBlock, context);
+
+    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+    {
+        context_check_fbo_status(context, GL_FRAMEBUFFER);
+    }
+
     LEAVE_GL();
     context->numDirtyEntries = 0; /* This makes the whole list clean */
     context->last_was_blit = FALSE;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index ab6a7d7..3fe2ddf 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -5098,6 +5098,8 @@ const struct StateEntryTemplate misc_state_template[] = {
     { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, WINED3D_GL_EXT_NONE             },
     { STATE_BASEVERTEXINDEX,                              { STATE_BASEVERTEXINDEX,                              state_nop,          }, ARB_DRAW_ELEMENTS_BASE_VERTEX   },
     { STATE_BASEVERTEXINDEX,                              { STATE_STREAMSRC,                                    NULL,               }, WINED3D_GL_EXT_NONE             },
+    { STATE_FRAMEBUFFER,                                  { STATE_FRAMEBUFFER,                                  context_state_fb    }, WINED3D_GL_EXT_NONE             },
+    { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  context_state_drawbuf},WINED3D_GL_EXT_NONE             },
     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 
@@ -5761,6 +5763,7 @@ static void validate_state_table(struct StateEntry *state_table)
         STATE_FRONTFACE,
         STATE_POINTSPRITECOORDORIGIN,
         STATE_BASEVERTEXINDEX,
+        STATE_FRAMEBUFFER
     };
     unsigned int i, current;
 
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 25cb4ee..11a52b6 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -2249,6 +2249,8 @@ const char *debug_d3dstate(DWORD state)
         return "STATE_POINTSPRITECOORDORIGIN";
     if (STATE_IS_BASEVERTEXINDEX(state))
         return "STATE_BASEVERTEXINDEX";
+    if (STATE_IS_FRAMEBUFFER(state))
+        return "STATE_FRAMEBUFFER";
 
     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f4947f1..8f210d8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -998,7 +998,10 @@ extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC
 #define STATE_BASEVERTEXINDEX  (STATE_POINTSPRITECOORDORIGIN + 1)
 #define STATE_IS_BASEVERTEXINDEX(a) ((a) == STATE_BASEVERTEXINDEX)
 
-#define STATE_HIGHEST (STATE_BASEVERTEXINDEX)
+#define STATE_FRAMEBUFFER (STATE_BASEVERTEXINDEX + 1)
+#define STATE_IS_FRAMEBUFFER(a) ((a) == STATE_FRAMEBUFFER)
+
+#define STATE_HIGHEST (STATE_FRAMEBUFFER)
 
 enum fogsource {
     FOGSOURCE_FFP,
@@ -1243,6 +1246,10 @@ void context_resource_unloaded(const struct wined3d_device *device,
 BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
 void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
 void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
+void context_state_drawbuf(DWORD state, struct wined3d_stateblock *stateblock,
+        struct wined3d_context *context) DECLSPEC_HIDDEN;
+void context_state_fb(DWORD state, struct wined3d_stateblock *stateblock,
+        struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
 
 /*****************************************************************************




More information about the wine-cvs mailing list