[PATCH 3/5] wined3d: Introduce "context_apply_state()" to setup a context for a specific usage.
Henri Verbeet
hverbeet at codeweavers.com
Sun Dec 27 12:57:21 CST 2009
---
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;
}
--
1.6.4.4
More information about the wine-patches
mailing list