Module: wine Branch: master Commit: d321959dd7ba21b555f27d32937c911fa61117a6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d321959dd7ba21b555f27d3293...
Author: Stefan Dösinger stefan@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;
/*****************************************************************************