diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ast_array_index.cpp | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 107 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser_extras.h | 4 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_uniform.h | 11 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 18 | ||||
-rw-r--r-- | mesalib/src/glsl/lower_offset_array.cpp | 10 | ||||
-rw-r--r-- | mesalib/src/glsl/main.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_array_splitting.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/standalone_scaffolding.cpp | 27 | ||||
-rw-r--r-- | mesalib/src/glsl/standalone_scaffolding.h | 3 |
10 files changed, 114 insertions, 76 deletions
diff --git a/mesalib/src/glsl/ast_array_index.cpp b/mesalib/src/glsl/ast_array_index.cpp index 49a8574f2..ff0c7576d 100644 --- a/mesalib/src/glsl/ast_array_index.cpp +++ b/mesalib/src/glsl/ast_array_index.cpp @@ -49,12 +49,12 @@ ast_array_specifier::print(void) const * loc and state to report the error. */ static void -update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc, +update_max_array_access(ir_rvalue *ir, int idx, YYLTYPE *loc, struct _mesa_glsl_parse_state *state) { if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) { ir_variable *var = deref_var->var; - if (idx > var->data.max_array_access) { + if (idx > (int)var->data.max_array_access) { var->data.max_array_access = idx; /* Check whether this access will, as a side effect, implicitly cause @@ -94,7 +94,7 @@ update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc, assert(max_ifc_array_access != NULL); - if (idx > max_ifc_array_access[field_index]) { + if (idx > (int)max_ifc_array_access[field_index]) { max_ifc_array_access[field_index] = idx; /* Check whether this access will, as a side effect, implicitly diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 068af295a..fe1e1291e 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -3767,7 +3767,7 @@ ast_declarator_list::hir(exec_list *instructions, earlier->data.how_declared == ir_var_declared_in_block) { _mesa_glsl_error(&loc, state, "`%s' has already been redeclared using " - "gl_PerVertex", var->name); + "gl_PerVertex", earlier->name); } earlier->data.how_declared = ir_var_declared_normally; } @@ -4373,7 +4373,7 @@ ast_jump_statement::hir(exec_list *instructions, * loop. */ if (state->loop_nesting_ast != NULL && - mode == ast_continue) { + mode == ast_continue && !state->switch_state.is_switch_innermost) { if (state->loop_nesting_ast->rest_expression) { state->loop_nesting_ast->rest_expression->hir(instructions, state); @@ -4385,19 +4385,27 @@ ast_jump_statement::hir(exec_list *instructions, } if (state->switch_state.is_switch_innermost && + mode == ast_continue) { + /* Set 'continue_inside' to true. */ + ir_rvalue *const true_val = new (ctx) ir_constant(true); + ir_dereference_variable *deref_continue_inside_var = + new(ctx) ir_dereference_variable(state->switch_state.continue_inside); + instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var, + true_val)); + + /* Break out from the switch, continue for the loop will + * be called right after switch. */ + ir_loop_jump *const jump = + new(ctx) ir_loop_jump(ir_loop_jump::jump_break); + instructions->push_tail(jump); + + } else if (state->switch_state.is_switch_innermost && mode == ast_break) { - /* Force break out of switch by setting is_break switch state. - */ - ir_variable *const is_break_var = state->switch_state.is_break_var; - ir_dereference_variable *const deref_is_break_var = - new(ctx) ir_dereference_variable(is_break_var); - ir_constant *const true_val = new(ctx) ir_constant(true); - ir_assignment *const set_break_var = - new(ctx) ir_assignment(deref_is_break_var, true_val); - - instructions->push_tail(set_break_var); - } - else { + /* Force break out of switch by inserting a break. */ + ir_loop_jump *const jump = + new(ctx) ir_loop_jump(ir_loop_jump::jump_break); + instructions->push_tail(jump); + } else { ir_loop_jump *const jump = new(ctx) ir_loop_jump((mode == ast_break) ? ir_loop_jump::jump_break @@ -4509,19 +4517,19 @@ ast_switch_statement::hir(exec_list *instructions, instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var, is_fallthru_val)); - /* Initalize is_break state to false. + /* Initialize continue_inside state to false. */ - ir_rvalue *const is_break_val = new (ctx) ir_constant(false); - state->switch_state.is_break_var = + state->switch_state.continue_inside = new(ctx) ir_variable(glsl_type::bool_type, - "switch_is_break_tmp", + "continue_inside_tmp", ir_var_temporary); - instructions->push_tail(state->switch_state.is_break_var); + instructions->push_tail(state->switch_state.continue_inside); - ir_dereference_variable *deref_is_break_var = - new(ctx) ir_dereference_variable(state->switch_state.is_break_var); - instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var, - is_break_val)); + ir_rvalue *const false_val = new (ctx) ir_constant(false); + ir_dereference_variable *deref_continue_inside_var = + new(ctx) ir_dereference_variable(state->switch_state.continue_inside); + instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var, + false_val)); state->switch_state.run_default = new(ctx) ir_variable(glsl_type::bool_type, @@ -4529,13 +4537,42 @@ ast_switch_statement::hir(exec_list *instructions, ir_var_temporary); instructions->push_tail(state->switch_state.run_default); + /* Loop around the switch is used for flow control. */ + ir_loop * loop = new(ctx) ir_loop(); + instructions->push_tail(loop); + /* Cache test expression. */ - test_to_hir(instructions, state); + test_to_hir(&loop->body_instructions, state); /* Emit code for body of switch stmt. */ - body->hir(instructions, state); + body->hir(&loop->body_instructions, state); + + /* Insert a break at the end to exit loop. */ + ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_break); + loop->body_instructions.push_tail(jump); + + /* If we are inside loop, check if continue got called inside switch. */ + if (state->loop_nesting_ast != NULL) { + ir_dereference_variable *deref_continue_inside = + new(ctx) ir_dereference_variable(state->switch_state.continue_inside); + ir_if *irif = new(ctx) ir_if(deref_continue_inside); + ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_continue); + + if (state->loop_nesting_ast != NULL) { + if (state->loop_nesting_ast->rest_expression) { + state->loop_nesting_ast->rest_expression->hir(&irif->then_instructions, + state); + } + if (state->loop_nesting_ast->mode == + ast_iteration_statement::ast_do_while) { + state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state); + } + } + irif->then_instructions.push_tail(jump); + instructions->push_tail(irif); + } hash_table_dtor(state->switch_state.labels_ht); @@ -4659,18 +4696,6 @@ ast_case_statement::hir(exec_list *instructions, { labels->hir(instructions, state); - /* Conditionally set fallthru state based on break state. */ - ir_constant *const false_val = new(state) ir_constant(false); - ir_dereference_variable *const deref_is_fallthru_var = - new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); - ir_dereference_variable *const deref_is_break_var = - new(state) ir_dereference_variable(state->switch_state.is_break_var); - ir_assignment *const reset_fallthru_on_break = - new(state) ir_assignment(deref_is_fallthru_var, - false_val, - deref_is_break_var); - instructions->push_tail(reset_fallthru_on_break); - /* Guard case statements depending on fallthru state. */ ir_dereference_variable *const deref_fallthru_guard = new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); @@ -5681,17 +5706,21 @@ ast_interface_block::hir(exec_list *instructions, var->data.stream = this->layout.stream; + /* Examine var name here since var may get deleted in the next call */ + bool var_is_gl_id = is_gl_identifier(var->name); + if (redeclaring_per_vertex) { ir_variable *earlier = get_variable_being_redeclared(var, loc, state, true /* allow_all_redeclarations */); - if (!is_gl_identifier(var->name) || earlier == NULL) { + if (!var_is_gl_id || earlier == NULL) { _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex can only " "include built-in variables"); } else if (earlier->data.how_declared == ir_var_declared_normally) { _mesa_glsl_error(&loc, state, - "`%s' has already been redeclared", var->name); + "`%s' has already been redeclared", + earlier->name); } else { earlier->data.how_declared = ir_var_declared_in_block; earlier->reinit_interface_type(block_type); diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index d0299a760..36955d9af 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -40,9 +40,11 @@ struct glsl_switch_state { /** Temporary variables needed for switch statement. */ ir_variable *test_var; ir_variable *is_fallthru_var; - ir_variable *is_break_var; class ast_switch_statement *switch_nesting_ast; + /** Used to detect if 'continue' was called inside a switch. */ + ir_variable *continue_inside; + /** Used to set condition if 'default' label should be chosen. */ ir_variable *run_default; diff --git a/mesalib/src/glsl/ir_uniform.h b/mesalib/src/glsl/ir_uniform.h index 2f7352825..b9ecf7cdd 100644 --- a/mesalib/src/glsl/ir_uniform.h +++ b/mesalib/src/glsl/ir_uniform.h @@ -45,17 +45,6 @@ extern "C" { enum PACKED gl_uniform_driver_format { uniform_native = 0, /**< Store data in the native format. */ uniform_int_float, /**< Store integer data as floats. */ - uniform_bool_float, /**< Store boolean data as floats. */ - - /** - * Store boolean data as integer using 1 for \c true. - */ - uniform_bool_int_0_1, - - /** - * Store boolean data as integer using ~0 for \c true. - */ - uniform_bool_int_0_not0 }; struct gl_uniform_driver_storage { diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 47a722d9d..2d31801d3 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1679,7 +1679,7 @@ link_intrastage_shaders(void *mem_ctx, populate_symbol_table(linked); - /* The a pointer to the main function in the final linked shader (i.e., the + /* The pointer to the main function in the final linked shader (i.e., the * copy of the original shader that contained the main function). */ ir_function_signature *const main_sig = @@ -1882,7 +1882,7 @@ find_available_slots(unsigned used_mask, unsigned needed_count) /** - * Assign locations for either VS inputs for FS outputs + * Assign locations for either VS inputs or FS outputs * * \param prog Shader program whose variables need locations assigned * \param target_index Selector for the program target to receive location @@ -2484,20 +2484,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) prog->Validated = false; prog->_Used = false; - ralloc_free(prog->InfoLog); - prog->InfoLog = ralloc_strdup(NULL, ""); - - ralloc_free(prog->UniformBlocks); - prog->UniformBlocks = NULL; - prog->NumUniformBlocks = 0; - for (int i = 0; i < MESA_SHADER_STAGES; i++) { - ralloc_free(prog->UniformBlockStageIndex[i]); - prog->UniformBlockStageIndex[i] = NULL; - } - - ralloc_free(prog->AtomicBuffers); - prog->AtomicBuffers = NULL; - prog->NumAtomicBuffers = 0; prog->ARB_fragment_coord_conventions_enable = false; /* Separate the shaders into groups based on their type. diff --git a/mesalib/src/glsl/lower_offset_array.cpp b/mesalib/src/glsl/lower_offset_array.cpp index 5b48526db..c30f80143 100644 --- a/mesalib/src/glsl/lower_offset_array.cpp +++ b/mesalib/src/glsl/lower_offset_array.cpp @@ -22,7 +22,7 @@ */ /** - * \file brw_lower_offset_array.cpp + * \file lower_offset_array.cpp * * IR lower pass to decompose ir_texture ir_tg4 with an array of offsets * into four ir_tg4s with a single ivec2 offset, select the .w component of each, @@ -39,9 +39,9 @@ using namespace ir_builder; -class brw_lower_offset_array_visitor : public ir_rvalue_visitor { +class lower_offset_array_visitor : public ir_rvalue_visitor { public: - brw_lower_offset_array_visitor() + lower_offset_array_visitor() { progress = false; } @@ -52,7 +52,7 @@ public: }; void -brw_lower_offset_array_visitor::handle_rvalue(ir_rvalue **rv) +lower_offset_array_visitor::handle_rvalue(ir_rvalue **rv) { if (*rv == NULL || (*rv)->ir_type != ir_type_texture) return; @@ -83,7 +83,7 @@ brw_lower_offset_array_visitor::handle_rvalue(ir_rvalue **rv) bool lower_offset_arrays(exec_list *instructions) { - brw_lower_offset_array_visitor v; + lower_offset_array_visitor v; visit_list_elements(&v, instructions); diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index afc458b44..79e943831 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -414,6 +414,8 @@ main(int argc, char **argv) } if ((status == EXIT_SUCCESS) && do_link) { + _mesa_clear_shader_program_data(whole_program); + link_shaders(ctx, whole_program); status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp index ebb076b22..9e73f3c44 100644 --- a/mesalib/src/glsl/opt_array_splitting.cpp +++ b/mesalib/src/glsl/opt_array_splitting.cpp @@ -295,7 +295,7 @@ ir_array_splitting_visitor::split_deref(ir_dereference **deref) ir_constant *constant = deref_array->array_index->as_constant(); assert(constant); - if (constant->value.i[0] < (int)entry->size) { + if (constant->value.i[0] >= 0 && constant->value.i[0] < (int)entry->size) { *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[constant->value.i[0]]); } else { diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 2b76dd17b..67b0d0c82 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -83,6 +83,33 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type) return shader; } +void +_mesa_clear_shader_program_data(struct gl_shader_program *shProg) +{ + unsigned i; + + shProg->NumUserUniformStorage = 0; + shProg->UniformStorage = NULL; + shProg->NumUniformRemapTable = 0; + shProg->UniformRemapTable = NULL; + shProg->UniformHash = NULL; + + ralloc_free(shProg->InfoLog); + shProg->InfoLog = ralloc_strdup(shProg, ""); + + ralloc_free(shProg->UniformBlocks); + shProg->UniformBlocks = NULL; + shProg->NumUniformBlocks = 0; + for (i = 0; i < MESA_SHADER_STAGES; i++) { + ralloc_free(shProg->UniformBlockStageIndex[i]); + shProg->UniformBlockStageIndex[i] = NULL; + } + + ralloc_free(shProg->AtomicBuffers); + shProg->AtomicBuffers = NULL; + shProg->NumAtomicBuffers = 0; +} + void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) { memset(ctx, 0, sizeof(*ctx)); diff --git a/mesalib/src/glsl/standalone_scaffolding.h b/mesalib/src/glsl/standalone_scaffolding.h index df783afdb..895dd2782 100644 --- a/mesalib/src/glsl/standalone_scaffolding.h +++ b/mesalib/src/glsl/standalone_scaffolding.h @@ -45,6 +45,9 @@ extern "C" struct gl_shader * _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type); extern "C" void +_mesa_clear_shader_program_data(struct gl_shader_program *); + +extern "C" void _mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id, const char *msg, int len); |