wined3d: Avoid looking up shaders for shader stages that didn't change.

This commit is contained in:
Henri Verbeet 2013-08-21 08:29:27 +02:00 committed by Alexandre Julliard
parent 251160fef9
commit 62859daf0b
6 changed files with 98 additions and 65 deletions

View File

@ -6493,7 +6493,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
}
else if (use_pshader)
{
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
return;
}
@ -6543,7 +6543,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
context->last_was_pshader = TRUE;
}
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
/* We can't link the fog states to the fragment state directly since the

View File

@ -942,7 +942,7 @@ static void atifs_apply_pixelshader(struct wined3d_context *context, const struc
* startup, and blitting disables all shaders and dirtifies all shader
* states. If atifs can deal with this it keeps the rest of the code
* simpler. */
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void atifs_srgbwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)

View File

@ -1624,7 +1624,9 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
{
GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
}
ret->select_shader = 1;
ret->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
| (1 << WINED3D_SHADER_TYPE_VERTEX)
| (1 << WINED3D_SHADER_TYPE_GEOMETRY);
/* If this happens to be the first context for the device, dummy textures
* are not created yet. In that case, they will be created (and bound) by
@ -1901,7 +1903,9 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
/* Disable shaders */
device->shader_backend->shader_disable(device->shader_priv, context);
context->select_shader = 1;
context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
| (1 << WINED3D_SHADER_TYPE_VERTEX)
| (1 << WINED3D_SHADER_TYPE_GEOMETRY);
context->blit_w = rt_size.cx;
context->blit_h = rt_size.cy;
@ -2379,10 +2383,10 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
state_table[rep].apply(context, state, rep);
}
if (context->select_shader)
if (context->shader_update_mask)
{
device->shader_backend->shader_select(device->shader_priv, context, state);
context->select_shader = 0;
context->shader_update_mask = 0;
}
if (context->constant_update_mask)

View File

