aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/program
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/program')
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp11
-rw-r--r--mesalib/src/mesa/program/programopt.c2
-rw-r--r--mesalib/src/mesa/program/register_allocate.c145
-rw-r--r--mesalib/src/mesa/program/register_allocate.h5
-rw-r--r--mesalib/src/mesa/program/sampler.cpp11
-rw-r--r--mesalib/src/mesa/program/sampler.h3
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);