aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/ast_array_index.cpp6
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp107
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h4
-rw-r--r--mesalib/src/glsl/ir_uniform.h11
-rw-r--r--mesalib/src/glsl/linker.cpp18
-rw-r--r--mesalib/src/glsl/lower_offset_array.cpp10
-rw-r--r--mesalib/src/glsl/main.cpp2
-rw-r--r--mesalib/src/glsl/opt_array_splitting.cpp2
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp27
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.h3
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);