diff options
Diffstat (limited to 'mesalib/src/mesa/program')
-rw-r--r-- | mesalib/src/mesa/program/ir_to_mesa.cpp | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/program/programopt.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/program/register_allocate.c | 145 | ||||
-rw-r--r-- | mesalib/src/mesa/program/register_allocate.h | 5 | ||||
-rw-r--r-- | mesalib/src/mesa/program/sampler.cpp | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/program/sampler.h | 3 |
6 files changed, 84 insertions, 93 deletions
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index b088160d3..e5844c3c4 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1459,6 +1459,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_unop_interpolate_at_centroid: case ir_binop_interpolate_at_offset: case ir_binop_interpolate_at_sample: + case ir_unop_dFdx_coarse: + case ir_unop_dFdx_fine: + case ir_unop_dFdy_coarse: + case ir_unop_dFdy_fine: assert(!"not supported"); break; @@ -2428,8 +2432,7 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name, } gl_register_file file; - if (type->is_sampler() || - (type->is_array() && type->fields.array->is_sampler())) { + if (type->without_array()->is_sampler()) { file = PROGRAM_SAMPLER; } else { file = PROGRAM_UNIFORM; @@ -2795,7 +2798,7 @@ get_mesa_program(struct gl_context *ctx, GLenum target = _mesa_shader_stage_to_program(shader->Stage); const char *target_string = _mesa_shader_stage_to_string(shader->Stage); struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[shader->Stage]; + &ctx->Const.ShaderCompilerOptions[shader->Stage]; validate_ir_tree(shader->ir); @@ -2980,7 +2983,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; const struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[prog->_LinkedShaders[i]->Stage]; + &ctx->Const.ShaderCompilerOptions[prog->_LinkedShaders[i]->Stage]; do { progress = false; diff --git a/mesalib/src/mesa/program/programopt.c b/mesalib/src/mesa/program/programopt.c index 92a8831d2..b654b1db6 100644 --- a/mesalib/src/mesa/program/programopt.c +++ b/mesalib/src/mesa/program/programopt.c @@ -218,7 +218,7 @@ _mesa_insert_mvp_mad_code(struct gl_context *ctx, struct gl_vertex_program *vpro void _mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog) { - if (ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS) + if (ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS) _mesa_insert_mvp_dp4_code( ctx, vprog ); else _mesa_insert_mvp_mad_code( ctx, vprog ); diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c index 549154e8a..db2be5dfa 100644 --- a/mesalib/src/mesa/program/register_allocate.c +++ b/mesalib/src/mesa/program/register_allocate.c @@ -146,6 +146,12 @@ struct ra_node { */ bool in_stack; + /** + * The q total, as defined in the Runeson/Nyström paper, for all the + * interfering nodes not in the stack. + */ + unsigned int q_total; + /* For an implementation that needs register spilling, this is the * approximate cost of spilling this node. */ @@ -162,16 +168,6 @@ struct ra_graph { unsigned int *stack; unsigned int stack_count; - - /** - * Tracks the start of the set of optimistically-colored registers in the - * stack. - * - * Along with any registers not in the stack (if one called ra_simplify() - * and didn't do optimistic coloring), these need to be considered for - * spilling. - */ - unsigned int stack_optimistic_start; }; /** @@ -354,6 +350,12 @@ ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2) { BITSET_SET(g->nodes[n1].adjacency, n2); + if (n1 != n2) { + int n1_class = g->nodes[n1].class; + int n2_class = g->nodes[n2].class; + g->nodes[n1].q_total += g->regs->classes[n1_class]->q[n2_class]; + } + if (g->nodes[n1].adjacency_count >= g->nodes[n1].adjacency_list_size) { g->nodes[n1].adjacency_list_size *= 2; @@ -387,6 +389,7 @@ ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) g->nodes[i].adjacency_list = ralloc_array(g, unsigned int, g->nodes[i].adjacency_list_size); g->nodes[i].adjacency_count = 0; + g->nodes[i].q_total = 0; ra_add_node_adjacency(g, i, i); g->nodes[i].reg = NO_REG; @@ -415,20 +418,25 @@ ra_add_node_interference(struct ra_graph *g, static bool pq_test(struct ra_graph *g, unsigned int n) { - unsigned int j; - unsigned int q = 0; int n_class = g->nodes[n].class; - for (j = 0; j < g->nodes[n].adjacency_count; j++) { - unsigned int n2 = g->nodes[n].adjacency_list[j]; + return g->nodes[n].q_total < g->regs->classes[n_class]->p; +} + +static void +decrement_q(struct ra_graph *g, unsigned int n) +{ + unsigned int i; + int n_class = g->nodes[n].class; + + for (i = 0; i < g->nodes[n].adjacency_count; i++) { + unsigned int n2 = g->nodes[n].adjacency_list[i]; unsigned int n2_class = g->nodes[n2].class; if (n != n2 && !g->nodes[n2].in_stack) { - q += g->regs->classes[n_class]->q[n2_class]; + g->nodes[n2].q_total -= g->regs->classes[n2_class]->q[n_class]; } } - - return q < g->regs->classes[n_class]->p; } /** @@ -436,17 +444,21 @@ pq_test(struct ra_graph *g, unsigned int n) * trivially-colorable nodes into a stack of nodes to be colored, * removing them from the graph, and rinsing and repeating. * - * Returns true if all nodes were removed from the graph. false - * means that either spilling will be required, or optimistic coloring - * should be applied. + * If we encounter a case where we can't push any nodes on the stack, then + * we optimistically choose a node and push it on the stack. We heuristically + * push the node with the lowest total q value, since it has the fewest + * neighbors and therefore is most likely to be allocated. */ -bool +static void ra_simplify(struct ra_graph *g) { bool progress = true; int i; while (progress) { + unsigned int best_optimistic_node = ~0; + unsigned int lowest_q_total = ~0; + progress = false; for (i = g->count - 1; i >= 0; i--) { @@ -454,20 +466,28 @@ ra_simplify(struct ra_graph *g) continue; if (pq_test(g, i)) { + decrement_q(g, i); g->stack[g->stack_count] = i; g->stack_count++; g->nodes[i].in_stack = true; progress = true; + } else { + unsigned int new_q_total = g->nodes[i].q_total; + if (new_q_total < lowest_q_total) { + best_optimistic_node = i; + lowest_q_total = new_q_total; + } } } - } - for (i = 0; i < g->count; i++) { - if (!g->nodes[i].in_stack && g->nodes[i].reg == -1) - return false; + if (!progress && best_optimistic_node != ~0) { + decrement_q(g, best_optimistic_node); + g->stack[g->stack_count] = best_optimistic_node; + g->stack_count++; + g->nodes[best_optimistic_node].in_stack = true; + progress = true; + } } - - return true; } /** @@ -477,7 +497,7 @@ ra_simplify(struct ra_graph *g) * If all nodes were trivially colorable, then this must succeed. If * not (optimistic coloring), then it may return false; */ -bool +static bool ra_select(struct ra_graph *g) { int i; @@ -509,11 +529,16 @@ ra_select(struct ra_graph *g) if (i == g->nodes[n].adjacency_count) break; } + + /* set this to false even if we return here so that + * ra_get_best_spill_node() considers this node later. + */ + g->nodes[n].in_stack = false; + if (ri == g->regs->count) return false; g->nodes[n].reg = r; - g->nodes[n].in_stack = false; g->stack_count--; if (g->regs->round_robin) @@ -523,35 +548,10 @@ ra_select(struct ra_graph *g) return true; } -/** - * Optimistic register coloring: Just push the remaining nodes - * on the stack. They'll be colored first in ra_select(), and - * if they succeed then the locally-colorable nodes are still - * locally-colorable and the rest of the register allocation - * will succeed. - */ -void -ra_optimistic_color(struct ra_graph *g) -{ - unsigned int i; - - g->stack_optimistic_start = g->stack_count; - for (i = 0; i < g->count; i++) { - if (g->nodes[i].in_stack || g->nodes[i].reg != NO_REG) - continue; - - g->stack[g->stack_count] = i; - g->stack_count++; - g->nodes[i].in_stack = true; - } -} - bool -ra_allocate_no_spills(struct ra_graph *g) +ra_allocate(struct ra_graph *g) { - if (!ra_simplify(g)) { - ra_optimistic_color(g); - } + ra_simplify(g); return ra_select(g); } @@ -614,15 +614,12 @@ ra_get_best_spill_node(struct ra_graph *g) { unsigned int best_node = -1; float best_benefit = 0.0; - unsigned int n, i; + unsigned int n; - /* For any registers not in the stack to be colored, consider them for - * spilling. This will mostly collect nodes that were being optimistally - * colored as part of ra_allocate_no_spills() if we didn't successfully - * optimistically color. - * - * It also includes nodes not trivially colorable by ra_simplify() if it - * was used directly instead of as part of ra_allocate_no_spills(). + /* Consider any nodes that we colored successfully or the node we failed to + * color for spilling. When we failed to color a node in ra_select(), we + * only considered these nodes, so spilling any other ones would not result + * in us making progress. */ for (n = 0; n < g->count; n++) { float cost = g->nodes[n].spill_cost; @@ -642,26 +639,6 @@ ra_get_best_spill_node(struct ra_graph *g) } } - /* Also consider spilling any nodes that were set up to be optimistically - * colored that we couldn't manage to color in ra_select(). - */ - for (i = g->stack_optimistic_start; i < g->stack_count; i++) { - float cost, benefit; - - n = g->stack[i]; - cost = g->nodes[n].spill_cost; - - if (cost <= 0.0) - continue; - - benefit = ra_get_spill_benefit(g, n); - - if (benefit / cost > best_benefit) { - best_benefit = benefit / cost; - best_node = n; - } - } - return best_node; } diff --git a/mesalib/src/mesa/program/register_allocate.h b/mesalib/src/mesa/program/register_allocate.h index 337dcf709..bfc9190dc 100644 --- a/mesalib/src/mesa/program/register_allocate.h +++ b/mesalib/src/mesa/program/register_allocate.h @@ -66,10 +66,7 @@ void ra_add_node_interference(struct ra_graph *g, /** @} */ /** @{ Graph-coloring register allocation */ -bool ra_simplify(struct ra_graph *g); -void ra_optimistic_color(struct ra_graph *g); -bool ra_select(struct ra_graph *g); -bool ra_allocate_no_spills(struct ra_graph *g); +bool ra_allocate(struct ra_graph *g); unsigned int ra_get_node_reg(struct ra_graph *g, unsigned int n); void ra_set_node_reg(struct ra_graph * g, unsigned int n, unsigned int reg); diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp index e6532be84..29a540871 100644 --- a/mesalib/src/mesa/program/sampler.cpp +++ b/mesalib/src/mesa/program/sampler.cpp @@ -134,3 +134,14 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler, return shader_program->UniformStorage[location].sampler[shader].index + getname.offset; } + + +extern "C" class ir_rvalue * +_mesa_get_sampler_array_nonconst_index(class ir_dereference *sampler) +{ + ir_dereference_array *deref_arr = sampler->as_dereference_array(); + if (!deref_arr || deref_arr->array_index->as_constant()) + return NULL; + + return deref_arr->array_index; +} diff --git a/mesalib/src/mesa/program/sampler.h b/mesalib/src/mesa/program/sampler.h index 22467e990..8b7c3b63e 100644 --- a/mesalib/src/mesa/program/sampler.h +++ b/mesalib/src/mesa/program/sampler.h @@ -27,3 +27,6 @@ int _mesa_get_sampler_uniform_value(class ir_dereference *sampler, struct gl_shader_program *shader_program, const struct gl_program *prog); + +class ir_rvalue * +_mesa_get_sampler_array_nonconst_index(class ir_dereference *sampler); |