Commit be43c867 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Split context_apply_state() into separate functions for each usage.

parent b8b1a565
...@@ -1977,117 +1977,124 @@ static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device, struct ...@@ -1977,117 +1977,124 @@ static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device, struct
} }
/* Context activation is done by the caller. */ /* Context activation is done by the caller. */
static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, enum ContextUsage usage) static void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
{ {
const struct StateEntry *state_table = device->StateTable; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
unsigned int i; {
if (context->render_offscreen)
{
FIXME("Applying blit state for an offscreen target with ORM_FBO. This should be avoided.\n");
surface_internal_preload(context->current_rt, SRGB_RGB);
switch (usage) { ENTER_GL();
case CTXUSAGE_CLEAR: context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
case CTXUSAGE_DRAWPRIM: context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt);
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
if (!context->render_offscreen) context_validate_onscreen_formats(device, context); LEAVE_GL();
ENTER_GL(); }
context_apply_fbo_state(context); else
LEAVE_GL(); {
} context_validate_onscreen_formats(device, context);
if (context->draw_buffer_dirty) {
context_apply_draw_buffer(context, FALSE);
context->draw_buffer_dirty = FALSE;
}
break;
case CTXUSAGE_BLIT: ENTER_GL();
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
if (!context->render_offscreen) context_validate_onscreen_formats(device, context); LEAVE_GL();
if (context->render_offscreen) }
{
FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
surface_internal_preload(context->current_rt, SRGB_RGB);
ENTER_GL();
context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt);
context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
LEAVE_GL();
} else {
ENTER_GL();
context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
LEAVE_GL();
}
context->draw_buffer_dirty = TRUE;
}
if (context->draw_buffer_dirty) {
context_apply_draw_buffer(context, TRUE);
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
context->draw_buffer_dirty = FALSE;
}
}
break;
default: context->draw_buffer_dirty = TRUE;
break;
} }
switch(usage) { if (context->draw_buffer_dirty)
case CTXUSAGE_RESOURCELOAD: {
/* This does not require any special states to be set up */ context_apply_draw_buffer(context, TRUE);
break; if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
context->draw_buffer_dirty = FALSE;
}
case CTXUSAGE_CLEAR: SetupForBlit(device, context);
if(context->last_was_blit) { }
device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
}
/* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling /* Context activation is done by the caller. */
* blending when clearing improves the clearing performance incredibly. static void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
*/ {
ENTER_GL(); const struct StateEntry *state_table = device->StateTable;
glDisable(GL_BLEND);
LEAVE_GL();
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
ENTER_GL(); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
glEnable(GL_SCISSOR_TEST); {
checkGLcall("glEnable GL_SCISSOR_TEST"); if (!context->render_offscreen) context_validate_onscreen_formats(device, context);
LEAVE_GL(); ENTER_GL();
context->last_was_blit = FALSE; context_apply_fbo_state(context);
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table); LEAVE_GL();
Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table); }
break;
case CTXUSAGE_DRAWPRIM: if (context->draw_buffer_dirty)
/* This needs all dirty states applied */ {
if(context->last_was_blit) { context_apply_draw_buffer(context, FALSE);
device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE); context->draw_buffer_dirty = FALSE;
} }
IWineD3DDeviceImpl_FindTexUnitMap(device); if (context->last_was_blit)
device_preload_textures(device); {
if (isStateDirty(context, STATE_VDECL)) device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
device_update_stream_info(device, context->gl_info); }
ENTER_GL(); /* Blending and clearing should be orthogonal, but tests on the nvidia
for (i = 0; i < context->numDirtyEntries; ++i) * driver show that disabling blending when clearing improves the clearing
{ * performance incredibly. */
DWORD rep = context->dirtyArray[i]; ENTER_GL();
DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT); glDisable(GL_BLEND);
BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1); glEnable(GL_SCISSOR_TEST);
context->isStateDirty[idx] &= ~(1 << shift); checkGLcall("glEnable GL_SCISSOR_TEST");
state_table[rep].apply(rep, device->stateBlock, context); LEAVE_GL();
}
LEAVE_GL();
context->numDirtyEntries = 0; /* This makes the whole list clean */
context->last_was_blit = FALSE;
break;
case CTXUSAGE_BLIT: context->last_was_blit = FALSE;
SetupForBlit(device, context); Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
break; Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table);
Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table);
}
default: /* Context activation is done by the caller. */
FIXME("Unexpected context usage requested\n"); static void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
{
const struct StateEntry *state_table = device->StateTable;
unsigned int i;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
if (!context->render_offscreen) context_validate_onscreen_formats(device, context);
ENTER_GL();
context_apply_fbo_state(context);
LEAVE_GL();
}
if (context->draw_buffer_dirty)
{
context_apply_draw_buffer(context, FALSE);
context->draw_buffer_dirty = FALSE;
} }
if (context->last_was_blit)
{
device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
}
IWineD3DDeviceImpl_FindTexUnitMap(device);
device_preload_textures(device);
if (isStateDirty(context, STATE_VDECL))
device_update_stream_info(device, context->gl_info);
ENTER_GL();
for (i = 0; i < context->numDirtyEntries; ++i)
{
DWORD rep = context->dirtyArray[i];
DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
context->isStateDirty[idx] &= ~(1 << shift);
state_table[rep].apply(rep, device->stateBlock, context);
}
LEAVE_GL();
context->numDirtyEntries = 0; /* This makes the whole list clean */
context->last_was_blit = FALSE;
} }
static void context_setup_target(IWineD3DDeviceImpl *device, static void context_setup_target(IWineD3DDeviceImpl *device,
...@@ -2220,7 +2227,27 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, ...@@ -2220,7 +2227,27 @@ struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device,
} }
} }
context_apply_state(context, device, usage); switch (usage)
{
case CTXUSAGE_BLIT:
context_apply_blit_state(context, device);
break;
case CTXUSAGE_CLEAR:
context_apply_clear_state(context, device);
break;
case CTXUSAGE_DRAWPRIM:
context_apply_draw_state(context, device);
break;
case CTXUSAGE_RESOURCELOAD:
break;
default:
FIXME("Unexpected context usage requested.\n");
break;
}
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