wined3d: Avoid looking up shaders for shader stages that didn't change.
This commit is contained in:
parent
251160fef9
commit
62859daf0b
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue