summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ir_optimization.h3
-rw-r--r--src/glsl/lower_variable_index_to_cond_assign.cpp57
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c7
-rw-r--r--src/mesa/main/mtypes.h10
-rw-r--r--src/mesa/program/ir_to_mesa.cpp13
5 files changed, 82 insertions, 8 deletions
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 5c8dc17d337..6a37e167fe5 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -56,5 +56,6 @@ bool do_tree_grafting(exec_list *instructions);
bool do_vec_index_to_cond_assign(exec_list *instructions);
bool do_vec_index_to_swizzle(exec_list *instructions);
bool lower_noise(exec_list *instructions);
-bool lower_variable_index_to_cond_assign(exec_list *instructions);
+bool lower_variable_index_to_cond_assign(exec_list *instructions,
+ bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform);
bool optimize_redundant_jumps(exec_list *instructions);
diff --git a/src/glsl/lower_variable_index_to_cond_assign.cpp b/src/glsl/lower_variable_index_to_cond_assign.cpp
index 095592b9f7f..2044199d27b 100644
--- a/src/glsl/lower_variable_index_to_cond_assign.cpp
+++ b/src/glsl/lower_variable_index_to_cond_assign.cpp
@@ -210,18 +210,56 @@ struct switch_generator
class variable_index_to_cond_assign_visitor : public ir_rvalue_visitor {
public:
- variable_index_to_cond_assign_visitor()
+ variable_index_to_cond_assign_visitor(bool lower_input,
+ bool lower_output,
+ bool lower_temp,
+ bool lower_uniform)
{
this->progress = false;
+ this->lower_inputs = lower_input;
+ this->lower_outputs = lower_output;
+ this->lower_temps = lower_temp;
+ this->lower_uniforms = lower_uniform;
}
bool progress;
+ bool lower_inputs;
+ bool lower_outputs;
+ bool lower_temps;
+ bool lower_uniforms;
bool is_array_or_matrix(const ir_instruction *ir) const
{
return (ir->type->is_array() || ir->type->is_matrix());
}
+ bool needs_lowering(ir_dereference_array *deref) const
+ {
+ if (deref == NULL || deref->array_index->as_constant()
+ || !is_array_or_matrix(deref->array))
+ return false;
+
+ if (deref->array->ir_type == ir_type_constant)
+ return this->lower_temps;
+
+ const ir_variable *const var = deref->array->variable_referenced();
+ switch (var->mode) {
+ case ir_var_auto:
+ case ir_var_temporary:
+ return this->lower_temps;
+ case ir_var_uniform:
+ return this->lower_uniforms;
+ case ir_var_in:
+ return (var->location == -1) ? this->lower_temps : this->lower_inputs;
+ case ir_var_out:
+ return (var->location == -1) ? this->lower_temps : this->lower_outputs;
+ case ir_var_inout:
+ return this->lower_temps;
+ }
+
+ assert(!"Should not get here.");
+ }
+
ir_variable *convert_dereference_array(ir_dereference_array *orig_deref,
ir_rvalue* value)
{
@@ -276,8 +314,7 @@ public:
return;
ir_dereference_array* orig_deref = (*pir)->as_dereference_array();
- if (orig_deref && !orig_deref->array_index->as_constant()
- && is_array_or_matrix(orig_deref->array)) {
+ if (needs_lowering(orig_deref)) {
ir_variable* var = convert_dereference_array(orig_deref, 0);
assert(var);
*pir = new(talloc_parent(base_ir)) ir_dereference_variable(var);
@@ -292,8 +329,7 @@ public:
ir_dereference_array *orig_deref = ir->lhs->as_dereference_array();
- if (orig_deref && !orig_deref->array_index->as_constant()
- && is_array_or_matrix(orig_deref->array)) {
+ if (needs_lowering(orig_deref)) {
convert_dereference_array(orig_deref, ir->rhs);
ir->remove();
this->progress = true;
@@ -304,9 +340,16 @@ public:
};
bool
-lower_variable_index_to_cond_assign(exec_list *instructions)
+lower_variable_index_to_cond_assign(exec_list *instructions,
+ bool lower_input,
+ bool lower_output,
+ bool lower_temp,
+ bool lower_uniform)
{
- variable_index_to_cond_assign_visitor v;
+ variable_index_to_cond_assign_visitor v(lower_input,
+ lower_output,
+ lower_temp,
+ lower_uniform);
visit_list_elements(&v, instructions);
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index de78400d424..d08538ec20c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -116,6 +116,13 @@ GLboolean brwCreateContext( int api,
ctx->ShaderCompilerOptions[i].EmitNVTempInitialization = GL_TRUE;
ctx->ShaderCompilerOptions[i].EmitNoNoise = GL_TRUE;
ctx->ShaderCompilerOptions[i].EmitNoMainReturn = GL_TRUE;
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectInput = GL_TRUE;
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectOutput = GL_TRUE;
+
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectUniform =
+ (i == MESA_SHADER_FRAGMENT);
+ ctx->ShaderCompilerOptions[i].EmitNoIndirectTemp =
+ (i == MESA_SHADER_FRAGMENT);
}
ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 864805af0ef..fdf8100c8cd 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2191,6 +2191,16 @@ struct gl_shader_compiler_options
GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */
GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */
+ /**
+ * \name Forms of indirect addressing the driver cannot do.
+ */
+ /*@{*/
+ GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */
+ GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */
+ GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */
+ GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */
+ /*@}*/
+
GLuint MaxUnrollIterations;
struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 227dfdbd50a..29b92821f6d 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2745,6 +2745,19 @@ _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
if (options->EmitNoNoise)
progress = lower_noise(ir) || progress;
+ /* If there are forms of indirect addressing that the driver
+ * cannot handle, perform the lowering pass.
+ */
+ if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput
+ || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform)
+ progress =
+ lower_variable_index_to_cond_assign(ir,
+ options->EmitNoIndirectInput,
+ options->EmitNoIndirectOutput,
+ options->EmitNoIndirectTemp,
+ options->EmitNoIndirectUniform)
+ || progress;
+
progress = do_vec_index_to_cond_assign(ir) || progress;
} while (progress);