Commit 9295de9b authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Introduce "context_apply_state()" to setup a context for a specific usage.

parent f30999f1
...@@ -2105,65 +2105,11 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) ...@@ -2105,65 +2105,11 @@ void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer)
context->draw_buffer_dirty = TRUE; context->draw_buffer_dirty = TRUE;
} }
/***************************************************************************** /* Context activation is done by the caller. */
* context_acquire static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, enum ContextUsage usage)
*
* 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)
{ {
struct wined3d_context *current_context = context_get_current(); const struct StateEntry *state_table = device->StateTable;
DWORD tid = GetCurrentThreadId(); unsigned int i;
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);
}
}
switch (usage) { switch (usage) {
case CTXUSAGE_CLEAR: case CTXUSAGE_CLEAR:
...@@ -2186,7 +2132,7 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac ...@@ -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"); FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
ENTER_GL(); ENTER_GL();
context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo); 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); context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
LEAVE_GL(); LEAVE_GL();
} else { } else {
...@@ -2215,7 +2161,7 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac ...@@ -2215,7 +2161,7 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac
case CTXUSAGE_CLEAR: case CTXUSAGE_CLEAR:
if(context->last_was_blit) { 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 /* 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 ...@@ -2224,32 +2170,33 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac
ENTER_GL(); ENTER_GL();
glDisable(GL_BLEND); glDisable(GL_BLEND);
LEAVE_GL(); LEAVE_GL();
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
ENTER_GL(); ENTER_GL();
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
checkGLcall("glEnable GL_SCISSOR_TEST"); checkGLcall("glEnable GL_SCISSOR_TEST");
LEAVE_GL(); LEAVE_GL();
context->last_was_blit = FALSE; context->last_was_blit = FALSE;
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table);
Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable); Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table);
break; break;
case CTXUSAGE_DRAWPRIM: case CTXUSAGE_DRAWPRIM:
/* This needs all dirty states applied */ /* This needs all dirty states applied */
if(context->last_was_blit) { 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(); ENTER_GL();
for(i=0; i < context->numDirtyEntries; i++) { for (i = 0; i < context->numDirtyEntries; ++i)
dirtyState = context->dirtyArray[i]; {
idx = dirtyState >> 5; DWORD rep = context->dirtyArray[i];
shift = dirtyState & 0x1f; DWORD idx = rep >> 5;
BYTE shift = rep & 0x1f;
context->isStateDirty[idx] &= ~(1 << shift); context->isStateDirty[idx] &= ~(1 << shift);
StateTable[dirtyState].apply(dirtyState, This->stateBlock, context); state_table[rep].apply(rep, device->stateBlock, context);
} }
LEAVE_GL(); LEAVE_GL();
context->numDirtyEntries = 0; /* This makes the whole list clean */ context->numDirtyEntries = 0; /* This makes the whole list clean */
...@@ -2257,14 +2204,69 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac ...@@ -2257,14 +2204,69 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurfac
break; break;
case CTXUSAGE_BLIT: case CTXUSAGE_BLIT:
SetupForBlit(This, context, SetupForBlit(device, context,
((IWineD3DSurfaceImpl *)target)->currentDesc.Width, ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Width,
((IWineD3DSurfaceImpl *)target)->currentDesc.Height); ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height);
break; break;
default: default:
FIXME("Unexpected context usage requested\n"); 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; return context;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment