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.cpp107
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.h1
-rw-r--r--mesalib/src/mesa/program/register_allocate.c45
3 files changed, 45 insertions, 108 deletions
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index a5b6699c2..35a9b8437 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -33,7 +33,6 @@
#include "main/compiler.h"
#include "ir.h"
#include "ir_visitor.h"
-#include "ir_print_visitor.h"
#include "ir_expression_flattening.h"
#include "ir_uniform.h"
#include "glsl_types.h"
@@ -1057,9 +1056,9 @@ ir_to_mesa_visitor::emit_swz(ir_expression *ir)
this->result.file = PROGRAM_UNDEFINED;
deref->accept(this);
if (this->result.file == PROGRAM_UNDEFINED) {
- ir_print_visitor v;
printf("Failed to get tree for expression operand:\n");
- deref->accept(&v);
+ deref->print();
+ printf("\n");
exit(1);
}
@@ -1129,9 +1128,9 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
this->result.file = PROGRAM_UNDEFINED;
ir->operands[operand]->accept(this);
if (this->result.file == PROGRAM_UNDEFINED) {
- ir_print_visitor v;
printf("Failed to get tree for expression operand:\n");
- ir->operands[operand]->accept(&v);
+ ir->operands[operand]->print();
+ printf("\n");
exit(1);
}
op[operand] = this->result;
@@ -2811,22 +2810,19 @@ get_mesa_program(struct gl_context *ctx,
int i;
struct gl_program *prog;
GLenum target;
- const char *target_string;
+ const char *target_string = _mesa_glsl_shader_target_name(shader->Type);
struct gl_shader_compiler_options *options =
&ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)];
switch (shader->Type) {
case GL_VERTEX_SHADER:
target = GL_VERTEX_PROGRAM_ARB;
- target_string = "vertex";
break;
case GL_FRAGMENT_SHADER:
target = GL_FRAGMENT_PROGRAM_ARB;
- target_string = "fragment";
break;
case GL_GEOMETRY_SHADER:
target = GL_GEOMETRY_PROGRAM_NV;
- target_string = "geometry";
break;
default:
assert(!"should not be reached");
@@ -3101,99 +3097,6 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
return prog->LinkStatus;
}
-
-/**
- * Compile a GLSL shader. Called via glCompileShader().
- */
-void
-_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
-{
- struct _mesa_glsl_parse_state *state =
- new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
-
- const char *source = shader->Source;
- /* Check if the user called glCompileShader without first calling
- * glShaderSource. This should fail to compile, but not raise a GL_ERROR.
- */
- if (source == NULL) {
- shader->CompileStatus = GL_FALSE;
- return;
- }
-
- state->error = glcpp_preprocess(state, &source, &state->info_log,
- &ctx->Extensions, ctx);
-
- if (ctx->Shader.Flags & GLSL_DUMP) {
- printf("GLSL source for %s shader %d:\n",
- _mesa_glsl_shader_target_name(state->target), shader->Name);
- printf("%s\n", shader->Source);
- }
-
- if (!state->error) {
- _mesa_glsl_lexer_ctor(state, source);
- _mesa_glsl_parse(state);
- _mesa_glsl_lexer_dtor(state);
- }
-
- ralloc_free(shader->ir);
- shader->ir = new(shader) exec_list;
- if (!state->error && !state->translation_unit.is_empty())
- _mesa_ast_to_hir(shader->ir, state);
-
- if (!state->error && !shader->ir->is_empty()) {
- validate_ir_tree(shader->ir);
- struct gl_shader_compiler_options *options =
- &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)];
-
- /* Do some optimization at compile time to reduce shader IR size
- * and reduce later work if the same shader is linked multiple times
- */
- while (do_common_optimization(shader->ir, false, false, 32, options))
- ;
-
- validate_ir_tree(shader->ir);
- }
-
- shader->symbols = state->symbols;
-
- shader->CompileStatus = !state->error;
- shader->InfoLog = state->info_log;
- shader->Version = state->language_version;
- memcpy(shader->builtins_to_link, state->builtins_to_link,
- sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
- shader->num_builtins_to_link = state->num_builtins_to_link;
-
- if (ctx->Shader.Flags & GLSL_LOG) {
- _mesa_write_shader_to_file(shader);
- }
-
- if (ctx->Shader.Flags & GLSL_DUMP) {
- if (shader->CompileStatus) {
- printf("GLSL IR for shader %d:\n", shader->Name);
- _mesa_print_ir(shader->ir, NULL);
- printf("\n\n");
- } else {
- printf("GLSL shader %d failed to compile.\n", shader->Name);
- }
- if (shader->InfoLog && shader->InfoLog[0] != 0) {
- printf("GLSL shader %d info log:\n", shader->Name);
- printf("%s\n", shader->InfoLog);
- }
- }
-
- if (shader->UniformBlocks)
- ralloc_free(shader->UniformBlocks);
- shader->NumUniformBlocks = state->num_uniform_blocks;
- shader->UniformBlocks = state->uniform_blocks;
- ralloc_steal(shader, shader->UniformBlocks);
-
- /* Retain any live IR, but trash the rest. */
- reparent_ir(shader->ir, shader->ir);
-
- ralloc_free(state);
-}
-
-
/**
* Link a GLSL shader program. Called via glLinkProgram().
*/
diff --git a/mesalib/src/mesa/program/ir_to_mesa.h b/mesalib/src/mesa/program/ir_to_mesa.h
index aa053d9c8..2488a4582 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.h
+++ b/mesalib/src/mesa/program/ir_to_mesa.h
@@ -33,7 +33,6 @@ struct gl_context;
struct gl_shader;
struct gl_shader_program;
-void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *sh);
void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
GLboolean _mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader);
GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c
index 16739fd39..4eed0b5aa 100644
--- a/mesalib/src/mesa/program/register_allocate.c
+++ b/mesalib/src/mesa/program/register_allocate.c
@@ -157,6 +157,16 @@ 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;
};
/**
@@ -509,6 +519,7 @@ 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;
@@ -587,8 +598,16 @@ ra_get_best_spill_node(struct ra_graph *g)
{
unsigned int best_node = -1;
float best_benefit = 0.0;
- unsigned int n;
+ unsigned int n, i;
+ /* 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().
+ */
for (n = 0; n < g->count; n++) {
float cost = g->nodes[n].spill_cost;
float benefit;
@@ -596,10 +615,6 @@ ra_get_best_spill_node(struct ra_graph *g)
if (cost <= 0.0)
continue;
- /* Only consider registers for spilling if they are still in the
- * interference graph (those on the stack have already been proven to be
- * allocatable without spilling).
- */
if (g->nodes[n].in_stack)
continue;
@@ -611,6 +626,26 @@ 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;
}