wined3d: Introduce "context_apply_state()" to setup a context for a specific usage.
This commit is contained in:
parent
f30999f193
commit
9295de9b84
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue