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