i965: Don't use _mesa_ir_link_shader to do our dirty work

Instead, do the uniform setting and input / output mapping directly in
brw_link_shader.  Hurray for not generating Mesa IR!  However, once
the i965 driver stops calling _mesa_ir_link_shader, UsesClipDistance
and UsesKill are no longer set.

Ideally gen6_upload_vs_push_constants should use the
gl_shader_program, but I don't see a way to propagate the information
there.  The other alternative, since this is the only usage, is to
move gl_vertex_program::UsesClipDistance to brw_vertex_program.

The compile (and precompile) stages use UsesKill to determine the
cache key for the shader.  This is then used to determine whether or
not to compile the shader.  Calculating this data during compilation
is too late.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Ian Romanick 2012-01-06 16:26:49 -08:00
parent efdc8bf189
commit 1c17745200
1 changed files with 85 additions and 7 deletions

View File

@ -77,22 +77,63 @@ brw_shader_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
}
GLboolean
brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
{
struct brw_context *brw = brw_context(ctx);
struct intel_context *intel = &brw->intel;
unsigned int stage;
if (!_mesa_ir_link_shader(ctx, prog))
return false;
for (stage = 0; stage < ARRAY_SIZE(prog->_LinkedShaders); stage++) {
for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders); stage++) {
struct brw_shader *shader =
(struct brw_shader *)prog->_LinkedShaders[stage];
(struct brw_shader *)shProg->_LinkedShaders[stage];
static const GLenum targets[] = {
GL_VERTEX_PROGRAM_ARB,
GL_FRAGMENT_PROGRAM_ARB,
GL_GEOMETRY_PROGRAM_NV
};
if (!shader)
continue;
struct gl_program *prog =
ctx->Driver.NewProgram(ctx, targets[stage], shader->base.Name);
if (!prog)
return NULL;
prog->Parameters = _mesa_new_parameter_list();
_mesa_generate_parameters_list_for_uniforms(shProg, &shader->base,
prog->Parameters);
if (stage == 0) {
struct gl_vertex_program *vp = (struct gl_vertex_program *) prog;
vp->UsesClipDistance = shProg->Vert.UsesClipDistance;
}
if (stage == 1) {
class uses_kill_visitor : public ir_hierarchical_visitor {
public:
uses_kill_visitor() : uses_kill(false)
{
/* empty */
}
virtual ir_visitor_status visit_enter(class ir_discard *ir)
{
this->uses_kill = true;
return visit_stop;
}
bool uses_kill;
};
uses_kill_visitor v;
v.run(shader->base.ir);
struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
fp->UsesKill = v.uses_kill;
}
void *mem_ctx = ralloc_context(NULL);
bool progress;
@ -147,13 +188,50 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|| progress;
} while (progress);
/* Make a pass over the IR to add state references for any built-in
* uniforms that are used. This has to be done now (during linking).
* Code generation doesn't happen until the first time this shader is
* used for rendering. Waiting until then to generate the parameters is
* too late. At that point, the values for the built-in informs won't
* get sent to the shader.
*/
foreach_list(node, shader->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
if ((var == NULL) || (var->mode != ir_var_uniform)
|| (strncmp(var->name, "gl_", 3) != 0))
continue;
const ir_state_slot *const slots = var->state_slots;
assert(var->state_slots != NULL);
for (unsigned int i = 0; i < var->num_state_slots; i++) {
_mesa_add_state_reference(prog->Parameters,
(gl_state_index *) slots[i].tokens);
}
}
validate_ir_tree(shader->ir);
reparent_ir(shader->ir, shader->ir);
ralloc_free(mem_ctx);
do_set_program_inouts(shader->ir, prog,
shader->base.Type == GL_FRAGMENT_SHADER);
prog->SamplersUsed = shader->base.active_samplers;
_mesa_update_shader_textures_used(shProg, prog);
_mesa_reference_program(ctx, &shader->base.Program, prog);
/* This has to be done last. Any operation that can cause
* prog->ParameterValues to get reallocated (e.g., anything that adds a
* program constant) has to happen before creating this linkage.
*/
_mesa_associate_uniform_storage(ctx, shProg, prog->Parameters);
}
if (!brw_shader_precompile(ctx, prog))
if (!brw_shader_precompile(ctx, shProg))
return false;
return true;