diff options
-rw-r--r-- | src/glsl/ir_optimization.h | 3 | ||||
-rw-r--r-- | src/glsl/lower_variable_index_to_cond_assign.cpp | 57 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.c | 7 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 10 | ||||
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 13 |
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); |