diff options
Diffstat (limited to 'mesalib/src')
77 files changed, 549 insertions, 616 deletions
diff --git a/mesalib/src/gallium/Automake.inc b/mesalib/src/gallium/Automake.inc index 4600b9c5b..e70a1363e 100644 --- a/mesalib/src/gallium/Automake.inc +++ b/mesalib/src/gallium/Automake.inc @@ -61,7 +61,7 @@ GALLIUM_DRI_LINKER_FLAGS = \ if HAVE_LD_VERSION_SCRIPT GALLIUM_DRI_LINKER_FLAGS += \ - -Wl,--version-script=$(top_srcdir)/src/gallium/targets/dri.sym + -Wl,--version-script=$(top_srcdir)/src/gallium/targets/dri/dri.sym endif diff --git a/mesalib/src/gallium/SConscript b/mesalib/src/gallium/SConscript index 598b2f1ec..df71b9aea 100644 --- a/mesalib/src/gallium/SConscript +++ b/mesalib/src/gallium/SConscript @@ -108,7 +108,7 @@ if not env['embedded']: if env['dri']: SConscript([ 'targets/dri-swrast/SConscript', - 'targets/dri-vmwgfx/SConscript', + 'targets/dri/SConscript', ]) diff --git a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c index 0f52e18cc..b48708c2f 100644 --- a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c +++ b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c @@ -90,7 +90,7 @@ query_new_value(struct hud_graph *gr) NUM_QUERIES); pipe->destroy_query(pipe, info->query[info->head]); info->query[info->head] = - pipe->create_query(pipe, info->query_type); + pipe->create_query(pipe, info->query_type, 0); } else { /* the last query is busy, we need to add a new one we can use @@ -98,7 +98,7 @@ query_new_value(struct hud_graph *gr) info->head = (info->head+1) % NUM_QUERIES; if (!info->query[info->head]) { info->query[info->head] = - pipe->create_query(pipe, info->query_type); + pipe->create_query(pipe, info->query_type, 0); } } break; @@ -119,7 +119,7 @@ query_new_value(struct hud_graph *gr) else { /* initialize */ info->last_time = now; - info->query[info->head] = pipe->create_query(pipe, info->query_type); + info->query[info->head] = pipe->create_query(pipe, info->query_type, 0); pipe->begin_query(pipe, info->query[info->head]); } } diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index 7b058fe22..db0d1b894 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -325,7 +325,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) } if (pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) && - pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) { + pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) { ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe); } diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.c b/mesalib/src/gallium/auxiliary/util/u_draw.c index 83d9284b8..b9f8fcd3c 100644 --- a/mesalib/src/gallium/auxiliary/util/u_draw.c +++ b/mesalib/src/gallium/auxiliary/util/u_draw.c @@ -27,6 +27,7 @@ #include "util/u_debug.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_format.h" #include "util/u_draw.h" @@ -123,3 +124,45 @@ util_draw_max_index( return max_index + 1; } + + +/* This extracts the draw arguments from the info_in->indirect resource, + * puts them into a new instance of pipe_draw_info, and calls draw_vbo on it. + */ +void +util_draw_indirect(struct pipe_context *pipe, + const struct pipe_draw_info *info_in) +{ + struct pipe_draw_info info; + struct pipe_transfer *transfer; + uint32_t *params; + const unsigned num_params = info_in->indexed ? 5 : 4; + + assert(info_in->indirect); + assert(!info_in->count_from_stream_output); + + memcpy(&info, info_in, sizeof(info)); + + params = (uint32_t *) + pipe_buffer_map_range(pipe, + info_in->indirect, + info_in->indirect_offset, + num_params * sizeof(uint32_t), + PIPE_TRANSFER_READ, + &transfer); + if (!transfer) { + debug_printf("%s: failed to map indirect buffer\n", __FUNCTION__); + return; + } + + info.count = params[0]; + info.instance_count = params[1]; + info.start = params[2]; + info.index_bias = info_in->indexed ? params[3] : 0; + info.start_instance = info_in->indexed ? params[4] : params[3]; + info.indirect = NULL; + + pipe_buffer_unmap(pipe, transfer); + + pipe->draw_vbo(pipe, &info); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.h b/mesalib/src/gallium/auxiliary/util/u_draw.h index 5a7ead27e..9fc3e9924 100644 --- a/mesalib/src/gallium/auxiliary/util/u_draw.h +++ b/mesalib/src/gallium/auxiliary/util/u_draw.h @@ -142,6 +142,14 @@ util_draw_range_elements(struct pipe_context *pipe, } +/* This converts an indirect draw into a direct draw by mapping the indirect + * buffer, extracting its arguments, and calling pipe->draw_vbo. + */ +void +util_draw_indirect(struct pipe_context *pipe, + const struct pipe_draw_info *info); + + unsigned util_draw_max_index( const struct pipe_vertex_buffer *vertex_buffers, diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c index 12f1d2d6e..e6614d5d2 100644 --- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c +++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c @@ -759,6 +759,9 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) util_dump_member(stream, ptr, state, count_from_stream_output); + util_dump_member(stream, ptr, state, indirect); + util_dump_member(stream, uint, state, indirect_offset); + util_dump_struct_end(stream); } diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.c b/mesalib/src/gallium/auxiliary/util/u_vbuf.c index 0c9c349e0..c475ee1b3 100644 --- a/mesalib/src/gallium/auxiliary/util/u_vbuf.c +++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.c @@ -1013,22 +1013,23 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr) static void u_vbuf_get_minmax_index(struct pipe_context *pipe, struct pipe_index_buffer *ib, - const struct pipe_draw_info *info, + boolean primitive_restart, + unsigned restart_index, + unsigned start, unsigned count, int *out_min_index, int *out_max_index) { struct pipe_transfer *transfer = NULL; const void *indices; unsigned i; - unsigned restart_index = info->restart_index; if (ib->user_buffer) { indices = (uint8_t*)ib->user_buffer + - ib->offset + info->start * ib->index_size; + ib->offset + start * ib->index_size; } else { indices = pipe_buffer_map_range(pipe, ib->buffer, - ib->offset + info->start * ib->index_size, - info->count * ib->index_size, + ib->offset + start * ib->index_size, + count * ib->index_size, PIPE_TRANSFER_READ, &transfer); } @@ -1037,8 +1038,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, const unsigned *ui_indices = (const unsigned*)indices; unsigned max_ui = 0; unsigned min_ui = ~0U; - if (info->primitive_restart) { - for (i = 0; i < info->count; i++) { + if (primitive_restart) { + for (i = 0; i < count; i++) { if (ui_indices[i] != restart_index) { if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; @@ -1046,7 +1047,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, } } else { - for (i = 0; i < info->count; i++) { + for (i = 0; i < count; i++) { if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; } @@ -1059,8 +1060,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, const unsigned short *us_indices = (const unsigned short*)indices; unsigned max_us = 0; unsigned min_us = ~0U; - if (info->primitive_restart) { - for (i = 0; i < info->count; i++) { + if (primitive_restart) { + for (i = 0; i < count; i++) { if (us_indices[i] != restart_index) { if (us_indices[i] > max_us) max_us = us_indices[i]; if (us_indices[i] < min_us) min_us = us_indices[i]; @@ -1068,7 +1069,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, } } else { - for (i = 0; i < info->count; i++) { + for (i = 0; i < count; i++) { if (us_indices[i] > max_us) max_us = us_indices[i]; if (us_indices[i] < min_us) min_us = us_indices[i]; } @@ -1081,8 +1082,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, const unsigned char *ub_indices = (const unsigned char*)indices; unsigned max_ub = 0; unsigned min_ub = ~0U; - if (info->primitive_restart) { - for (i = 0; i < info->count; i++) { + if (primitive_restart) { + for (i = 0; i < count; i++) { if (ub_indices[i] != restart_index) { if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; @@ -1090,7 +1091,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, } } else { - for (i = 0; i < info->count; i++) { + for (i = 0; i < count; i++) { if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; } @@ -1132,6 +1133,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) uint32_t used_vb_mask = mgr->ve->used_vb_mask; uint32_t user_vb_mask = mgr->user_vb_mask & used_vb_mask; uint32_t incompatible_vb_mask = mgr->incompatible_vb_mask & used_vb_mask; + struct pipe_draw_info new_info; /* Normal draw. No fallback and no user buffers. */ if (!incompatible_vb_mask && @@ -1147,33 +1149,62 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) return; } - if (info->indexed) { + new_info = *info; + + /* Fallback. We need to know all the parameters. */ + if (new_info.indirect) { + struct pipe_transfer *transfer = NULL; + int *data; + + if (new_info.indexed) { + data = pipe_buffer_map_range(pipe, new_info.indirect, + new_info.indirect_offset, 20, + PIPE_TRANSFER_READ, &transfer); + new_info.index_bias = data[3]; + new_info.start_instance = data[4]; + } + else { + data = pipe_buffer_map_range(pipe, new_info.indirect, + new_info.indirect_offset, 16, + PIPE_TRANSFER_READ, &transfer); + new_info.start_instance = data[3]; + } + + new_info.count = data[0]; + new_info.instance_count = data[1]; + new_info.start = data[2]; + pipe_buffer_unmap(pipe, transfer); + new_info.indirect = NULL; + } + + if (new_info.indexed) { /* See if anything needs to be done for per-vertex attribs. */ if (u_vbuf_need_minmax_index(mgr)) { int max_index; - if (info->max_index != ~0) { - min_index = info->min_index; - max_index = info->max_index; + if (new_info.max_index != ~0) { + min_index = new_info.min_index; + max_index = new_info.max_index; } else { - u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info, - &min_index, &max_index); + u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, + new_info.primitive_restart, + new_info.restart_index, new_info.start, + new_info.count, &min_index, &max_index); } assert(min_index <= max_index); - start_vertex = min_index + info->index_bias; + start_vertex = min_index + new_info.index_bias; num_vertices = max_index + 1 - min_index; /* Primitive restart doesn't work when unrolling indices. * We would have to break this drawing operation into several ones. */ /* Use some heuristic to see if unrolling indices improves * performance. */ - if (!info->primitive_restart && - num_vertices > info->count*2 && - num_vertices-info->count > 32 && + if (!new_info.primitive_restart && + num_vertices > new_info.count*2 && + num_vertices - new_info.count > 32 && !u_vbuf_mapping_vertex_buffer_blocks(mgr)) { - /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/ unroll_indices = TRUE; user_vb_mask &= ~(mgr->nonzero_stride_vb_mask & mgr->ve->noninstance_vb_mask_any); @@ -1185,8 +1216,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) min_index = 0; } } else { - start_vertex = info->start; - num_vertices = info->count; + start_vertex = new_info.start; + num_vertices = new_info.count; min_index = 0; } @@ -1195,13 +1226,21 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) incompatible_vb_mask || mgr->ve->incompatible_elem_mask) { if (!u_vbuf_translate_begin(mgr, start_vertex, num_vertices, - info->start_instance, info->instance_count, - info->start, info->count, min_index, - unroll_indices)) { + new_info.start_instance, + new_info.instance_count, new_info.start, + new_info.count, min_index, unroll_indices)) { debug_warn_once("u_vbuf_translate_begin() failed"); return; } + if (unroll_indices) { + new_info.indexed = FALSE; + new_info.index_bias = 0; + new_info.min_index = 0; + new_info.max_index = new_info.count - 1; + new_info.start = 0; + } + user_vb_mask &= ~(incompatible_vb_mask | mgr->ve->incompatible_vb_mask_all); } @@ -1209,8 +1248,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) /* Upload user buffers. */ if (user_vb_mask) { if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices, - info->start_instance, - info->instance_count) != PIPE_OK) { + new_info.start_instance, + new_info.instance_count) != PIPE_OK) { debug_warn_once("u_vbuf_upload_buffers() failed"); return; } @@ -1242,18 +1281,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) u_upload_unmap(mgr->uploader); u_vbuf_set_driver_vertex_buffers(mgr); - if (unlikely(unroll_indices)) { - struct pipe_draw_info new_info = *info; - new_info.indexed = FALSE; - new_info.index_bias = 0; - new_info.min_index = 0; - new_info.max_index = info->count - 1; - new_info.start = 0; - - pipe->draw_vbo(pipe, &new_info); - } else { - pipe->draw_vbo(pipe, info); - } + pipe->draw_vbo(pipe, &new_info); if (mgr->using_translate) { u_vbuf_translate_end(mgr); diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 8e91a1e67..cdb34cc69 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -41,8 +41,7 @@ process_parameters(exec_list *instructions, exec_list *actual_parameters, { unsigned count = 0; - foreach_list (n, parameters) { - ast_node *const ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, parameters) { ir_rvalue *result = ast->hir(instructions, state); ir_constant *const constant = result->constant_expression_value(); @@ -82,9 +81,7 @@ prototype_string(const glsl_type *return_type, const char *name, ralloc_asprintf_append(&str, "%s(", name); const char *comma = ""; - foreach_list(node, parameters) { - const ir_variable *const param = (ir_variable *) node; - + foreach_in_list(const ir_variable, param, parameters) { ralloc_asprintf_append(&str, "%s%s", comma, param->type->name); comma = ", "; } @@ -158,12 +155,11 @@ verify_parameter_modes(_mesa_glsl_parse_state *state, exec_node *actual_ir_node = actual_ir_parameters.head; exec_node *actual_ast_node = actual_ast_parameters.head; - foreach_list(formal_node, &sig->parameters) { + foreach_in_list(const ir_variable, formal, &sig->parameters) { /* The lists must be the same length. */ assert(!actual_ir_node->is_tail_sentinel()); assert(!actual_ast_node->is_tail_sentinel()); - const ir_variable *const formal = (ir_variable *) formal_node; const ir_rvalue *const actual = (ir_rvalue *) actual_ir_node; const ast_expression *const actual_ast = exec_node_data(ast_expression, actual_ast_node, link); @@ -478,9 +474,7 @@ print_function_prototypes(_mesa_glsl_parse_state *state, YYLTYPE *loc, if (f == NULL) return; - foreach_list (node, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) node; - + foreach_in_list(ir_function_signature, sig, &f->signatures) { if (sig->is_builtin() && !sig->is_builtin_available(state)) continue; @@ -690,8 +684,7 @@ process_vec_mat_constructor(exec_list *instructions, bool all_parameters_are_constant = true; /* Type cast each parameter and, if possible, fold constants. */ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; + foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { ir_rvalue *result = ir; /* Apply implicit conversions (not the scalar constructor rules!). See @@ -749,8 +742,7 @@ process_vec_mat_constructor(exec_list *instructions, instructions->push_tail(var); int i = 0; - foreach_list(node, &actual_parameters) { - ir_rvalue *rhs = (ir_rvalue *) node; + foreach_in_list(ir_rvalue, rhs, &actual_parameters) { ir_rvalue *lhs = new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); @@ -819,8 +811,7 @@ process_array_constructor(exec_list *instructions, bool all_parameters_are_constant = true; /* Type cast each parameter and, if possible, fold constants. */ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; + foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { ir_rvalue *result = ir; /* Apply implicit conversions (not the scalar constructor rules!). See @@ -870,8 +861,7 @@ process_array_constructor(exec_list *instructions, instructions->push_tail(var); int i = 0; - foreach_list(node, &actual_parameters) { - ir_rvalue *rhs = (ir_rvalue *) node; + foreach_in_list(ir_rvalue, rhs, &actual_parameters) { ir_rvalue *lhs = new(ctx) ir_dereference_array(var, new(ctx) ir_constant(i)); @@ -892,8 +882,8 @@ static ir_constant * constant_record_constructor(const glsl_type *constructor_type, exec_list *parameters, void *mem_ctx) { - foreach_list(node, parameters) { - ir_constant *constant = ((ir_instruction *) node)->as_constant(); + foreach_in_list(ir_instruction, node, parameters) { + ir_constant *constant = node->as_constant(); if (constant == NULL) return NULL; node->replace_with(constant); @@ -967,8 +957,7 @@ emit_inline_vector_constructor(const glsl_type *type, memset(&data, 0, sizeof(data)); - foreach_list(node, parameters) { - ir_rvalue *param = (ir_rvalue *) node; + foreach_in_list(ir_rvalue, param, parameters) { unsigned rhs_components = param->type->components(); /* Do not try to assign more components to the vector than it has! @@ -1025,8 +1014,7 @@ emit_inline_vector_constructor(const glsl_type *type, } base_component = 0; - foreach_list(node, parameters) { - ir_rvalue *param = (ir_rvalue *) node; + foreach_in_list(ir_rvalue, param, parameters) { unsigned rhs_components = param->type->components(); /* Do not try to assign more components to the vector than it has! @@ -1312,8 +1300,7 @@ emit_inline_matrix_constructor(const glsl_type *type, unsigned col_idx = 0; unsigned row_idx = 0; - foreach_list (node, parameters) { - ir_rvalue *const rhs = (ir_rvalue *) node; + foreach_in_list(ir_rvalue, rhs, parameters) { const unsigned components_remaining_this_column = rows - row_idx; unsigned rhs_components = rhs->type->components(); unsigned rhs_base = 0; @@ -1558,8 +1545,7 @@ ast_function_expression::hir(exec_list *instructions, unsigned nonmatrix_parameters = 0; exec_list actual_parameters; - foreach_list (n, &this->expressions) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, &this->expressions) { ir_rvalue *result = ast->hir(instructions, state); /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: @@ -1639,9 +1625,7 @@ ast_function_expression::hir(exec_list *instructions, * need to break them up into a series of column vectors. */ if (constructor_type->base_type != GLSL_TYPE_FLOAT) { - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *matrix = (ir_rvalue *) n; - + foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) { if (!matrix->type->is_matrix()) continue; @@ -1665,9 +1649,7 @@ ast_function_expression::hir(exec_list *instructions, bool all_parameters_are_constant = true; /* Type cast each parameter and, if possible, fold constants.*/ - foreach_list_safe(n, &actual_parameters) { - ir_rvalue *ir = (ir_rvalue *) n; - + foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { const glsl_type *desired_type = glsl_type::get_instance(constructor_type->base_type, ir->type->vector_elements, diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 042ef243b..885bee547 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -112,8 +112,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) * applications depend on this behavior, and it matches what nearly all * other drivers do. */ - foreach_list_safe(node, instructions) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list_safe(ir_instruction, node, instructions) { + ir_variable *const var = node->as_variable(); if (var == NULL) continue; @@ -4210,10 +4210,8 @@ ast_function_definition::hir(exec_list *instructions, * Add these to the symbol table. */ state->symbols->push_scope(); - foreach_list(n, &signature->parameters) { - ir_variable *const var = ((ir_instruction *) n)->as_variable(); - - assert(var != NULL); + foreach_in_list(ir_variable, var, &signature->parameters) { + assert(var->as_variable() != NULL); /* The only way a parameter would "exist" is if two parameters have * the same name. @@ -5009,7 +5007,7 @@ ast_process_structure_or_interface_block(exec_list *instructions, * 'declarations' list in each of the elements. */ foreach_list_typed (ast_declarator_list, decl_list, link, declarations) { - foreach_list_const (decl_ptr, & decl_list->declarations) { + foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) { decl_count++; } } @@ -5621,8 +5619,8 @@ ast_interface_block::hir(exec_list *instructions, * thinking there are conflicting definitions of gl_PerVertex in the * shader. */ - foreach_list_safe(node, instructions) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list_safe(ir_instruction, node, instructions) { + ir_variable *const var = node->as_variable(); if (var != NULL && var->get_interface_type() == earlier_per_vertex && var->data.mode == var_mode) { @@ -5678,8 +5676,8 @@ ast_gs_input_layout::hir(exec_list *instructions, /* If any shader inputs occurred before this declaration and did not * specify an array size, their size is determined now. */ - foreach_list (node, instructions) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, instructions) { + ir_variable *var = node->as_variable(); if (var == NULL || var->data.mode != ir_var_shader_in) continue; @@ -5796,8 +5794,8 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, YYLTYPE loc; memset(&loc, 0, sizeof(loc)); - foreach_list(node, instructions) { - ir_variable *var = ((ir_instruction *)node)->as_variable(); + foreach_in_list(ir_instruction, node, instructions) { + ir_variable *var = node->as_variable(); if (!var || !var->data.assigned) continue; @@ -5886,8 +5884,8 @@ remove_per_vertex_blocks(exec_list *instructions, /* Remove any ir_variable declarations that refer to the interface block * we're removing. */ - foreach_list_safe(node, instructions) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list_safe(ir_instruction, node, instructions) { + ir_variable *const var = node->as_variable(); if (var != NULL && var->get_interface_type() == per_vertex && var->data.mode == mode) { state->symbols->disable_variable(var->name); diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp index 017f23d0e..de4c1a410 100644 --- a/mesalib/src/glsl/ast_type.cpp +++ b/mesalib/src/glsl/ast_type.cpp @@ -122,18 +122,28 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, ubo_binding_mask.flags.q.explicit_binding = 1; ubo_binding_mask.flags.q.explicit_offset = 1; + ast_type_qualifier stream_layout_mask; + stream_layout_mask.flags.i = 0; + stream_layout_mask.flags.q.stream = 1; + /* Uniform block layout qualifiers get to overwrite each * other (rightmost having priority), while all other * qualifiers currently don't allow duplicates. - * - * Geometry shaders can have several layout qualifiers + */ + ast_type_qualifier allowed_duplicates_mask; + allowed_duplicates_mask.flags.i = + ubo_mat_mask.flags.i | + ubo_layout_mask.flags.i | + ubo_binding_mask.flags.i; + + /* Geometry shaders can have several layout qualifiers * assigning different stream values. */ + if (state->stage == MESA_SHADER_GEOMETRY) + allowed_duplicates_mask.flags.i |= + stream_layout_mask.flags.i; - if ((state->stage != MESA_SHADER_GEOMETRY) && - (this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i | - ubo_layout_mask.flags.i | - ubo_binding_mask.flags.i)) != 0) { + if ((this->flags.i & q.flags.i & ~allowed_duplicates_mask.flags.i) != 0) { _mesa_glsl_error(loc, state, "duplicate layout qualifiers used"); return false; diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp index 94b578107..258b83142 100644 --- a/mesalib/src/glsl/builtin_functions.cpp +++ b/mesalib/src/glsl/builtin_functions.cpp @@ -2575,8 +2575,7 @@ builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params) { exec_list actual_params; - foreach_list(node, ¶ms) { - ir_variable *var = (ir_variable *) node; + foreach_in_list(ir_variable, var, ¶ms) { actual_params.push_tail(var_ref(var)); } diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index 9f9571619..34973023f 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -815,6 +815,8 @@ builtin_variable_generator::generate_vs_special_vars() add_system_value(SYSTEM_VALUE_INSTANCE_ID, int_t, "gl_InstanceID"); if (state->AMD_vertex_shader_layer_enable) add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer"); + if (state->AMD_vertex_shader_viewport_index_enable) + add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); if (compatibility) { add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex"); add_input(VERT_ATTRIB_NORMAL, vec3_t, "gl_Normal"); diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index d8c395778..ccf810559 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -2133,6 +2133,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio if (extensions->AMD_vertex_shader_layer) add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1); + if (extensions->AMD_vertex_shader_viewport_index) + add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1); + if (extensions->ARB_shading_language_420pack) add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1); diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 11a9a4320..b327c2b43 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -552,6 +552,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(AMD_shader_stencil_export, true, false, ARB_shader_stencil_export), EXT(AMD_shader_trinary_minmax, true, false, dummy_true), EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer), + EXT(AMD_vertex_shader_viewport_index, true, false, AMD_vertex_shader_viewport_index), EXT(EXT_separate_shader_objects, false, true, dummy_true), EXT(EXT_shader_integer_mix, true, true, EXT_shader_integer_mix), EXT(EXT_texture_array, true, false, EXT_texture_array), @@ -844,8 +845,7 @@ ast_compound_statement::print(void) const { printf("{\n"); - foreach_list_const(n, &this->statements) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, &this->statements) { ast->print(); } @@ -924,11 +924,10 @@ ast_expression::print(void) const subexpressions[0]->print(); printf("( "); - foreach_list_const (n, &this->expressions) { - if (n != this->expressions.get_head()) + foreach_list_typed (ast_node, ast, link, &this->expressions) { + if (&ast->link != this->expressions.get_head()) printf(", "); - ast_node *ast = exec_node_data(ast_node, n, link); ast->print(); } @@ -960,11 +959,10 @@ ast_expression::print(void) const case ast_sequence: { printf("( "); - foreach_list_const(n, & this->expressions) { - if (n != this->expressions.get_head()) + foreach_list_typed (ast_node, ast, link, & this->expressions) { + if (&ast->link != this->expressions.get_head()) printf(", "); - ast_node *ast = exec_node_data(ast_node, n, link); ast->print(); } printf(") "); @@ -973,11 +971,10 @@ ast_expression::print(void) const case ast_aggregate: { printf("{ "); - foreach_list_const(n, & this->expressions) { - if (n != this->expressions.get_head()) + foreach_list_typed (ast_node, ast, link, & this->expressions) { + if (&ast->link != this->expressions.get_head()) printf(", "); - ast_node *ast = exec_node_data(ast_node, n, link); ast->print(); } printf("} "); @@ -1027,8 +1024,7 @@ ast_function::print(void) const return_type->print(); printf(" %s (", identifier); - foreach_list_const(n, & this->parameters) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, & this->parameters) { ast->print(); } @@ -1105,11 +1101,10 @@ ast_declarator_list::print(void) const else printf("precise "); - foreach_list_const (ptr, & this->declarations) { - if (ptr != this->declarations.get_head()) + foreach_list_typed (ast_node, ast, link, & this->declarations) { + if (&ast->link != this->declarations.get_head()) printf(", "); - ast_node *ast = exec_node_data(ast_node, ptr, link); ast->print(); } @@ -1241,8 +1236,7 @@ ast_case_label::ast_case_label(ast_expression *test_value) void ast_case_label_list::print(void) const { - foreach_list_const(n, & this->labels) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, & this->labels) { ast->print(); } printf("\n"); @@ -1257,8 +1251,7 @@ ast_case_label_list::ast_case_label_list(void) void ast_case_statement::print(void) const { labels->print(); - foreach_list_const(n, & this->stmts) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, & this->stmts) { ast->print(); printf("\n"); } @@ -1273,8 +1266,7 @@ ast_case_statement::ast_case_statement(ast_case_label_list *labels) void ast_case_statement_list::print(void) const { - foreach_list_const(n, & this->cases) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, & this->cases) { ast->print(); } } @@ -1344,8 +1336,7 @@ void ast_struct_specifier::print(void) const { printf("struct %s { ", name); - foreach_list_const(n, &this->declarations) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, &this->declarations) { ast->print(); } printf("} "); @@ -1456,8 +1447,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, } if (dump_ast) { - foreach_list_const(n, &state->translation_unit) { - ast_node *ast = exec_node_data(ast_node, n, link); + foreach_list_typed(ast_node, ast, link, &state->translation_unit) { ast->print(); } printf("\n\n"); diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index a0af965fd..17918163e 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -461,6 +461,8 @@ struct _mesa_glsl_parse_state { bool AMD_shader_trinary_minmax_warn; bool AMD_vertex_shader_layer_enable; bool AMD_vertex_shader_layer_warn; + bool AMD_vertex_shader_viewport_index_enable; + bool AMD_vertex_shader_viewport_index_warn; bool EXT_separate_shader_objects_enable; bool EXT_separate_shader_objects_warn; bool EXT_shader_integer_mix_enable; diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 10c00068e..1d8bb6e7b 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -699,8 +699,7 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) if (type->is_array()) { this->array_elements = ralloc_array(this, ir_constant *, type->length); unsigned i = 0; - foreach_list(node, value_list) { - ir_constant *value = (ir_constant *) node; + foreach_in_list(ir_constant, value, value_list) { assert(value->as_constant() != NULL); this->array_elements[i++] = value; @@ -1001,9 +1000,7 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_STRUCT: { assert (src->type == this->type); this->components.make_empty(); - foreach_list(node, &src->components) { - ir_constant *const orig = (ir_constant *) node; - + foreach_in_list(ir_constant, orig, &src->components) { this->components.push_tail(orig->clone(this, NULL)); } break; @@ -1702,8 +1699,7 @@ ir_function::ir_function(const char *name) bool ir_function::has_user_signature() { - foreach_list(n, &this->signatures) { - ir_function_signature *const sig = (ir_function_signature *) n; + foreach_in_list(ir_function_signature, sig, &this->signatures) { if (!sig->is_builtin()) return true; } @@ -1724,8 +1720,8 @@ ir_rvalue::error_value(void *mem_ctx) void visit_exec_list(exec_list *list, ir_visitor *visitor) { - foreach_list_safe(n, list) { - ((ir_instruction *) n)->accept(visitor); + foreach_in_list_safe(ir_instruction, node, list) { + node->accept(visitor); } } @@ -1746,8 +1742,7 @@ steal_memory(ir_instruction *ir, void *new_ctx) */ if (constant != NULL) { if (constant->type->is_record()) { - foreach_list(n, &constant->components) { - ir_constant *field = (ir_constant *) n; + foreach_in_list(ir_constant, field, &constant->components) { steal_memory(field, ir); } } else if (constant->type->is_array()) { @@ -1764,8 +1759,8 @@ steal_memory(ir_instruction *ir, void *new_ctx) void reparent_ir(exec_list *list, void *mem_ctx) { - foreach_list(node, list) { - visit_tree((ir_instruction *) node, steal_memory, mem_ctx); + foreach_in_list(ir_instruction, node, list) { + visit_tree(node, steal_memory, mem_ctx); } } diff --git a/mesalib/src/glsl/ir_basic_block.cpp b/mesalib/src/glsl/ir_basic_block.cpp index 74ee4b696..15481aa47 100644 --- a/mesalib/src/glsl/ir_basic_block.cpp +++ b/mesalib/src/glsl/ir_basic_block.cpp @@ -56,8 +56,7 @@ void call_for_basic_blocks(exec_list *instructions, ir_instruction *leader = NULL; ir_instruction *last = NULL; - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, instructions) { ir_if *ir_if; ir_loop *ir_loop; ir_function *ir_function; @@ -88,9 +87,7 @@ void call_for_basic_blocks(exec_list *instructions, * and the body of main(). Perhaps those instructions ought * to live inside of main(). */ - foreach_list(func_node, &ir_function->signatures) { - ir_function_signature *ir_sig = (ir_function_signature *) func_node; - + foreach_in_list(ir_function_signature, ir_sig, &ir_function->signatures) { call_for_basic_blocks(&ir_sig->body, callback, data); } } diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index c00adc564..4b444d468 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -123,13 +123,11 @@ ir_if::clone(void *mem_ctx, struct hash_table *ht) const { ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht)); - foreach_list(n, &this->then_instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, &this->then_instructions) { new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht)); } - foreach_list(n, &this->else_instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, &this->else_instructions) { new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht)); } @@ -141,8 +139,7 @@ ir_loop::clone(void *mem_ctx, struct hash_table *ht) const { ir_loop *new_loop = new(mem_ctx) ir_loop(); - foreach_list(n, &this->body_instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, &this->body_instructions) { new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht)); } @@ -158,8 +155,7 @@ ir_call::clone(void *mem_ctx, struct hash_table *ht) const exec_list new_parameters; - foreach_list(n, &this->actual_parameters) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, &this->actual_parameters) { new_parameters.push_tail(ir->clone(mem_ctx, ht)); } @@ -278,10 +274,7 @@ ir_function::clone(void *mem_ctx, struct hash_table *ht) const { ir_function *copy = new(mem_ctx) ir_function(this->name); - foreach_list_const(node, &this->signatures) { - const ir_function_signature *const sig = - (const ir_function_signature *const) node; - + foreach_in_list(const ir_function_signature, sig, &this->signatures) { ir_function_signature *sig_copy = sig->clone(mem_ctx, ht); copy->add_signature(sig_copy); @@ -302,9 +295,7 @@ ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const /* Clone the instruction list. */ - foreach_list_const(node, &this->body) { - const ir_instruction *const inst = (const ir_instruction *) node; - + foreach_in_list(const ir_instruction, inst, &this->body) { ir_instruction *const inst_copy = inst->clone(mem_ctx, ht); copy->body.push_tail(inst_copy); } @@ -324,9 +315,7 @@ ir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) con /* Clone the parameter list, but NOT the body. */ - foreach_list_const(node, &this->parameters) { - const ir_variable *const param = (const ir_variable *) node; - + foreach_in_list(const ir_variable, param, &this->parameters) { assert(const_cast<ir_variable *>(param)->as_variable() != NULL); ir_variable *const param_copy = param->clone(mem_ctx, ht); @@ -430,8 +419,7 @@ clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in) struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); - foreach_list_const(node, in) { - const ir_instruction *const original = (ir_instruction *) node; + foreach_in_list(const ir_instruction, original, in) { ir_instruction *copy = original->clone(mem_ctx, ht); out->push_tail(copy); diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index 7b4a22df4..7f83eb134 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -1782,8 +1782,7 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s struct hash_table *variable_context, ir_constant **result) { - foreach_list(n, &body) { - ir_instruction *inst = (ir_instruction *)n; + foreach_in_list(ir_instruction, inst, &body) { switch(inst->ir_type) { /* (declare () type symbol) */ @@ -1922,8 +1921,8 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters, s */ const exec_node *parameter_info = origin ? origin->parameters.head : parameters.head; - foreach_list(n, actual_parameters) { - ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(variable_context); + foreach_in_list(ir_rvalue, n, actual_parameters) { + ir_constant *constant = n->constant_expression_value(variable_context); if (constant == NULL) { hash_table_dtor(deref_hash); return NULL; diff --git a/mesalib/src/glsl/ir_expression_flattening.cpp b/mesalib/src/glsl/ir_expression_flattening.cpp index 0b1ada519..c13ae811d 100644 --- a/mesalib/src/glsl/ir_expression_flattening.cpp +++ b/mesalib/src/glsl/ir_expression_flattening.cpp @@ -57,9 +57,7 @@ do_expression_flattening(exec_list *instructions, { ir_expression_flattening_visitor v(predicate); - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; - + foreach_in_list(ir_instruction, ir, instructions) { ir->accept(&v); } } diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index deec1dfe8..7d6c2f451 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -306,9 +306,7 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state, * multiple ways to apply these conversions to the actual arguments of a * call such that the call can be made to match multiple signatures." */ - foreach_list(n, &this->signatures) { - ir_function_signature *const sig = (ir_function_signature *) n; - + foreach_in_list(ir_function_signature, sig, &this->signatures) { /* Skip over any built-ins that aren't available in this shader. */ if (sig->is_builtin() && !sig->is_builtin_available(state)) continue; @@ -380,9 +378,7 @@ ir_function_signature * ir_function::exact_matching_signature(_mesa_glsl_parse_state *state, const exec_list *actual_parameters) { - foreach_list(n, &this->signatures) { - ir_function_signature *const sig = (ir_function_signature *) n; - + foreach_in_list(ir_function_signature, sig, &this->signatures) { /* Skip over any built-ins that aren't available in this shader. */ if (sig->is_builtin() && !sig->is_builtin_available(state)) continue; diff --git a/mesalib/src/glsl/ir_function_detect_recursion.cpp b/mesalib/src/glsl/ir_function_detect_recursion.cpp index 5813315b6..b2334d2e4 100644 --- a/mesalib/src/glsl/ir_function_detect_recursion.cpp +++ b/mesalib/src/glsl/ir_function_detect_recursion.cpp @@ -229,15 +229,13 @@ public: static void destroy_links(exec_list *list, function *f) { - foreach_list_safe(node, list) { - struct call_node *n = (struct call_node *) node; - + foreach_in_list_safe(call_node, node, list) { /* If this is the right function, remove it. Note that the loop cannot * terminate now. There can be multiple links to a function if it is * either called multiple times or calls multiple times. */ - if (n->func == f) - n->remove(); + if (node->func == f) + node->remove(); } } diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp index 3ca7a5887..be5b3eaa0 100644 --- a/mesalib/src/glsl/ir_hv_accept.cpp +++ b/mesalib/src/glsl/ir_hv_accept.cpp @@ -49,8 +49,7 @@ visit_list_elements(ir_hierarchical_visitor *v, exec_list *l, { ir_instruction *prev_base_ir = v->base_ir; - foreach_list_safe(n, l) { - ir_instruction *const ir = (ir_instruction *) n; + foreach_in_list_safe(ir_instruction, ir, l) { if (statement_list) v->base_ir = ir; ir_visitor_status s = ir->accept(v); diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 72ad4223f..bd398052c 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -67,8 +67,7 @@ _mesa_print_ir(FILE *f, exec_list *instructions, } fprintf(f, "(\n"); - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, instructions) { ir->fprint(f); if (ir->ir_type != ir_type_function) fprintf(f, "\n"); @@ -196,9 +195,7 @@ void ir_print_visitor::visit(ir_function_signature *ir) fprintf(f, "(parameters\n"); indentation++; - foreach_list(n, &ir->parameters) { - ir_variable *const inst = (ir_variable *) n; - + foreach_in_list(ir_variable, inst, &ir->parameters) { indent(); inst->accept(this); fprintf(f, "\n"); @@ -213,9 +210,7 @@ void ir_print_visitor::visit(ir_function_signature *ir) fprintf(f, "(\n"); indentation++; - foreach_list(n, &ir->body) { - ir_instruction *const inst = (ir_instruction *) n; - + foreach_in_list(ir_instruction, inst, &ir->body) { indent(); inst->accept(this); fprintf(f, "\n"); @@ -232,8 +227,7 @@ void ir_print_visitor::visit(ir_function *ir) { fprintf(f, "(function %s\n", ir->name); indentation++; - foreach_list(n, &ir->signatures) { - ir_function_signature *const sig = (ir_function_signature *) n; + foreach_in_list(ir_function_signature, sig, &ir->signatures) { indent(); sig->accept(this); fprintf(f, "\n"); @@ -457,9 +451,7 @@ ir_print_visitor::visit(ir_call *ir) if (ir->return_deref) ir->return_deref->accept(this); fprintf(f, " ("); - foreach_list(n, &ir->actual_parameters) { - ir_rvalue *const param = (ir_rvalue *) n; - + foreach_in_list(ir_rvalue, param, &ir->actual_parameters) { param->accept(this); } fprintf(f, "))\n"); @@ -504,9 +496,7 @@ ir_print_visitor::visit(ir_if *ir) fprintf(f, "(\n"); indentation++; - foreach_list(n, &ir->then_instructions) { - ir_instruction *const inst = (ir_instruction *) n; - + foreach_in_list(ir_instruction, inst, &ir->then_instructions) { indent(); inst->accept(this); fprintf(f, "\n"); @@ -521,9 +511,7 @@ ir_print_visitor::visit(ir_if *ir) fprintf(f, "(\n"); indentation++; - foreach_list(n, &ir->else_instructions) { - ir_instruction *const inst = (ir_instruction *) n; - + foreach_in_list(ir_instruction, inst, &ir->else_instructions) { indent(); inst->accept(this); fprintf(f, "\n"); @@ -543,9 +531,7 @@ ir_print_visitor::visit(ir_loop *ir) fprintf(f, "(loop (\n"); indentation++; - foreach_list(n, &ir->body_instructions) { - ir_instruction *const inst = (ir_instruction *) n; - + foreach_in_list(ir_instruction, inst, &ir->body_instructions) { indent(); inst->accept(this); fprintf(f, "\n"); diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index a178c82b5..4017bdd73 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -170,9 +170,8 @@ ir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr) return; } - foreach_list(n, &list->subexpressions) { - s_list *sub = SX_AS_LIST(n); - if (sub == NULL) + foreach_in_list(s_list, sub, &list->subexpressions) { + if (!sub->is_list()) continue; // not a (function ...); ignore it. s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head()); @@ -317,8 +316,7 @@ ir_reader::read_instructions(exec_list *instructions, s_expression *expr, return; } - foreach_list(n, &list->subexpressions) { - s_expression *sub = (s_expression *) n; + foreach_in_list(s_expression, sub, &list->subexpressions) { ir_instruction *ir = read_instruction(sub, loop_ctx); if (ir != NULL) { /* Global variable declarations should be moved to the top, before @@ -405,9 +403,8 @@ ir_reader::read_declaration(s_expression *expr) ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(), ir_var_auto); - foreach_list(n, &s_quals->subexpressions) { - s_symbol *qualifier = SX_AS_SYMBOL(n); - if (qualifier == NULL) { + foreach_in_list(s_symbol, qualifier, &s_quals->subexpressions) { + if (!qualifier->is_symbol()) { ir_read_error(expr, "qualifier list must contain only symbols"); return NULL; } @@ -664,11 +661,10 @@ ir_reader::read_call(s_expression *expr) exec_list parameters; - foreach_list(n, ¶ms->subexpressions) { - s_expression *expr = (s_expression *) n; - ir_rvalue *param = read_rvalue(expr); + foreach_in_list(s_expression, e, ¶ms->subexpressions) { + ir_rvalue *param = read_rvalue(e); if (param == NULL) { - ir_read_error(expr, "when reading parameter to function call"); + ir_read_error(e, "when reading parameter to function call"); return NULL; } parameters.push_tail(param); @@ -729,7 +725,7 @@ ir_reader::read_expression(s_expression *expr) } int num_operands = -3; /* skip "expression" <type> <operation> */ - foreach_list(n, &((s_list *) expr)->subexpressions) + foreach_in_list(s_expression, e, &((s_list *) expr)->subexpressions) ++num_operands; int expected_operands = ir_expression::get_num_operands(op); @@ -804,8 +800,7 @@ ir_reader::read_constant(s_expression *expr) if (type->is_array()) { unsigned elements_supplied = 0; exec_list elements; - foreach_list(n, &values->subexpressions) { - s_expression *elt = (s_expression *) n; + foreach_in_list(s_expression, elt, &values->subexpressions) { ir_constant *ir_elt = read_constant(elt); if (ir_elt == NULL) return NULL; @@ -825,14 +820,12 @@ ir_reader::read_constant(s_expression *expr) // Read in list of values (at most 16). unsigned k = 0; - foreach_list(n, &values->subexpressions) { + foreach_in_list(s_expression, expr, &values->subexpressions) { if (k >= 16) { ir_read_error(values, "expected at most 16 numbers"); return NULL; } - s_expression *expr = (s_expression *) n; - if (type->base_type == GLSL_TYPE_FLOAT) { s_number *value = SX_AS_NUMBER(expr); if (value == NULL) { diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index 0370170b3..34cdb1c98 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -123,8 +123,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir) ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_call *ir) { - foreach_list_safe(n, &ir->actual_parameters) { - ir_rvalue *param = (ir_rvalue *) n; + foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) { ir_rvalue *new_param = param; handle_rvalue(&new_param); diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 17a74ea55..271dbe096 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -172,9 +172,7 @@ ir_validate::visit_enter(ir_function *ir) /* Verify that all of the things stored in the list of signatures are, * in fact, function signatures. */ - foreach_list(node, &ir->signatures) { - ir_instruction *sig = (ir_instruction *) node; - + foreach_in_list(ir_instruction, sig, &ir->signatures) { if (sig->ir_type != ir_type_function_signature) { printf("Non-signature in signature list of function `%s'\n", ir->name); @@ -816,9 +814,7 @@ validate_ir_tree(exec_list *instructions) v.run(instructions); - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; - + foreach_in_list(ir_instruction, ir, instructions) { visit_tree(ir, check_node_type, NULL); } #endif diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp index fbe4e7364..75699fd93 100644 --- a/mesalib/src/glsl/link_atomics.cpp +++ b/mesalib/src/glsl/link_atomics.cpp @@ -110,8 +110,8 @@ namespace { if (sh == NULL) continue; - foreach_list(node, sh->ir) { - ir_variable *var = ((ir_instruction *)node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *var = node->as_variable(); if (var && var->type->contains_atomic()) { unsigned id = 0; diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp index 56f3f207e..2ce9609b5 100644 --- a/mesalib/src/glsl/link_functions.cpp +++ b/mesalib/src/glsl/link_functions.cpp @@ -145,8 +145,7 @@ public: struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); exec_list formal_parameters; - foreach_list_const(node, &sig->parameters) { - const ir_instruction *const original = (ir_instruction *) node; + foreach_in_list(const ir_instruction, original, &sig->parameters) { assert(const_cast<ir_instruction *>(original)->as_variable()); ir_instruction *copy = original->clone(linked, ht); @@ -156,9 +155,7 @@ public: linked_sig->replace_parameters(&formal_parameters); if (sig->is_defined) { - foreach_list_const(node, &sig->body) { - const ir_instruction *const original = (ir_instruction *) node; - + foreach_in_list(const ir_instruction, original, &sig->body) { ir_instruction *copy = original->clone(linked, ht); linked_sig->body.push_tail(copy); } diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp index 52552cc68..0ce502d4f 100644 --- a/mesalib/src/glsl/link_interface_blocks.cpp +++ b/mesalib/src/glsl/link_interface_blocks.cpp @@ -259,8 +259,8 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog, if (shader_list[i] == NULL) continue; - foreach_list(node, shader_list[i]->ir) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, shader_list[i]->ir) { + ir_variable *var = node->as_variable(); if (!var) continue; @@ -316,8 +316,8 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog, const bool extra_array_level = consumer->Stage == MESA_SHADER_GEOMETRY; /* Add input interfaces from the consumer to the symbol table. */ - foreach_list(node, consumer->ir) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, consumer->ir) { + ir_variable *var = node->as_variable(); if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in) continue; @@ -325,8 +325,8 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog, } /* Verify that the producer's output interfaces match. */ - foreach_list(node, producer->ir) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, producer->ir) { + ir_variable *var = node->as_variable(); if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out) continue; @@ -359,8 +359,8 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog, continue; const gl_shader *stage = stages[i]; - foreach_list(node, stage->ir) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, stage->ir) { + ir_variable *var = node->as_variable(); if (!var || !var->get_interface_type() || var->data.mode != ir_var_uniform) continue; diff --git a/mesalib/src/glsl/link_uniform_initializers.cpp b/mesalib/src/glsl/link_uniform_initializers.cpp index d755cec98..c6fe6a9ad 100644 --- a/mesalib/src/glsl/link_uniform_initializers.cpp +++ b/mesalib/src/glsl/link_uniform_initializers.cpp @@ -242,8 +242,8 @@ link_set_uniform_initializers(struct gl_shader_program *prog) if (shader == NULL) continue; - foreach_list(node, shader->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, shader->ir) { + ir_variable *const var = node->as_variable(); if (!var || var->data.mode != ir_var_uniform) continue; diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 66f6d4db3..6c731976b 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -702,8 +702,8 @@ link_cross_validate_uniform_block(void *mem_ctx, static void link_update_uniform_buffer_variables(struct gl_shader *shader) { - foreach_list(node, shader->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, shader->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || !var->is_in_uniform_block()) continue; @@ -804,8 +804,8 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog) if (sh == NULL) continue; - foreach_list(node, sh->ir) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *var = node->as_variable(); if (var && var->data.mode == ir_var_uniform && var->type->contains_image()) { @@ -871,8 +871,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog) */ uniform_size.start_shader(); - foreach_list(node, sh->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || (var->data.mode != ir_var_uniform)) continue; @@ -923,8 +923,8 @@ link_assign_uniform_locations(struct gl_shader_program *prog) parcel.start_shader((gl_shader_stage)i); - foreach_list(node, prog->_LinkedShaders[i]->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || (var->data.mode != ir_var_uniform)) continue; diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 520a51a27..a3fc2ae34 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -175,8 +175,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog, /* Find all shader outputs in the "producer" stage. */ - foreach_list(node, producer->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, producer->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || (var->data.mode != ir_var_shader_out)) continue; @@ -212,8 +212,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog, * should be arrays and the type of the array element should match the type * of the corresponding producer output. */ - foreach_list(node, consumer->ir) { - ir_variable *const input = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, consumer->ir) { + ir_variable *const input = node->as_variable(); if ((input == NULL) || (input->data.mode != ir_var_shader_in)) continue; @@ -1121,8 +1121,8 @@ populate_consumer_input_sets(void *mem_ctx, exec_list *ir, 0, sizeof(consumer_inputs_with_locations[0]) * VARYING_SLOT_MAX); - foreach_list(node, ir) { - ir_variable *const input_var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + ir_variable *const input_var = node->as_variable(); if ((input_var != NULL) && (input_var->data.mode == ir_var_shader_in)) { if (input_var->type->is_interface()) @@ -1227,8 +1227,8 @@ canonicalize_shader_io(exec_list *ir, enum ir_variable_mode io_mode) ir_variable *var_table[MAX_PROGRAM_OUTPUTS * 4]; unsigned num_variables = 0; - foreach_list(node, ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + ir_variable *const var = node->as_variable(); if (var == NULL || var->data.mode != io_mode) continue; @@ -1339,9 +1339,8 @@ assign_varying_locations(struct gl_context *ctx, } if (producer) { - foreach_list(node, producer->ir) { - ir_variable *const output_var = - ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, producer->ir) { + ir_variable *const output_var = node->as_variable(); if ((output_var == NULL) || (output_var->data.mode != ir_var_shader_out)) @@ -1383,9 +1382,8 @@ assign_varying_locations(struct gl_context *ctx, * geometry) shader program. This means that locations must be assigned * for all the inputs. */ - foreach_list(node, consumer->ir) { - ir_variable *const input_var = - ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, consumer->ir) { + ir_variable *const input_var = node->as_variable(); if ((input_var == NULL) || (input_var->data.mode != ir_var_shader_in)) @@ -1450,8 +1448,8 @@ assign_varying_locations(struct gl_context *ctx, } if (consumer && producer) { - foreach_list(node, consumer->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, consumer->ir) { + ir_variable *const var = node->as_variable(); if (var && var->data.mode == ir_var_shader_in && var->data.is_unmatched_generic_inout) { @@ -1494,8 +1492,8 @@ check_against_output_limit(struct gl_context *ctx, { unsigned output_vectors = 0; - foreach_list(node, producer->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, producer->ir) { + ir_variable *const var = node->as_variable(); if (var && var->data.mode == ir_var_shader_out && var_counts_against_varying_limit(producer->Stage, var)) { @@ -1533,8 +1531,8 @@ check_against_input_limit(struct gl_context *ctx, { unsigned input_vectors = 0; - foreach_list(node, consumer->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, consumer->ir) { + ir_variable *const var = node->as_variable(); if (var && var->data.mode == ir_var_shader_in && var_counts_against_varying_limit(consumer->Stage, var)) { diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 3036ebcb3..d588bc63e 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -437,8 +437,8 @@ parse_program_resource_name(const GLchar *name, void link_invalidate_variable_locations(exec_list *ir) { - foreach_list(node, ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + ir_variable *const var = node->as_variable(); if (var == NULL) continue; @@ -692,8 +692,8 @@ cross_validate_globals(struct gl_shader_program *prog, if (shader_list[i] == NULL) continue; - foreach_list(node, shader_list[i]->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, shader_list[i]->ir) { + ir_variable *const var = node->as_variable(); if (var == NULL) continue; @@ -962,8 +962,7 @@ populate_symbol_table(gl_shader *sh) { sh->symbols = new(sh) glsl_symbol_table; - foreach_list(node, sh->ir) { - ir_instruction *const inst = (ir_instruction *) node; + foreach_in_list(ir_instruction, inst, sh->ir) { ir_variable *var; ir_function *func; @@ -1079,9 +1078,7 @@ move_non_declarations(exec_list *instructions, exec_node *last, temps = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); - foreach_list_safe(node, instructions) { - ir_instruction *inst = (ir_instruction *) node; - + foreach_in_list_safe(ir_instruction, inst, instructions) { if (inst->as_function()) continue; @@ -1603,8 +1600,8 @@ link_intrastage_shaders(void *mem_ctx, * across all shaders. */ for (unsigned i = 0; i < (num_shaders - 1); i++) { - foreach_list(node, shader_list[i]->ir) { - ir_function *const f = ((ir_instruction *) node)->as_function(); + foreach_in_list(ir_instruction, node, shader_list[i]->ir) { + ir_function *const f = node->as_function(); if (f == NULL) continue; @@ -1619,9 +1616,7 @@ link_intrastage_shaders(void *mem_ctx, if (other == NULL) continue; - foreach_list(n, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) n; - + foreach_in_list(ir_function_signature, sig, &f->signatures) { if (!sig->is_defined || sig->is_builtin()) continue; @@ -1735,8 +1730,7 @@ link_intrastage_shaders(void *mem_ctx, if (linked->Stage == MESA_SHADER_GEOMETRY) { unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); geom_array_resize_visitor input_resize_visitor(num_vertices, prog); - foreach_list(n, linked->ir) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, linked->ir) { ir->accept(&input_resize_visitor); } } @@ -1774,8 +1768,8 @@ update_array_sizes(struct gl_shader_program *prog) if (prog->_LinkedShaders[i] == NULL) continue; - foreach_list(node, prog->_LinkedShaders[i]->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || (var->data.mode != ir_var_uniform) || !var->type->is_array()) @@ -1797,8 +1791,8 @@ update_array_sizes(struct gl_shader_program *prog) if (prog->_LinkedShaders[j] == NULL) continue; - foreach_list(node2, prog->_LinkedShaders[j]->ir) { - ir_variable *other_var = ((ir_instruction *) node2)->as_variable(); + foreach_in_list(ir_instruction, node2, prog->_LinkedShaders[j]->ir) { + ir_variable *other_var = node2->as_variable(); if (!other_var) continue; @@ -1940,8 +1934,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog, unsigned num_attr = 0; - foreach_list(node, sh->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || (var->data.mode != (unsigned) direction)) continue; @@ -2159,8 +2153,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog, void demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode) { - foreach_list(node, sh->ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *const var = node->as_variable(); if ((var == NULL) || (var->data.mode != int(mode))) continue; @@ -2195,8 +2189,8 @@ store_fragdepth_layout(struct gl_shader_program *prog) * We're only interested in the cases where the variable is NOT removed * from the IR. */ - foreach_list(node, ir) { - ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + ir_variable *const var = node->as_variable(); if (var == NULL || var->data.mode != ir_var_shader_out) { continue; @@ -2327,8 +2321,8 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) total_image_units += sh->NumImages; if (i == MESA_SHADER_FRAGMENT) { - foreach_list(node, sh->ir) { - ir_variable *var = ((ir_instruction *)node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *var = node->as_variable(); if (var && var->data.mode == ir_var_shader_out) fragment_outputs += var->type->count_attribute_slots(); } @@ -2440,8 +2434,8 @@ check_explicit_uniform_locations(struct gl_context *ctx, if (!sh) continue; - foreach_list(node, sh->ir) { - ir_variable *var = ((ir_instruction *)node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *var = node->as_variable(); if ((var && var->data.mode == ir_var_uniform) && var->data.explicit_location) { if (!reserve_explicit_locations(prog, uniform_map, var)) diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h index 576bc14e4..922bd68ab 100644 --- a/mesalib/src/glsl/list.h +++ b/mesalib/src/glsl/list.h @@ -560,19 +560,30 @@ inline void exec_node::insert_before(exec_list *before) } #endif +#define foreach_in_list(__type, __inst, __list) \ + for (__type *(__inst) = (__type *)(__list)->head; \ + !(__inst)->is_tail_sentinel(); \ + (__inst) = (__type *)(__inst)->next) + +#define foreach_in_list_reverse(__type, __inst, __list) \ + for (__type *(__inst) = (__type *)(__list)->head; \ + !(__inst)->is_head_sentinel(); \ + (__inst) = (__type *)(__inst)->prev) + /** * This version is safe even if the current node is removed. */ -#define foreach_list_safe(__node, __list) \ - for (struct exec_node * __node = (__list)->head, * __next = __node->next \ - ; __next != NULL \ - ; __node = __next, __next = __next->next) - -#define foreach_list(__node, __list) \ - for (struct exec_node * __node = (__list)->head \ - ; (__node)->next != NULL \ - ; (__node) = (__node)->next) - +#define foreach_in_list_safe(__type, __node, __list) \ + for (__type *__node = (__type *)(__list)->head, \ + *__next = (__type *)__node->next; \ + __next != NULL; \ + __node = __next, __next = (__type *)__next->next) + +#define foreach_in_list_use_after(__type, __inst, __list) \ + __type *(__inst); \ + for ((__inst) = (__type *)(__list)->head; \ + !(__inst)->is_tail_sentinel(); \ + (__inst) = (__type *)(__inst)->next) /** * Iterate through two lists at once. Stops at the end of the shorter list. * @@ -589,21 +600,19 @@ inline void exec_node::insert_before(exec_list *before) __next1 = __next1->next, \ __next2 = __next2->next) -#define foreach_list_const(__node, __list) \ - for (const struct exec_node * __node = (__list)->head \ - ; (__node)->next != NULL \ - ; (__node) = (__node)->next) - #define foreach_list_typed(__type, __node, __field, __list) \ for (__type * __node = \ exec_node_data(__type, (__list)->head, __field); \ (__node)->__field.next != NULL; \ (__node) = exec_node_data(__type, (__node)->__field.next, __field)) -#define foreach_list_typed_const(__type, __node, __field, __list) \ - for (const __type * __node = \ - exec_node_data(__type, (__list)->head, __field); \ - (__node)->__field.next != NULL; \ - (__node) = exec_node_data(__type, (__node)->__field.next, __field)) +#define foreach_list_typed_safe(__type, __node, __field, __list) \ + for (__type * __node = \ + exec_node_data(__type, (__list)->head, __field), \ + * __next = \ + exec_node_data(__type, (__node)->__field.next, __field); \ + __next != NULL; \ + __node = __next, __next = \ + exec_node_data(__type, (__next)->__field.next, __field)) #endif /* LIST_CONTAINER_H */ diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp index 78ac30044..21d46ebce 100644 --- a/mesalib/src/glsl/loop_analysis.cpp +++ b/mesalib/src/glsl/loop_analysis.cpp @@ -227,8 +227,7 @@ loop_analysis::visit_enter(ir_call *) /* Mark every loop that we're currently analyzing as containing an ir_call * (even those at outer nesting levels). */ - foreach_list(node, &this->state) { - loop_variable_state *const ls = (loop_variable_state *) node; + foreach_in_list(loop_variable_state, ls, &this->state) { ls->contains_calls = true; } @@ -246,9 +245,7 @@ loop_analysis::visit(ir_dereference_variable *ir) bool nested = false; - foreach_list(node, &this->state) { - loop_variable_state *const ls = (loop_variable_state *) node; - + foreach_in_list(loop_variable_state, ls, &this->state) { ir_variable *var = ir->variable_referenced(); loop_variable *lv = ls->get_or_insert(var, this->in_assignee); @@ -288,10 +285,10 @@ loop_analysis::visit_leave(ir_loop *ir) if (ls->contains_calls) return visit_continue; - foreach_list(node, &ir->body_instructions) { + foreach_in_list(ir_instruction, node, &ir->body_instructions) { /* Skip over declarations at the start of a loop. */ - if (((ir_instruction *) node)->as_variable()) + if (node->as_variable()) continue; ir_if *if_stmt = ((ir_instruction *) node)->as_if(); @@ -303,9 +300,7 @@ loop_analysis::visit_leave(ir_loop *ir) } - foreach_list_safe(node, &ls->variables) { - loop_variable *lv = (loop_variable *) node; - + foreach_in_list_safe(loop_variable, lv, &ls->variables) { /* Move variables that are already marked as being loop constant to * a separate list. These trivially don't need to be tested. */ @@ -333,9 +328,7 @@ loop_analysis::visit_leave(ir_loop *ir) do { progress = false; - foreach_list_safe(node, &ls->variables) { - loop_variable *lv = (loop_variable *) node; - + foreach_in_list_safe(loop_variable, lv, &ls->variables) { if (lv->conditional_or_nested_assignment || (lv->num_assignments > 1)) continue; @@ -359,9 +352,7 @@ loop_analysis::visit_leave(ir_loop *ir) /* The remaining variables that are not loop invariant might be loop * induction variables. */ - foreach_list_safe(node, &ls->variables) { - loop_variable *lv = (loop_variable *) node; - + foreach_in_list_safe(loop_variable, lv, &ls->variables) { /* If there is more than one assignment to a variable, it cannot be a * loop induction variable. This isn't strictly true, but this is a * very simple induction variable detector, and it can't handle more @@ -402,8 +393,7 @@ loop_analysis::visit_leave(ir_loop *ir) * Also figure out which terminator (if any) produces the smallest * iteration count--this is the limiting terminator. */ - foreach_list(node, &ls->terminators) { - loop_terminator *t = (loop_terminator *) node; + foreach_in_list(loop_terminator, t, &ls->terminators) { ir_if *if_stmt = t->ir; /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care diff --git a/mesalib/src/glsl/loop_controls.cpp b/mesalib/src/glsl/loop_controls.cpp index 3db06ad18..36b49eb46 100644 --- a/mesalib/src/glsl/loop_controls.cpp +++ b/mesalib/src/glsl/loop_controls.cpp @@ -202,9 +202,7 @@ loop_control_visitor::visit_leave(ir_loop *ir) * bound, then that terminates the loop, so we don't even need the limiting * terminator. */ - foreach_list(node, &ls->terminators) { - loop_terminator *t = (loop_terminator *) node; - + foreach_in_list(loop_terminator, t, &ls->terminators) { if (t->iterations < 0) continue; diff --git a/mesalib/src/glsl/loop_unroll.cpp b/mesalib/src/glsl/loop_unroll.cpp index da532804a..ce795f6cd 100644 --- a/mesalib/src/glsl/loop_unroll.cpp +++ b/mesalib/src/glsl/loop_unroll.cpp @@ -347,10 +347,8 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) return visit_continue; } - foreach_list(node, &ir->body_instructions) { - /* recognize loops in the form produced by ir_lower_jumps */ - ir_instruction *cur_ir = (ir_instruction *) node; - + /* recognize loops in the form produced by ir_lower_jumps */ + foreach_in_list(ir_instruction, cur_ir, &ir->body_instructions) { /* Skip the limiting terminator, since it will go away when we * unroll. */ diff --git a/mesalib/src/glsl/lower_discard.cpp b/mesalib/src/glsl/lower_discard.cpp index f2757d120..b44d2a6d2 100644 --- a/mesalib/src/glsl/lower_discard.cpp +++ b/mesalib/src/glsl/lower_discard.cpp @@ -138,8 +138,8 @@ lower_discard(exec_list *instructions) static ir_discard * find_discard(exec_list &instructions) { - foreach_list(n, &instructions) { - ir_discard *ir = ((ir_instruction *) n)->as_discard(); + foreach_in_list(ir_instruction, node, &instructions) { + ir_discard *ir = node->as_discard(); if (ir != NULL) return ir; } diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp index f15b217e0..3232ce92a 100644 --- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp @@ -116,9 +116,7 @@ move_block_to_cond_assign(void *mem_ctx, exec_list *instructions, struct hash_table *ht) { - foreach_list_safe(node, instructions) { - ir_instruction *ir = (ir_instruction *) node; - + foreach_in_list_safe(ir_instruction, ir, instructions) { if (ir->ir_type == ir_type_assignment) { ir_assignment *assign = (ir_assignment *)ir; @@ -178,12 +176,10 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) ir_assignment *assign; /* Check that both blocks don't contain anything we can't support. */ - foreach_list(n, &ir->then_instructions) { - ir_instruction *then_ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, then_ir, &ir->then_instructions) { visit_tree(then_ir, check_control_flow, &found_control_flow); } - foreach_list(n, &ir->else_instructions) { - ir_instruction *else_ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, else_ir, &ir->else_instructions) { visit_tree(else_ir, check_control_flow, &found_control_flow); } if (found_control_flow) diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp index 02f65f097..ec7a0c537 100644 --- a/mesalib/src/glsl/lower_jumps.cpp +++ b/mesalib/src/glsl/lower_jumps.cpp @@ -500,16 +500,16 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor { /* Note: since visiting a node may change that node's next * pointer, we can't use visit_exec_list(), because * visit_exec_list() caches the node's next pointer before - * visiting it. So we use foreach_list() instead. + * visiting it. So we use foreach_in_list() instead. * - * foreach_list() isn't safe if the node being visited gets + * foreach_in_list() isn't safe if the node being visited gets * removed, but fortunately this visitor doesn't do that. */ block_record saved_block = this->block; this->block = block_record(); - foreach_list(node, list) { - ((ir_instruction *) node)->accept(this); + foreach_in_list(ir_instruction, node, list) { + node->accept(this); } block_record ret = this->block; this->block = saved_block; diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp index 04e0d36e6..7304c5139 100644 --- a/mesalib/src/glsl/lower_named_interface_blocks.cpp +++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp @@ -99,8 +99,8 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) * The interface block variables are stored in the interface_namespace * hash table so they can be used in the second pass. */ - foreach_list_safe(node, instructions) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list_safe(ir_instruction, node, instructions) { + ir_variable *var = node->as_variable(); if (!var || !var->is_interface_instance()) continue; diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp index eda56a97b..c72b80a32 100644 --- a/mesalib/src/glsl/lower_packed_varyings.cpp +++ b/mesalib/src/glsl/lower_packed_varyings.cpp @@ -242,8 +242,8 @@ lower_packed_varyings_visitor::lower_packed_varyings_visitor( void lower_packed_varyings_visitor::run(exec_list *instructions) { - foreach_list (node, instructions) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, instructions) { + ir_variable *var = node->as_variable(); if (var == NULL) continue; @@ -639,8 +639,7 @@ lower_packed_varyings_gs_splicer::lower_packed_varyings_gs_splicer( ir_visitor_status lower_packed_varyings_gs_splicer::visit_leave(ir_emit_vertex *ev) { - foreach_list(node, this->instructions) { - ir_instruction *ir = (ir_instruction *) node; + foreach_in_list(ir_instruction, ir, this->instructions) { ev->insert_before(ir->clone(this->mem_ctx, NULL)); } return visit_continue; diff --git a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp index fe6a3f208..0c3394a50 100644 --- a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -197,8 +197,7 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) ir_visitor_status ir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir) { - foreach_list_safe(n, &ir->actual_parameters) { - ir_rvalue *param = (ir_rvalue *) n; + foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) { ir_rvalue *new_param = convert_vector_extract_to_cond_assign(param); if (new_param != param) { diff --git a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp index b5bb00c30..4d4d2f17e 100644 --- a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp @@ -131,8 +131,7 @@ ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir) ir_visitor_status ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir) { - foreach_list_safe(n, &ir->actual_parameters) { - ir_rvalue *param = (ir_rvalue *) n; + foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) { ir_rvalue *new_param = convert_vector_extract_to_swizzle(param); if (new_param != param) { diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp index 97d3a57e9..ebb076b22 100644 --- a/mesalib/src/glsl/opt_array_splitting.cpp +++ b/mesalib/src/glsl/opt_array_splitting.cpp @@ -135,8 +135,7 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var) if (var->type->is_unsized_array()) return NULL; - foreach_list(n, &this->variable_list) { - variable_entry *entry = (variable_entry *) n; + foreach_in_list(variable_entry, entry, &this->variable_list) { if (entry->var == var) return entry; } @@ -213,8 +212,8 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions, * declarations, which need to be matched by name across shaders. */ if (!linked) { - foreach_list(node, instructions) { - ir_variable *var = ((ir_instruction *)node)->as_variable(); + foreach_in_list(ir_instruction, node, instructions) { + ir_variable *var = node->as_variable(); if (var) { variable_entry *entry = get_variable_entry(var); if (entry) @@ -224,9 +223,7 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions, } /* Trim out variables we found that we can't split. */ - foreach_list_safe(n, &variable_list) { - variable_entry *entry = (variable_entry *) n; - + foreach_in_list_safe(variable_entry, entry, &variable_list) { if (debug) { printf("array %s@%p: decl %d, split %d\n", entry->var->name, (void *) entry->var, entry->declaration, @@ -270,8 +267,7 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var) { assert(var); - foreach_list(n, this->variable_list) { - variable_entry *entry = (variable_entry *) n; + foreach_in_list(variable_entry, entry, this->variable_list) { if (entry->var == var) { return entry; } @@ -368,8 +364,7 @@ optimize_split_arrays(exec_list *instructions, bool linked) /* Replace the decls of the arrays to be split with their split * components. */ - foreach_list(n, &refs.variable_list) { - variable_entry *entry = (variable_entry *) n; + foreach_in_list(variable_entry, entry, &refs.variable_list) { const struct glsl_type *type = entry->var->type; const struct glsl_type *subtype; diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp index 18f5da689..c334e1276 100644 --- a/mesalib/src/glsl/opt_constant_propagation.cpp +++ b/mesalib/src/glsl/opt_constant_propagation.cpp @@ -172,8 +172,7 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue) channel = i; } - foreach_list(n, this->acp) { - acp_entry *entry = (acp_entry *) n; + foreach_in_list(acp_entry, entry, this->acp) { if (entry->var == deref->var && entry->write_mask & (1 << channel)) { found = entry; break; @@ -317,8 +316,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a constant of the original */ - foreach_list(n, orig_acp) { - acp_entry *a = (acp_entry *) n; + foreach_in_list(acp_entry, a, orig_acp) { this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); } @@ -333,8 +331,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_list(n, new_kills) { - kill_entry *k = (kill_entry *) n; + foreach_in_list(kill_entry, k, new_kills) { kill(k->var, k->write_mask); } } @@ -378,8 +375,7 @@ ir_constant_propagation_visitor::visit_enter(ir_loop *ir) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_list(n, new_kills) { - kill_entry *k = (kill_entry *) n; + foreach_in_list(kill_entry, k, new_kills) { kill(k->var, k->write_mask); } @@ -397,9 +393,7 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask) return; /* Remove any entries currently in the ACP for this kill. */ - foreach_list_safe(n, this->acp) { - acp_entry *entry = (acp_entry *) n; - + foreach_in_list_safe(acp_entry, entry, this->acp) { if (entry->var == var) { entry->write_mask &= ~write_mask; if (entry->write_mask == 0) @@ -410,9 +404,7 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask) /* Add this writemask of the variable to the list of killed * variables in this block. */ - foreach_list(n, this->kills) { - kill_entry *entry = (kill_entry *) n; - + foreach_in_list(kill_entry, entry, this->kills) { if (entry->var == var) { entry->write_mask |= write_mask; return; diff --git a/mesalib/src/glsl/opt_constant_variable.cpp b/mesalib/src/glsl/opt_constant_variable.cpp index 961b8aa06..7222eb92a 100644 --- a/mesalib/src/glsl/opt_constant_variable.cpp +++ b/mesalib/src/glsl/opt_constant_variable.cpp @@ -193,12 +193,10 @@ do_constant_variable_unlinked(exec_list *instructions) { bool progress = false; - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, instructions) { ir_function *f = ir->as_function(); if (f) { - foreach_list(signode, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) signode; + foreach_in_list(ir_function_signature, sig, &f->signatures) { if (do_constant_variable(&sig->body)) progress = true; } diff --git a/mesalib/src/glsl/opt_copy_propagation.cpp b/mesalib/src/glsl/opt_copy_propagation.cpp index 195cc8baa..5c65af66b 100644 --- a/mesalib/src/glsl/opt_copy_propagation.cpp +++ b/mesalib/src/glsl/opt_copy_propagation.cpp @@ -167,9 +167,7 @@ ir_copy_propagation_visitor::visit(ir_dereference_variable *ir) ir_variable *var = ir->var; - foreach_list(n, this->acp) { - acp_entry *entry = (acp_entry *) n; - + foreach_in_list(acp_entry, entry, this->acp) { if (var == entry->lhs) { ir->var = entry->rhs; this->progress = true; @@ -216,8 +214,7 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a copy of the original */ - foreach_list(n, orig_acp) { - acp_entry *a = (acp_entry *) n; + foreach_in_list(acp_entry, a, orig_acp) { this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs)); } @@ -232,8 +229,7 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_list(n, new_kills) { - kill_entry *k = (kill_entry *) n; + foreach_in_list(kill_entry, k, new_kills) { kill(k->var); } } @@ -276,8 +272,7 @@ ir_copy_propagation_visitor::visit_enter(ir_loop *ir) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_list(n, new_kills) { - kill_entry *k = (kill_entry *) n; + foreach_in_list(kill_entry, k, new_kills) { kill(k->var); } @@ -291,9 +286,7 @@ ir_copy_propagation_visitor::kill(ir_variable *var) assert(var != NULL); /* Remove any entries currently in the ACP for this kill. */ - foreach_list_safe(n, acp) { - acp_entry *entry = (acp_entry *) n; - + foreach_in_list_safe(acp_entry, entry, acp) { if (entry->lhs == var || entry->rhs == var) { entry->remove(); } diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp index 4d8f476a8..f5f59b7d3 100644 --- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp +++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp @@ -244,9 +244,7 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) /* Try to find ACP entries covering swizzle_chan[], hoping they're * the same source variable. */ - foreach_list(n, this->acp) { - acp_entry *entry = (acp_entry *) n; - + foreach_in_list(acp_entry, entry, this->acp) { if (var == entry->lhs) { for (int c = 0; c < chans; c++) { if (entry->write_mask & (1 << swizzle_chan[c])) { @@ -324,8 +322,7 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a copy of the original */ - foreach_list(n, orig_acp) { - acp_entry *a = (acp_entry *) n; + foreach_in_list(acp_entry, a, orig_acp) { this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); } @@ -343,8 +340,7 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions) /* Move the new kills into the parent block's list, removing them * from the parent's ACP list in the process. */ - foreach_list_safe(node, new_kills) { - kill_entry *k = (kill_entry *)node; + foreach_in_list_safe(kill_entry, k, new_kills) { kill(k); } } @@ -387,8 +383,7 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_list_safe(node, new_kills) { - kill_entry *k = (kill_entry *)node; + foreach_in_list_safe(kill_entry, k, new_kills) { kill(k); } @@ -400,9 +395,7 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir) void ir_copy_propagation_elements_visitor::kill(kill_entry *k) { - foreach_list_safe(node, acp) { - acp_entry *entry = (acp_entry *)node; - + foreach_in_list_safe(acp_entry, entry, acp) { if (entry->lhs == k->var) { entry->write_mask = entry->write_mask & ~k->write_mask; if (entry->write_mask == 0) { diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp index 1b8782bcb..0e720cc26 100644 --- a/mesalib/src/glsl/opt_cse.cpp +++ b/mesalib/src/glsl/opt_cse.cpp @@ -173,9 +173,7 @@ dump_ae(exec_list *ae) int i = 0; printf("CSE: AE contents:\n"); - foreach_list(node, ae) { - ae_entry *entry = (ae_entry *)node; - + foreach_in_list(ae_entry, entry, ae) { printf("CSE: AE %2d (%p): ", i, entry); (*entry->val)->print(); printf("\n"); @@ -254,9 +252,7 @@ is_cse_candidate(ir_rvalue *ir) ir_rvalue * cse_visitor::try_cse(ir_rvalue *rvalue) { - foreach_list(node, ae) { - ae_entry *entry = (ae_entry *)node; - + foreach_in_list(ae_entry, entry, ae) { if (debug) { printf("Comparing to AE %p: ", entry); (*entry->val)->print(); @@ -303,8 +299,7 @@ cse_visitor::try_cse(ir_rvalue *rvalue) * updated so that any further elimination from inside gets its new * assignments put before our new assignment. */ - foreach_list(fixup_node, ae) { - ae_entry *fixup_entry = (ae_entry *)fixup_node; + foreach_in_list(ae_entry, fixup_entry, ae) { if (contains_rvalue(assignment->rhs, *fixup_entry->val)) fixup_entry->base_ir = assignment; } diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp index af53d94fd..da90bfb40 100644 --- a/mesalib/src/glsl/opt_dead_code.cpp +++ b/mesalib/src/glsl/opt_dead_code.cpp @@ -129,12 +129,10 @@ do_dead_code_unlinked(exec_list *instructions) { bool progress = false; - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, instructions) { ir_function *f = ir->as_function(); if (f) { - foreach_list(signode, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) signode; + foreach_in_list(ir_function_signature, sig, &f->signatures) { /* The setting of the uniform_locations_assigned flag here is * irrelevent. If there is a uniform declaration encountered * inside the body of the function, something has already gone diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp index 88895fb0e..4770fcff2 100644 --- a/mesalib/src/glsl/opt_dead_code_local.cpp +++ b/mesalib/src/glsl/opt_dead_code_local.cpp @@ -70,9 +70,7 @@ public: void use_channels(ir_variable *const var, int used) { - foreach_list_safe(n, this->assignments) { - assignment_entry *entry = (assignment_entry *) n; - + foreach_in_list_safe(assignment_entry, entry, this->assignments) { if (entry->lhs == var) { if (var->type->is_scalar() || var->type->is_vector()) { if (debug) @@ -119,8 +117,7 @@ public: /* For the purpose of dead code elimination, emitting a vertex counts as * "reading" all of the currently assigned output variables. */ - foreach_list_safe(n, this->assignments) { - assignment_entry *entry = (assignment_entry *) n; + foreach_in_list_safe(assignment_entry, entry, this->assignments) { if (entry->lhs->data.mode == ir_var_shader_out) { if (debug) printf("kill %s\n", entry->lhs->name); @@ -196,9 +193,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) printf("looking for %s.0x%01x to remove\n", var->name, ir->write_mask); - foreach_list_safe(n, assignments) { - assignment_entry *entry = (assignment_entry *) n; - + foreach_in_list_safe(assignment_entry, entry, assignments) { if (entry->lhs != var) continue; @@ -258,9 +253,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) */ if (debug) printf("looking for %s to remove\n", var->name); - foreach_list_safe(n, assignments) { - assignment_entry *entry = (assignment_entry *) n; - + foreach_in_list_safe(assignment_entry, entry, assignments) { if (entry->lhs == var) { if (debug) printf("removing %s\n", var->name); @@ -280,9 +273,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) printf("add %s\n", var->name); printf("current entries\n"); - foreach_list(n, assignments) { - assignment_entry *entry = (assignment_entry *) n; - + foreach_in_list(assignment_entry, entry, assignments) { printf(" %s (0x%01x)\n", entry->lhs->name, entry->unused); } } diff --git a/mesalib/src/glsl/opt_dead_functions.cpp b/mesalib/src/glsl/opt_dead_functions.cpp index 8bb278e45..5dff16521 100644 --- a/mesalib/src/glsl/opt_dead_functions.cpp +++ b/mesalib/src/glsl/opt_dead_functions.cpp @@ -74,8 +74,7 @@ public: signature_entry * ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) { - foreach_list(n, &this->signature_list) { - signature_entry *entry = (signature_entry *) n; + foreach_in_list(signature_entry, entry, &this->signature_list) { if (entry->signature == sig) return entry; } @@ -123,9 +122,7 @@ do_dead_functions(exec_list *instructions) * the unused ones, and remove function definitions that have no more * signatures. */ - foreach_list_safe(n, &v.signature_list) { - signature_entry *entry = (signature_entry *) n; - + foreach_in_list_safe(signature_entry, entry, &v.signature_list) { if (!entry->used) { entry->signature->remove(); delete entry->signature; @@ -137,8 +134,7 @@ do_dead_functions(exec_list *instructions) /* We don't just do this above when we nuked a signature because of * const pointers. */ - foreach_list_safe(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list_safe(ir_instruction, ir, instructions) { ir_function *func = ir->as_function(); if (func && func->signatures.is_empty()) { diff --git a/mesalib/src/glsl/opt_flip_matrices.cpp b/mesalib/src/glsl/opt_flip_matrices.cpp index 9044fd680..04c6170b8 100644 --- a/mesalib/src/glsl/opt_flip_matrices.cpp +++ b/mesalib/src/glsl/opt_flip_matrices.cpp @@ -45,8 +45,7 @@ public: mvp_transpose = NULL; texmat_transpose = NULL; - foreach_list(n, instructions) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, instructions) { ir_variable *var = ir->as_variable(); if (!var) continue; diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp index 9649598dd..b84bb8e11 100644 --- a/mesalib/src/glsl/opt_function_inlining.cpp +++ b/mesalib/src/glsl/opt_function_inlining.cpp @@ -107,7 +107,7 @@ ir_call::generate_inline(ir_instruction *next_ir) ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); num_parameters = 0; - foreach_list(n, &this->callee->parameters) + foreach_in_list(ir_rvalue, param, &this->callee->parameters) num_parameters++; parameters = new ir_variable *[num_parameters]; @@ -159,8 +159,7 @@ ir_call::generate_inline(ir_instruction *next_ir) exec_list new_instructions; /* Generate the inlined body of the function to a new list */ - foreach_list(n, &callee->body) { - ir_instruction *ir = (ir_instruction *) n; + foreach_in_list(ir_instruction, ir, &callee->body) { ir_instruction *new_ir = ir->clone(ctx, ht); new_instructions.push_tail(new_ir); @@ -342,8 +341,7 @@ ir_variable_replacement_visitor::visit_leave(ir_dereference_record *ir) ir_visitor_status ir_variable_replacement_visitor::visit_leave(ir_call *ir) { - foreach_list_safe(n, &ir->actual_parameters) { - ir_rvalue *param = (ir_rvalue *) n; + foreach_in_list_safe(ir_rvalue, param, &ir->actual_parameters) { ir_rvalue *new_param = param; replace_rvalue(&new_param); diff --git a/mesalib/src/glsl/opt_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp index 1ec537b13..5e82fe93a 100644 --- a/mesalib/src/glsl/opt_structure_splitting.cpp +++ b/mesalib/src/glsl/opt_structure_splitting.cpp @@ -107,8 +107,7 @@ ir_structure_reference_visitor::get_variable_entry(ir_variable *var) || var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) return NULL; - foreach_list(n, &this->variable_list) { - variable_entry *entry = (variable_entry *) n; + foreach_in_list(variable_entry, entry, &this->variable_list) { if (entry->var == var) return entry; } @@ -209,8 +208,7 @@ ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) if (!var->type->is_record()) return NULL; - foreach_list(n, this->variable_list) { - variable_entry *entry = (variable_entry *) n; + foreach_in_list(variable_entry, entry, this->variable_list) { if (entry->var == var) { return entry; } @@ -315,9 +313,7 @@ do_structure_splitting(exec_list *instructions) visit_list_elements(&refs, instructions); /* Trim out variables we can't split. */ - foreach_list_safe(n, &refs.variable_list) { - variable_entry *entry = (variable_entry *) n; - + foreach_in_list_safe(variable_entry, entry, &refs.variable_list) { if (debug) { printf("structure %s@%p: decl %d, whole_access %d\n", entry->var->name, (void *) entry->var, entry->declaration, @@ -337,8 +333,7 @@ do_structure_splitting(exec_list *instructions) /* Replace the decls of the structures to be split with their split * components. */ - foreach_list_safe(n, &refs.variable_list) { - variable_entry *entry = (variable_entry *) n; + foreach_in_list_safe(variable_entry, entry, &refs.variable_list) { const struct glsl_type *type = entry->var->type; entry->mem_ctx = ralloc_parent(entry->var); diff --git a/mesalib/src/glsl/opt_vectorize.cpp b/mesalib/src/glsl/opt_vectorize.cpp index f9a3b6183..28534a86a 100644 --- a/mesalib/src/glsl/opt_vectorize.cpp +++ b/mesalib/src/glsl/opt_vectorize.cpp @@ -227,8 +227,7 @@ write_mask_to_swizzle(unsigned write_mask) case WRITEMASK_Z: return SWIZZLE_Z; case WRITEMASK_W: return SWIZZLE_W; } - assert(!"not reached"); - unreachable(); + unreachable("not reached"); } /** diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp index 6906ff0eb..1a28e1d52 100644 --- a/mesalib/src/glsl/s_expression.cpp +++ b/mesalib/src/glsl/s_expression.cpp @@ -162,8 +162,7 @@ void s_symbol::print() void s_list::print() { printf("("); - foreach_list(n, &this->subexpressions) { - s_expression *expr = (s_expression *) n; + foreach_in_list(s_expression, expr, &this->subexpressions) { expr->print(); if (!expr->next->is_tail_sentinel()) printf(" "); @@ -201,11 +200,10 @@ s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial) return false; unsigned i = 0; - foreach_list(node, &list->subexpressions) { + foreach_in_list(s_expression, expr, &list->subexpressions) { if (i >= n) return partial; /* More actual items than the pattern expected */ - s_expression *expr = (s_expression *) node; if (expr == NULL || !pattern[i].match(expr)) return false; diff --git a/mesalib/src/loader/Makefile.am b/mesalib/src/loader/Makefile.am index ae8a84492..c02de6f59 100644 --- a/mesalib/src/loader/Makefile.am +++ b/mesalib/src/loader/Makefile.am @@ -33,6 +33,7 @@ libloader_la_SOURCES = $(LOADER_C_FILES) libloader_la_LIBADD = if NEED_OPENGL_COMMON +if HAVE_DRICOMMON libloader_la_CPPFLAGS += \ -I$(top_srcdir)/src/mesa/drivers/dri/common/ \ -I$(top_builddir)/src/mesa/drivers/dri/common/ \ @@ -47,6 +48,7 @@ libloader_la_LIBADD += \ -lm \ $(EXPAT_LIBS) endif +endif if !HAVE_LIBDRM libloader_la_CPPFLAGS += \ diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index f313f5645..f1f57297c 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -2592,8 +2592,7 @@ _mesa_meta_setup_texture_coords(GLenum faceTarget, coord = coords3; break; default: - assert(0); - unreachable(); + unreachable("not reached"); } coord[3] = (float) (slice / 6); diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index 8506f5356..6c78928ee 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -677,7 +677,7 @@ dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) static int -dri2ConfigQueryb(__DRIscreen *screen, const char *var, bool *val) +dri2ConfigQueryb(__DRIscreen *screen, const char *var, unsigned char *val) { if (!driCheckOption(&screen->optionCache, var, DRI_BOOL)) return -1; diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c index 5091c115b..58d0e0656 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c @@ -285,7 +285,7 @@ static float strToF (const XML_Char *string, const XML_Char **tail) { } /** \brief Parse a value of a given type. */ -static bool parseValue (driOptionValue *v, driOptionType type, +static unsigned char parseValue (driOptionValue *v, driOptionType type, const XML_Char *string) { const XML_Char *tail = NULL; /* skip leading white-space */ @@ -328,7 +328,7 @@ static bool parseValue (driOptionValue *v, driOptionType type, } /** \brief Parse a list of ranges of type info->type. */ -static bool parseRanges (driOptionInfo *info, const XML_Char *string) { +static unsigned char parseRanges (driOptionInfo *info, const XML_Char *string) { XML_Char *cp, *range; uint32_t nRanges, i; driOptionRange *ranges; @@ -1003,13 +1003,13 @@ void driDestroyOptionCache (driOptionCache *cache) { free(cache->values); } -bool driCheckOption (const driOptionCache *cache, const char *name, +unsigned char driCheckOption (const driOptionCache *cache, const char *name, driOptionType type) { uint32_t i = findOption (cache, name); return cache->info[i].name != NULL && cache->info[i].type == type; } -bool driQueryOptionb (const driOptionCache *cache, const char *name) { +unsigned char driQueryOptionb (const driOptionCache *cache, const char *name) { uint32_t i = findOption (cache, name); /* make sure the option is defined and has the correct type */ assert (cache->info[i].name != NULL); diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h index 386ddf19d..af0323485 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h @@ -30,8 +30,6 @@ #ifndef __XMLCONFIG_H #define __XMLCONFIG_H -#include <stdbool.h> - #define STRING_CONF_MAXLEN 25 /** \brief Option data types */ @@ -41,7 +39,7 @@ typedef enum driOptionType { /** \brief Option value */ typedef union driOptionValue { - bool _bool; /**< \brief Boolean */ + unsigned char _bool; /**< \brief Boolean */ int _int; /**< \brief Integer or Enum */ float _float; /**< \brief Floating-point */ char *_string; /**< \brief String */ @@ -114,11 +112,11 @@ void driDestroyOptionInfo (driOptionCache *info); void driDestroyOptionCache (driOptionCache *cache); /** \brief Check if there exists a certain option */ -bool driCheckOption (const driOptionCache *cache, const char *name, +unsigned char driCheckOption (const driOptionCache *cache, const char *name, driOptionType type); /** \brief Query a boolean option value */ -bool driQueryOptionb (const driOptionCache *cache, const char *name); +unsigned char driQueryOptionb (const driOptionCache *cache, const char *name); /** \brief Query an integer option value */ int driQueryOptioni (const driOptionCache *cache, const char *name); /** \brief Query a floating-point option value */ diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 600691724..79d8740e5 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -253,15 +253,23 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) * function" warnings. */ #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5 -#define unreachable() __builtin_unreachable() +#define unreachable(str) \ +do { \ + assert(!str); \ + __builtin_unreachable(); \ +} while (0) #elif (defined(__clang__) && defined(__has_builtin)) # if __has_builtin(__builtin_unreachable) -# define unreachable() __builtin_unreachable() +# define unreachable(str) \ +do { \ + assert(!str); \ + __builtin_unreachable(); \ +} while (0) # endif #endif #ifndef unreachable -#define unreachable() +#define unreachable(str) #endif /* diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 6f2536170..92e3f0d68 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -323,6 +323,7 @@ static const struct extension extension_table[] = { { "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, { "GL_AMD_shader_trinary_minmax", o(dummy_true), GL, 2012 }, { "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GLC, 2012 }, + { "GL_AMD_vertex_shader_viewport_index", o(AMD_vertex_shader_viewport_index), GLC, 2012 }, { "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL, 2006 }, { "GL_APPLE_packed_pixels", o(dummy_true), GLL, 2002 }, { "GL_APPLE_texture_max_level", o(dummy_true), ES1 | ES2, 2009 }, diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index eaf377610..a7126fd55 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2560,7 +2560,7 @@ struct gl_uniform_block GLuint Binding; /** - * Minimum size of a buffer object to back this uniform buffer + * Minimum size (in bytes) of a buffer object to back this uniform buffer * (GL_UNIFORM_BLOCK_DATA_SIZE). */ GLuint UniformBufferSize; @@ -3616,6 +3616,7 @@ struct gl_extensions GLboolean AMD_performance_monitor; GLboolean AMD_seamless_cubemap_per_texture; GLboolean AMD_vertex_shader_layer; + GLboolean AMD_vertex_shader_viewport_index; GLboolean APPLE_object_purgeable; GLboolean ATI_texture_compression_3dc; GLboolean ATI_texture_mirror_once; diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index 36d1d9cc0..426774316 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -126,8 +126,8 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; unsigned current_index = 0; - foreach_list(node, ir) { - const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + const ir_variable *const var = node->as_variable(); if (!is_active_attrib(var)) continue; @@ -236,8 +236,8 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name) return -1; exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; - foreach_list(node, ir) { - const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + const ir_variable *const var = node->as_variable(); /* The extra check against VERT_ATTRIB_GENERIC0 is because * glGetAttribLocation cannot be used on "conventional" attributes. @@ -274,8 +274,8 @@ _mesa_count_active_attribs(struct gl_shader_program *shProg) exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; unsigned i = 0; - foreach_list(node, ir) { - const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + const ir_variable *const var = node->as_variable(); if (!is_active_attrib(var)) continue; @@ -298,8 +298,8 @@ _mesa_longest_attribute_name_length(struct gl_shader_program *shProg) exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; size_t longest = 0; - foreach_list(node, ir) { - const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + const ir_variable *const var = node->as_variable(); if (var == NULL || var->data.mode != ir_var_shader_in @@ -400,8 +400,8 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name) return -1; exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; - foreach_list(node, ir) { - const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + const ir_variable *const var = node->as_variable(); /* The extra check against FRAG_RESULT_DATA0 is because * glGetFragDataLocation cannot be used on "conventional" attributes. @@ -456,8 +456,8 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name) return -1; exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; - foreach_list(node, ir) { - const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, ir) { + const ir_variable *const var = node->as_variable(); /* The extra check against FRAG_RESULT_DATA0 is because * glGetFragDataLocation cannot be used on "conventional" attributes. diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 59cf1232a..1109051e9 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -663,11 +663,7 @@ ir_to_mesa_visitor::get_temp(const glsl_type *type) variable_storage * ir_to_mesa_visitor::find_variable_storage(const ir_variable *var) { - variable_storage *entry; - - foreach_list(node, &this->variables) { - entry = (variable_storage *) node; - + foreach_in_list(variable_storage, entry, &this->variables) { if (entry->var == var) return entry; } @@ -801,9 +797,7 @@ ir_to_mesa_visitor::visit(ir_function *ir) assert(sig); - foreach_list(node, &sig->body) { - ir_instruction *ir = (ir_instruction *) node; - + foreach_in_list(ir_instruction, ir, &sig->body) { ir->accept(this); } } @@ -1868,8 +1862,7 @@ ir_to_mesa_visitor::visit(ir_constant *ir) src_reg temp_base = get_temp(ir->type); dst_reg temp = dst_reg(temp_base); - foreach_list(node, &ir->components) { - ir_constant *field_value = (ir_constant *) node; + foreach_in_list(ir_constant, field_value, &ir->components) { int size = type_size(field_value->type); assert(size > 0); @@ -2338,9 +2331,7 @@ set_branchtargets(ir_to_mesa_visitor *v, mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; break; case OPCODE_CAL: - foreach_list(n, &v->function_signatures) { - function_entry *entry = (function_entry *) n; - + foreach_in_list(function_entry, entry, &v->function_signatures) { if (entry->sig_id == mesa_instructions[i].BranchTarget) { mesa_instructions[i].BranchTarget = entry->inst; break; @@ -2495,8 +2486,8 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program { add_uniform_to_shader add(shader_program, params, sh->Stage); - foreach_list(node, sh->ir) { - ir_variable *var = ((ir_instruction *) node)->as_variable(); + foreach_in_list(ir_instruction, node, sh->ir) { + ir_variable *var = node->as_variable(); if ((var == NULL) || (var->data.mode != ir_var_uniform) || var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0)) @@ -2621,9 +2612,7 @@ ir_to_mesa_visitor::copy_propagate(void) int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); int level = 0; - foreach_list(node, &this->instructions) { - ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node; - + foreach_in_list(ir_to_mesa_instruction, inst, &this->instructions) { assert(inst->dst.file != PROGRAM_TEMPORARY || inst->dst.index < this->next_temp); @@ -2826,7 +2815,7 @@ get_mesa_program(struct gl_context *ctx, prog->NumTemporaries = v.next_temp; int num_instructions = 0; - foreach_list(node, &v.instructions) { + foreach_in_list(ir_instruction, node, &v.instructions) { num_instructions++; } @@ -2842,9 +2831,7 @@ get_mesa_program(struct gl_context *ctx, */ mesa_inst = mesa_instructions; i = 0; - foreach_list(node, &v.instructions) { - const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node; - + foreach_in_list(const ir_to_mesa_instruction, inst, &v.instructions) { mesa_inst->Opcode = inst->op; mesa_inst->CondUpdate = inst->cond_update; if (inst->saturate) diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index 02624617b..3b4d28d47 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -225,6 +225,9 @@ st_bufferobj_data(struct gl_context *ctx, case GL_UNIFORM_BUFFER: bind = PIPE_BIND_CONSTANT_BUFFER; break; + case GL_DRAW_INDIRECT_BUFFER: + bind = PIPE_BIND_COMMAND_ARGS_BUFFER; + break; default: bind = 0; } diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 371f7fcda..4bfa8d75a 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -136,7 +136,7 @@ set_vertex_shader_layered(struct st_context *st) struct pipe_context *pipe = st->pipe; if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) || - !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) { + !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) { assert(!"Got layered clear, but the VS layer output is unsupported"); set_vertex_shader(st); return; diff --git a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c index 78a737094..489f537d8 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c +++ b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c @@ -132,13 +132,13 @@ st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) type == PIPE_QUERY_TIMESTAMP) { /* Determine time elapsed by emitting two timestamp queries. */ if (!stq->pq_begin) { - stq->pq_begin = pipe->create_query(pipe, type); + stq->pq_begin = pipe->create_query(pipe, type, 0); stq->type = type; } pipe->end_query(pipe, stq->pq_begin); } else { if (!stq->pq) { - stq->pq = pipe->create_query(pipe, type); + stq->pq = pipe->create_query(pipe, type, q->Stream); stq->type = type; } if (stq->pq) { @@ -164,7 +164,7 @@ st_EndQuery(struct gl_context *ctx, struct gl_query_object *q) if ((q->Target == GL_TIMESTAMP || q->Target == GL_TIME_ELAPSED) && !stq->pq) { - stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP); + stq->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP, 0); stq->type = PIPE_QUERY_TIMESTAMP; } diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index c8189faad..64d6ef525 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -244,6 +244,14 @@ st_draw_vbo(struct gl_context *ctx, } } + if (indirect) { + info.indirect = st_buffer_object(indirect)->buffer; + + /* Primitive restart is not handled by the VBO module in this case. */ + info.primitive_restart = ctx->Array._PrimitiveRestart; + info.restart_index = ctx->Array.RestartIndex; + } + /* do actual drawing */ for (i = 0; i < nr_prims; i++) { info.mode = translate_prim(ctx, prims[i].mode); @@ -256,6 +264,7 @@ st_draw_vbo(struct gl_context *ctx, info.min_index = info.start; info.max_index = info.start + info.count - 1; } + info.indirect_offset = prims[i].indirect_offset; if (ST_DEBUG & DEBUG_DRAW) { debug_printf("st/draw: mode %s start %u count %u indexed %d\n", @@ -265,7 +274,7 @@ st_draw_vbo(struct gl_context *ctx, info.indexed); } - if (info.count_from_stream_output) { + if (info.count_from_stream_output || info.indirect) { cso_draw_vbo(st->cso_context, &info); } else if (info.primitive_restart) { diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index e93804689..4207cb64a 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -287,6 +287,11 @@ void st_init_limits(struct st_context *st) screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS); c->MaxTransformFeedbackInterleavedComponents = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS); + c->MaxVertexStreams = + MAX2(1, screen->get_param(screen, PIPE_CAP_MAX_VERTEX_STREAMS)); + + /* The vertex stream must fit into pipe_stream_output_info::stream */ + assert(c->MaxVertexStreams <= 4); c->StripTextureBorder = GL_TRUE; @@ -427,6 +432,7 @@ void st_init_extensions(struct st_context *st) { o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE }, { o(ARB_texture_query_lod), PIPE_CAP_TEXTURE_QUERY_LOD }, { o(ARB_sample_shading), PIPE_CAP_SAMPLE_SHADING }, + { o(ARB_draw_indirect), PIPE_CAP_DRAW_INDIRECT } }; /* Required: render target and sampler support */ @@ -618,7 +624,7 @@ void st_init_extensions(struct st_context *st) /* This extension needs full OpenGL 3.2, but we don't know if that's * supported at this point. Only check the GLSL version. */ if (ctx->Const.GLSLVersion >= 150 && - screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER)) { + screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) { ctx->Extensions.AMD_vertex_shader_layer = GL_TRUE; } @@ -809,6 +815,9 @@ void st_init_extensions(struct st_context *st) ctx->Const.ViewportBounds.Min = -16384.0; ctx->Const.ViewportBounds.Max = 16384.0; ctx->Extensions.ARB_viewport_array = GL_TRUE; + ctx->Extensions.ARB_fragment_layer_viewport = GL_TRUE; + if (ctx->Extensions.AMD_vertex_shader_layer) + ctx->Extensions.AMD_vertex_shader_viewport_index = GL_TRUE; } } if (ctx->Const.MaxProgramTextureGatherComponents > 0) diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index cac1e0fe2..9e1943139 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -919,9 +919,7 @@ glsl_to_tgsi_visitor::add_constant(gl_register_file file, /* Search immediate storage to see if we already have an identical * immediate that we can use instead of adding a duplicate entry. */ - foreach_list(node, &this->immediates) { - entry = (immediate_storage *) node; - + foreach_in_list(immediate_storage, entry, &this->immediates) { if (entry->size == size && entry->type == datatype && !memcmp(entry->values, values, size * sizeof(gl_constant_value))) { @@ -1061,11 +1059,7 @@ variable_storage * glsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) { - variable_storage *entry; - - foreach_list(node, &this->variables) { - entry = (variable_storage *) node; - + foreach_in_list(variable_storage, entry, &this->variables) { if (entry->var == var) return entry; } @@ -1202,9 +1196,7 @@ glsl_to_tgsi_visitor::visit(ir_function *ir) assert(sig); - foreach_list(node, &sig->body) { - ir_instruction *ir = (ir_instruction *) node; - + foreach_in_list(ir_instruction, ir, &sig->body) { ir->accept(this); } } @@ -1971,9 +1963,17 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) assert(ir->type->is_vector() || ir->type->is_scalar()); if (const_offset_ir) { - index_reg = st_src_reg_for_int(const_offset / 16); - } else { - emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1], st_src_reg_for_int(4)); + /* Constant index into constant buffer */ + cbuf.reladdr = NULL; + cbuf.index = const_offset / 16; + cbuf.has_index2 = true; + } + else { + /* Relative/variable index into constant buffer */ + emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1], + st_src_reg_for_int(4)); + cbuf.reladdr = ralloc(mem_ctx, st_src_reg); + memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg)); } cbuf.swizzle = swizzle_for_size(ir->type->vector_elements); @@ -1982,9 +1982,6 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) const_offset % 16 / 4, const_offset % 16 / 4); - cbuf.reladdr = ralloc(mem_ctx, st_src_reg); - memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg)); - if (ir->type->base_type == GLSL_TYPE_BOOL) { emit(ir, TGSI_OPCODE_USNE, result_dst, cbuf, st_src_reg_for_int(0)); } else { @@ -2549,8 +2546,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir) st_src_reg temp_base = get_temp(ir->type); st_dst_reg temp = st_dst_reg(temp_base); - foreach_list(node, &ir->components) { - ir_constant *field_value = (ir_constant *) node; + foreach_in_list(ir_constant, field_value, &ir->components) { int size = type_size(field_value->type); assert(size > 0); @@ -2664,11 +2660,7 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir) function_entry * glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) { - function_entry *entry; - - foreach_list(node, &this->function_signatures) { - entry = (function_entry *) node; - + foreach_in_list_use_after(function_entry, entry, &this->function_signatures) { if (entry->sig == sig) return entry; } @@ -2679,8 +2671,7 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) entry->bgn_inst = NULL; /* Allocate storage for all the parameters. */ - foreach_list(node, &sig->parameters) { - ir_variable *param = (ir_variable *) node; + foreach_in_list(ir_variable, param, &sig->parameters) { variable_storage *storage; storage = find_variable_storage(param); @@ -3139,14 +3130,18 @@ void glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir) { assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV); - emit(ir, TGSI_OPCODE_EMIT); + + ir->stream->accept(this); + emit(ir, TGSI_OPCODE_EMIT, undef_dst, this->result); } void glsl_to_tgsi_visitor::visit(ir_end_primitive *ir) { assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV); - emit(ir, TGSI_OPCODE_ENDPRIM); + + ir->stream->accept(this); + emit(ir, TGSI_OPCODE_ENDPRIM, undef_dst, this->result); } glsl_to_tgsi_visitor::glsl_to_tgsi_visitor() @@ -3190,9 +3185,7 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog) { v->samplers_used = 0; - foreach_list(node, &v->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) { if (is_tex_instruction(inst->op)) { v->samplers_used |= 1 << inst->sampler; @@ -3336,8 +3329,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void) memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS); memset(outputWrites, 0, sizeof(outputWrites)); - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { unsigned prevWriteMask = 0; /* Give up if we encounter relative addressing or flow control. */ @@ -3382,8 +3374,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void) void glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) { - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { unsigned j; for (j=0; j < num_inst_src_regs(inst->op); j++) { @@ -3413,9 +3404,7 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index) int loop_start = -1; /* index of the first active BGNLOOP (if any) */ unsigned i = 0, j; - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { for (j=0; j < num_inst_src_regs(inst->op); j++) { if (inst->src[j].file == PROGRAM_TEMPORARY && inst->src[j].index == index) { @@ -3451,9 +3440,7 @@ glsl_to_tgsi_visitor::get_first_temp_write(int index) int loop_start = -1; /* index of the first active BGNLOOP (if any) */ int i = 0; - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { return (depth == 0) ? i : loop_start; } @@ -3480,9 +3467,7 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index) int last = -1; /* index of last instruction that reads the temporary */ unsigned i = 0, j; - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { for (j=0; j < num_inst_src_regs(inst->op); j++) { if (inst->src[j].file == PROGRAM_TEMPORARY && inst->src[j].index == index) { @@ -3516,9 +3501,7 @@ glsl_to_tgsi_visitor::get_last_temp_write(int index) int last = -1; /* index of last instruction that writes to the temporary */ int i = 0; - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) last = (depth == 0) ? i : -2; @@ -3565,9 +3548,7 @@ glsl_to_tgsi_visitor::copy_propagate(void) int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); int level = 0; - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { assert(inst->dst.file != PROGRAM_TEMPORARY || inst->dst.index < this->next_temp); @@ -3761,9 +3742,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) int level = 0; int removed = 0; - foreach_list(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { assert(inst->dst.file != PROGRAM_TEMPORARY || inst->dst.index < this->next_temp); @@ -3889,9 +3868,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) /* Now actually remove the instructions that are completely dead and update * the writemask of other instructions with dead channels. */ - foreach_list_safe(node, &this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; - + foreach_in_list_safe(glsl_to_tgsi_instruction, inst, &this->instructions) { if (!inst->dead_mask || !inst->dst.writemask) continue; else if ((inst->dst.writemask & ~inst->dead_mask) == 0) { @@ -4077,8 +4054,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, /* Now copy the instructions from the original glsl_to_tgsi_visitor into the * new visitor. */ - foreach_list(node, &original->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; + foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) { glsl_to_tgsi_instruction *newinst; st_src_reg src_regs[3]; @@ -4162,8 +4138,7 @@ get_bitmap_visitor(struct st_fragment_program *fp, /* Now copy the instructions from the original glsl_to_tgsi_visitor into the * new visitor. */ - foreach_list(node, &original->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; + foreach_in_list(glsl_to_tgsi_instruction, inst, &original->instructions) { glsl_to_tgsi_instruction *newinst; st_src_reg src_regs[3]; @@ -4396,7 +4371,7 @@ src_register(struct st_translate *t, case PROGRAM_CONSTANT: /* ie, immediate */ if (index2D) { struct ureg_src src; - src = ureg_src_register(TGSI_FILE_CONSTANT, 0); + src = ureg_src_register(TGSI_FILE_CONSTANT, index); src.Dimension = 1; src.DimensionIndex = index2D; return src; @@ -4484,7 +4459,10 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg) { struct ureg_src src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D); - if (t->procType == TGSI_PROCESSOR_GEOMETRY && src_reg->has_index2) { + if (src_reg->has_index2) { + /* 2D indexes occur with geometry shader inputs (attrib, vertex) + * and UBO constant buffers (buffer, position). + */ src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D); if (src_reg->reladdr2) src = ureg_src_dimension_indirect(src, ureg_src(t->address[1]), @@ -5115,7 +5093,14 @@ st_translate_program( unsigned num_ubos = program->shader->NumUniformBlocks; for (i = 0; i < num_ubos; i++) { - ureg_DECL_constant2D(t->ureg, 0, program->shader->UniformBlocks[i].UniformBufferSize / 4, i + 1); + unsigned size = + program->shader_program->UniformBlocks[i].UniformBufferSize; + unsigned num_const_vecs = (size + 15) / 16; + unsigned first, last; + assert(num_const_vecs > 0); + first = 0; + last = num_const_vecs > 0 ? num_const_vecs - 1 : 0; + ureg_DECL_constant2D(t->ureg, first, last, i + 1); } } @@ -5128,8 +5113,7 @@ st_translate_program( goto out; } i = 0; - foreach_list(node, &program->immediates) { - immediate_storage *imm = (immediate_storage *) node; + foreach_in_list(immediate_storage, imm, &program->immediates) { assert(i < program->num_immediates); t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size); } @@ -5144,9 +5128,9 @@ st_translate_program( /* Emit each instruction in turn: */ - foreach_list(n, &program->instructions) { + foreach_in_list(glsl_to_tgsi_instruction, inst, &program->instructions) { set_insn_start(t, ureg_get_instruction_number(ureg)); - compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *) n, clamp_color); + compile_tgsi_instruction(t, inst, clamp_color); } /* Fix up all emitted labels: @@ -5257,9 +5241,7 @@ get_mesa_program(struct gl_context *ctx, do { progress = GL_FALSE; - foreach_list(node, &v->function_signatures) { - function_entry *entry = (function_entry *) node; - + foreach_in_list(function_entry, entry, &v->function_signatures) { if (!entry->bgn_inst) { v->current_function = entry; @@ -5524,6 +5506,7 @@ st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, so->output[i].num_components = info->Outputs[i].NumComponents; so->output[i].output_buffer = info->Outputs[i].OutputBuffer; so->output[i].dst_offset = info->Outputs[i].DstOffset; + so->output[i].stream = info->Outputs[i].StreamId; } for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index 1df411c3b..3570557fe 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -262,6 +262,10 @@ st_prepare_vertex_program(struct gl_context *ctx, stvp->output_semantic_name[slot] = TGSI_SEMANTIC_LAYER; stvp->output_semantic_index[slot] = 0; break; + case VARYING_SLOT_VIEWPORT: + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX; + stvp->output_semantic_index[slot] = 0; + break; case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: |