@ -5843,23 +5843,40 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
GLhandleARB programId = 0;
GLhandleARB reorder_shader_id = 0;
unsigned int i;
struct ps_compile_args ps_compile_args;
struct vs_compile_args vs_compile_args;
GLhandleARB vs_id, gs_id, ps_id;
GLhandleARB vs_id = 0;
GLhandleARB gs_id = 0;
GLhandleARB ps_id = 0;
struct list *ps_list, *vs_list;
struct wined3d_device *device = context->swapchain->device;
if (use_vs(state))
if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_VERTEX)))
{
vs_id = priv->glsl_program->vs.id;
vs_list = &priv->glsl_program->vs.shader_entry;
if (use_vs(state))
{
vshader = state->vertex_shader;
gshader = state->geometry_shader;
if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_GEOMETRY))
&& priv->glsl_program->gs.id)
gs_id = priv->glsl_program->gs.id;
else if (gshader)
gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader);
}
}
else if (use_vs(state))
{
struct vs_compile_args vs_compile_args;
vshader = state->vertex_shader;
find_vs_compile_args(state, vshader, &vs_compile_args);
vs_id = find_glsl_vshader(context, &priv->shader_buffer, vshader, &vs_compile_args);
vs_list = &vshader->linked_programs;
if ((gshader = state->geometry_shader))
gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader);
else
gs_id = 0;
}
else if (priv->vertex_pipe == &glsl_vertex_pipe)
{
@ -5870,17 +5887,19 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings);
vs_id = ffp_shader->id;
vs_list = &ffp_shader->linked_programs;
gs_id = 0;
}
else
{
vs_id = 0;
gs_id = 0;
}
if (use_ps(state))
if (!(context->shader_update_mask & (1 << WINED3D_SHADER_TYPE_PIXEL)))
{
ps_id = priv->glsl_program->ps.id;
ps_list = &priv->glsl_program->ps.shader_entry;
if (use_ps(state))
pshader = state->pixel_shader;
}
else if (use_ps(state))
{
struct ps_compile_args ps_compile_args;
pshader = state->pixel_shader;
find_ps_compile_args(state, pshader, &ps_compile_args);
ps_id = find_glsl_pshader(context, &priv->shader_buffer,
@ -5897,10 +5916,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
ps_id = ffp_shader->id;
ps_list = &ffp_shader->linked_programs;
}
else
{
ps_id = 0;
}
if ((!vs_id && !gs_id && !ps_id) || (entry = get_glsl_program_entry(priv, vs_id, gs_id, ps_id)))
{
@ -6320,6 +6335,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
struct glsl_shader_private *shader_data = shader->backend_data;
struct wined3d_device *device = shader->device;
struct shader_glsl_priv *priv = device->shader_priv;
BOOL invalidate_current_program = FALSE;
const struct wined3d_gl_info *gl_info;
const struct list *linked_programs;
struct wined3d_context *context;
@ -6347,22 +6363,22 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
{
struct glsl_ps_compiled_shader *gl_shaders = shader_data->gl_shaders.ps;
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting pixel shader %u.\n", gl_shaders[i].prgId);
if (priv->glsl_program && priv->glsl_program->ps.id == gl_shaders[i].prgId)
invalidate_current_program = TRUE;
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps);
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
struct glsl_shader_prog_link, ps.shader_entry)
{
delete_glsl_program_entry(priv, gl_info, entry);
}
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting pixel shader %u.\n", gl_shaders[i].prgId);
if (priv->glsl_program && priv->glsl_program->ps.id == gl_shaders[i].prgId)
shader_glsl_disable(priv, context);
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps);
break;
}
@ -6370,22 +6386,22 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
{
struct glsl_vs_compiled_shader *gl_shaders = shader_data->gl_shaders.vs;
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting vertex shader %u.\n", gl_shaders[i].prgId);
if (priv->glsl_program && priv->glsl_program->vs.id == gl_shaders[i].prgId)
invalidate_current_program = TRUE;
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs);
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
struct glsl_shader_prog_link, vs.shader_entry)
{
delete_glsl_program_entry(priv, gl_info, entry);
}
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting vertex shader %u.\n", gl_shaders[i].prgId);
if (priv->glsl_program && priv->glsl_program->vs.id == gl_shaders[i].prgId)
shader_glsl_disable(priv, context);
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs);
break;
}
@ -6393,22 +6409,22 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
{
struct glsl_gs_compiled_shader *gl_shaders = shader_data->gl_shaders.gs;
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id);
if (priv->glsl_program && priv->glsl_program->gs.id == gl_shaders[i].id)
invalidate_current_program = TRUE;
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].id));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs);
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
struct glsl_shader_prog_link, gs.shader_entry)
{
delete_glsl_program_entry(priv, gl_info, entry);
}
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id);
if (priv->glsl_program && priv->glsl_program->gs.id == gl_shaders[i].id)
shader_glsl_disable(priv, context);
GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].id));
checkGLcall("glDeleteObjectARB");
}
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs);
break;
}
@ -6418,6 +6434,14 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
}
}
if (invalidate_current_program)
{
shader_glsl_disable(priv, context);
context->shader_update_mask = (1 << WINED3D_SHADER_TYPE_PIXEL)
| (1 << WINED3D_SHADER_TYPE_VERTEX)
| (1 << WINED3D_SHADER_TYPE_GEOMETRY);
}
HeapFree(GetProcessHeap(), 0, shader->backend_data);
shader->backend_data = NULL;
@ -6887,7 +6911,7 @@ static void glsl_vertex_pipe_vp_free(struct wined3d_device *device)
static void glsl_vertex_pipe_shader(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
}
static void glsl_vertex_pipe_projection(struct wined3d_context *context,
@ -6896,7 +6920,7 @@ static void glsl_vertex_pipe_projection(struct wined3d_context *context,
/* Table fog behavior depends on the projection matrix. */
if (state->render_states[WINED3D_RS_FOGENABLE]
&& state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
transform_projection(context, state, state_id);
}
@ -7160,7 +7184,7 @@ static void glsl_fragment_pipe_shader(struct wined3d_context *context,
{
context->last_was_pshader = use_ps(state);
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void glsl_fragment_pipe_fog(struct wined3d_context *context,
@ -7171,7 +7195,7 @@ static void glsl_fragment_pipe_fog(struct wined3d_context *context,
DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
if (!state->render_states[WINED3D_RS_FOGENABLE])
return;
@ -7200,7 +7224,7 @@ static void glsl_fragment_pipe_fog(struct wined3d_context *context,
static void glsl_fragment_pipe_tex_transform(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *context,

View File

@ -607,7 +607,7 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state
* The enabled / disabled planes are hardcoded into the shader. Update the
* shader to update the enabled clipplanes. In case of fixed function, we
* need to update the clipping field from ffp_vertex_settings. */
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
/* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
* of already set values
@ -3731,12 +3731,12 @@ void apply_pixelshader(struct wined3d_context *context, const struct wined3d_sta
context->last_was_pshader = FALSE;
}
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_GEOMETRY;
}
static void shader_bumpenv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -4630,7 +4630,7 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta
}
context->last_was_vshader = useVertexShaderFunction;
context->select_shader = 1;
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
if (updateFog)
context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
@ -4644,6 +4644,10 @@ void vertexdeclaration(struct wined3d_context *context, const struct wined3d_sta
if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
}
if (use_ps(state) && state->pixel_shader->reg_maps.shader_version.major == 1
&& state->pixel_shader->reg_maps.shader_version.minor <= 3)
context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
}
if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))

View File

@ -1092,9 +1092,10 @@ struct wined3d_context
DWORD current : 1;
DWORD destroyed : 1;
DWORD valid : 1;
DWORD select_shader : 1;
DWORD padding : 1;
DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */
DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */
DWORD shader_update_mask;
DWORD constant_update_mask;
DWORD numbered_array_mask;
GLenum tracking_parm; /* Which source is tracking current colour */