diff options
Diffstat (limited to 'mesalib/src/gallium/auxiliary')
-rw-r--r-- | mesalib/src/gallium/auxiliary/hud/hud_driver_query.c | 6 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.c | 2 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_draw.c | 43 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_draw.h | 8 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_dump_state.c | 3 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_vbuf.c | 116 |
6 files changed, 130 insertions, 48 deletions
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); |