Module: wine Branch: master Commit: 9295de9b841ad46a628f7e1d802f93b2ce4a73ee URL: http://source.winehq.org/git/wine.git/?a=commit;h=9295de9b841ad46a628f7e1d80...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Sun Dec 27 19:57:21 2009 +0100
wined3d: Introduce "context_apply_state()" to setup a context for a specific usage.
---
dlls/wined3d/context.c | 148 ++++++++++++++++++++++++------------------------ 1 files changed, 75 insertions(+), 73 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 30590af..797dd6b 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -2105,65 +2105,11 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) context->draw_buffer_dirty = TRUE; }
-/***************************************************************************** - * context_acquire - * - * Finds a rendering context and drawable matching the device and render - * target for the current thread, activates them and puts them into the - * requested state. - * - * Params: - * This: Device to activate the context for - * target: Requested render target - * usage: Prepares the context for blitting, drawing or other actions - * - *****************************************************************************/ -struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage) +/* Context activation is done by the caller. */ +static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, enum ContextUsage usage) { - struct wined3d_context *current_context = context_get_current(); - DWORD tid = GetCurrentThreadId(); - DWORD i, dirtyState, idx; - BYTE shift; - const struct StateEntry *StateTable = This->StateTable; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid); - - context = FindContext(This, target, tid); - context_enter(context); - if (!context->valid) return context; - - gl_info = context->gl_info; - - /* Activate the opengl context */ - if (context != current_context) - { - if (!context_set_current(context)) ERR("Failed to activate the new context.\n"); - else This->frag_pipe->enable_extension((IWineD3DDevice *)This, !context->last_was_blit); - - if (context->vshader_const_dirty) - { - memset(context->vshader_const_dirty, 1, - sizeof(*context->vshader_const_dirty) * This->d3d_vshader_constantF); - This->highest_dirty_vs_const = This->d3d_vshader_constantF; - } - if (context->pshader_const_dirty) - { - memset(context->pshader_const_dirty, 1, - sizeof(*context->pshader_const_dirty) * This->d3d_pshader_constantF); - This->highest_dirty_ps_const = This->d3d_pshader_constantF; - } - } - else if (context->restore_ctx) - { - if (!pwglMakeCurrent(context->hdc, context->glCtx)) - { - DWORD err = GetLastError(); - ERR("Failed to make GL context %p current on device context %p, last error %#x.\n", - context->hdc, context->glCtx, err); - } - } + const struct StateEntry *state_table = device->StateTable; + unsigned int i;
switch (usage) { case CTXUSAGE_CLEAR: @@ -2186,7 +2132,7 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n"); ENTER_GL(); context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); - context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, target); + context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt); context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE); LEAVE_GL(); } else { @@ -2215,7 +2161,7 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac
case CTXUSAGE_CLEAR: if(context->last_was_blit) { - This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE); + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); }
/* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling @@ -2224,32 +2170,33 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac ENTER_GL(); glDisable(GL_BLEND); LEAVE_GL(); - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
ENTER_GL(); glEnable(GL_SCISSOR_TEST); checkGLcall("glEnable GL_SCISSOR_TEST"); LEAVE_GL(); context->last_was_blit = FALSE; - Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable); - Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); + Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); + Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); break;
case CTXUSAGE_DRAWPRIM: /* This needs all dirty states applied */ if(context->last_was_blit) { - This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE); + device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); }
- IWineD3DDeviceImpl_FindTexUnitMap(This); + IWineD3DDeviceImpl_FindTexUnitMap(device);
ENTER_GL(); - for(i=0; i < context->numDirtyEntries; i++) { - dirtyState = context->dirtyArray[i]; - idx = dirtyState >> 5; - shift = dirtyState & 0x1f; + for (i = 0; i < context->numDirtyEntries; ++i) + { + DWORD rep = context->dirtyArray[i]; + DWORD idx = rep >> 5; + BYTE shift = rep & 0x1f; context->isStateDirty[idx] &= ~(1 << shift); - StateTable[dirtyState].apply(dirtyState, This->stateBlock, context); + state_table[rep].apply(rep, device->stateBlock, context); } LEAVE_GL(); context->numDirtyEntries = 0; /* This makes the whole list clean */ @@ -2257,14 +2204,69 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac break;
case CTXUSAGE_BLIT: - SetupForBlit(This, context, - ((IWineD3DSurfaceImpl *)target)->currentDesc.Width, - ((IWineD3DSurfaceImpl *)target)->currentDesc.Height); + SetupForBlit(device, context, + ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Width, + ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height); break;
default: FIXME("Unexpected context usage requested\n"); } +} + +/***************************************************************************** + * context_acquire + * + * Finds a rendering context and drawable matching the device and render + * target for the current thread, activates them and puts them into the + * requested state. + * + * Params: + * This: Device to activate the context for + * target: Requested render target + * usage: Prepares the context for blitting, drawing or other actions + * + *****************************************************************************/ +struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurface *target, enum ContextUsage usage) +{ + struct wined3d_context *current_context = context_get_current(); + struct wined3d_context *context; + + TRACE("device %p, target %p, usage %#x.\n", device, target, usage); + + context = FindContext(device, target, GetCurrentThreadId()); + context_enter(context); + if (!context->valid) return context; + + if (context != current_context) + { + if (!context_set_current(context)) ERR("Failed to activate the new context.\n"); + else device->frag_pipe->enable_extension((IWineD3DDevice *)device, !context->last_was_blit); + + if (context->vshader_const_dirty) + { + memset(context->vshader_const_dirty, 1, + sizeof(*context->vshader_const_dirty) * device->d3d_vshader_constantF); + device->highest_dirty_vs_const = device->d3d_vshader_constantF; + } + if (context->pshader_const_dirty) + { + memset(context->pshader_const_dirty, 1, + sizeof(*context->pshader_const_dirty) * device->d3d_pshader_constantF); + device->highest_dirty_ps_const = device->d3d_pshader_constantF; + } + } + else if (context->restore_ctx) + { + if (!pwglMakeCurrent(context->hdc, context->glCtx)) + { + DWORD err = GetLastError(); + ERR("Failed to make GL context %p current on device context %p, last error %#x.\n", + context->hdc, context->glCtx, err); + } + } + + context_apply_state(context, device, usage);
return context; }