diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 2fdea6cc35f405ddeb6e1fa33ec7e409ef83f02a..d63892f27bb120d9b3cfe5f0fbe9ee00fccc9217 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -1722,25 +1722,26 @@ cso_restore_state(struct cso_context *cso) void cso_draw_vbo(struct cso_context *cso, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct u_vbuf *vbuf = cso->vbuf_current; /* We can't have both indirect drawing and SO-vertex-count drawing */ - assert(!info->indirect || - info->indirect->buffer == NULL || - info->indirect->count_from_stream_output == NULL); + assert(!indirect || + indirect->buffer == NULL || + indirect->count_from_stream_output == NULL); /* We can't have SO-vertex-count drawing with an index buffer */ assert(info->index_size == 0 || - !info->indirect || - info->indirect->count_from_stream_output == NULL); + !indirect || + indirect->count_from_stream_output == NULL); if (vbuf) { - u_vbuf_draw_vbo(vbuf, info); + u_vbuf_draw_vbo(vbuf, info, indirect); } else { struct pipe_context *pipe = cso->pipe; - pipe->draw_vbo(pipe, info); + pipe->draw_vbo(pipe, info, indirect); } } @@ -1757,7 +1758,7 @@ cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count) info.min_index = start; info.max_index = start + count - 1; - cso_draw_vbo(cso, &info); + cso_draw_vbo(cso, &info, NULL); } void @@ -1777,5 +1778,5 @@ cso_draw_arrays_instanced(struct cso_context *cso, uint mode, info.start_instance = start_instance; info.instance_count = instance_count; - cso_draw_vbo(cso, &info); + cso_draw_vbo(cso, &info, NULL); } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 95df3c169d7fe6e69474912ca51c4324b80e836e..57dcccff8ae99efb8316153afbb5826baabd2833 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -217,7 +217,8 @@ cso_set_vertex_buffers_and_elements(struct cso_context *ctx, void cso_draw_vbo(struct cso_context *cso, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); void cso_draw_arrays_instanced(struct cso_context *cso, uint mode, diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 0098657357bfa8cc4e4c208625023ffdfec07927..13cbe1ea122540b57ed999274db3671c00e12f6c 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -323,7 +323,8 @@ draw_set_mapped_so_targets(struct draw_context *draw, */ void draw_vbo(struct draw_context *draw, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); /******************************************************************************* diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index a1626c7171f995291349ea29b6580655462ec6ee..5149a17acaa4bbae6d6c183a5a1cdc4d1e137405 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -440,14 +440,15 @@ draw_pt_arrays_restart(struct draw_context *draw, */ static void resolve_draw_info(const struct pipe_draw_info *raw_info, + const struct pipe_draw_indirect_info *indirect, struct pipe_draw_info *info, struct pipe_vertex_buffer *vertex_buffer) { memcpy(info, raw_info, sizeof(struct pipe_draw_info)); - if (raw_info->indirect && raw_info->indirect->count_from_stream_output) { + if (indirect && indirect->count_from_stream_output) { struct draw_so_target *target = - (struct draw_so_target *)info->indirect->count_from_stream_output; + (struct draw_so_target *)indirect->count_from_stream_output; assert(vertex_buffer != NULL); info->count = vertex_buffer->stride == 0 ? 0 : target->internal_offset / vertex_buffer->stride; @@ -455,7 +456,6 @@ resolve_draw_info(const struct pipe_draw_info *raw_info, /* Stream output draw can not be indexed */ debug_assert(!info->index_size); info->max_index = info->count - 1; - info->indirect = NULL; } } @@ -467,7 +467,8 @@ resolve_draw_info(const struct pipe_draw_info *raw_info, */ void draw_vbo(struct draw_context *draw, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { unsigned instance; unsigned index_limit; @@ -483,7 +484,7 @@ draw_vbo(struct draw_context *draw, */ util_fpstate_set_denorms_to_zero(fpstate); - resolve_draw_info(info, &resolved_info, &(draw->pt.vertex_buffer[0])); + resolve_draw_info(info, indirect, &resolved_info, &(draw->pt.vertex_buffer[0])); info = &resolved_info; if (info->index_size) diff --git a/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/src/gallium/auxiliary/driver_ddebug/dd_draw.c index e9e3b493d89178becb62ed4c9615f6f9fd2975ed..ba398f6df5f3cad8292f244e0d35f0972aa394e4 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_draw.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_draw.c @@ -351,19 +351,19 @@ dd_dump_flush(struct dd_draw_state *dstate, struct call_flush *info, FILE *f) } static void -dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f) +dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, FILE *f) { int sh, i; DUMP(draw_info, info); - if (info->indirect) { - if (info->indirect->buffer) - DUMP_M(resource, info, indirect->buffer); - if (info->indirect->indirect_draw_count) - DUMP_M(resource, info, indirect->indirect_draw_count); - if (info->indirect->count_from_stream_output) - DUMP_M(stream_output_target, info, - indirect->count_from_stream_output); + if (indirect) { + if (indirect->buffer) + DUMP_M(resource, indirect, buffer); + if (indirect->indirect_draw_count) + DUMP_M(resource, indirect, indirect_draw_count); + if (indirect->count_from_stream_output) + DUMP_M(stream_output_target, indirect, count_from_stream_output); } fprintf(f, "\n"); @@ -633,7 +633,8 @@ dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call) dd_dump_flush(state, &call->info.flush, f); break; case CALL_DRAW_VBO: - dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f); + dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, + &call->info.draw_vbo.indirect, f); break; case CALL_LAUNCH_GRID: dd_dump_launch_grid(state, &call->info.launch_grid, f); @@ -1298,7 +1299,8 @@ dd_context_flush(struct pipe_context *_pipe, static void dd_context_draw_vbo(struct pipe_context *_pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct dd_context *dctx = dd_context(_pipe); struct pipe_context *pipe = dctx->pipe; @@ -1312,25 +1314,23 @@ dd_context_draw_vbo(struct pipe_context *_pipe, info->index.resource); } - if (info->indirect) { - record->call.info.draw_vbo.indirect = *info->indirect; - record->call.info.draw_vbo.draw.indirect = &record->call.info.draw_vbo.indirect; - + if (indirect) { + record->call.info.draw_vbo.indirect = *indirect; record->call.info.draw_vbo.indirect.buffer = NULL; pipe_resource_reference(&record->call.info.draw_vbo.indirect.buffer, - info->indirect->buffer); + indirect->buffer); record->call.info.draw_vbo.indirect.indirect_draw_count = NULL; pipe_resource_reference(&record->call.info.draw_vbo.indirect.indirect_draw_count, - info->indirect->indirect_draw_count); + indirect->indirect_draw_count); record->call.info.draw_vbo.indirect.count_from_stream_output = NULL; pipe_so_target_reference(&record->call.info.draw_vbo.indirect.count_from_stream_output, - info->indirect->count_from_stream_output); + indirect->count_from_stream_output); } else { - memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*info->indirect)); + memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*indirect)); } dd_before_draw(dctx, record); - pipe->draw_vbo(pipe, info); + pipe->draw_vbo(pipe, info, indirect); dd_after_draw(dctx, record); } diff --git a/src/gallium/auxiliary/driver_noop/noop_state.c b/src/gallium/auxiliary/driver_noop/noop_state.c index 056d4be6b19c638495af61c7099771c38bc6ac6f..222cee45cd9b7838d862230db637e599f9f82987 100644 --- a/src/gallium/auxiliary/driver_noop/noop_state.c +++ b/src/gallium/auxiliary/driver_noop/noop_state.c @@ -30,7 +30,8 @@ #include "util/u_inlines.h" #include "util/u_transfer.h" -static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) +static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { } diff --git a/src/gallium/auxiliary/driver_rbug/rbug_context.c b/src/gallium/auxiliary/driver_rbug/rbug_context.c index c391adff244c3f03e56bc606ef0e0b5ef6a1e954..0698f96256bcbc4b652f654784d378af8354cc4a 100644 --- a/src/gallium/auxiliary/driver_rbug/rbug_context.c +++ b/src/gallium/auxiliary/driver_rbug/rbug_context.c @@ -114,7 +114,8 @@ rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag) } static void -rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *_info) +rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *_info, + const struct pipe_draw_indirect_info *_indirect) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; @@ -132,7 +133,7 @@ rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *_info) if (!(rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT] && rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT]->disabled) && !(rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY] && rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY]->disabled) && !(rb_pipe->curr.shader[PIPE_SHADER_VERTEX] && rb_pipe->curr.shader[PIPE_SHADER_VERTEX]->disabled)) - pipe->draw_vbo(pipe, &info); + pipe->draw_vbo(pipe, &info, _indirect); mtx_unlock(&rb_pipe->call_mutex); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c index b0bd53ee6a9ad5432092929cc37846b2f462f01b..8f0d42629409958dc31b9adb35d0f8b1ab9d0d3b 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.c +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -89,7 +89,8 @@ trace_surface_unwrap(struct trace_context *tr_ctx, static void trace_context_draw_vbo(struct pipe_context *_pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; @@ -98,10 +99,11 @@ trace_context_draw_vbo(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(draw_info, info); + trace_dump_arg(draw_indirect_info, indirect); trace_dump_trace_flush(); - pipe->draw_vbo(pipe, info); + pipe->draw_vbo(pipe, info, indirect); trace_dump_call_end(); } diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.c b/src/gallium/auxiliary/driver_trace/tr_dump_state.c index c63c373f9235552ef33bcd487e5c6a52bfee53fe..f747e9af82d94f227908bd805fb53d3e51849355 100644 --- a/src/gallium/auxiliary/driver_trace/tr_dump_state.c +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.c @@ -793,19 +793,27 @@ void trace_dump_draw_info(const struct pipe_draw_info *state) trace_dump_member(uint, state, restart_index); trace_dump_member(ptr, state, index.resource); + trace_dump_struct_end(); +} - if (!state->indirect) { - trace_dump_member(ptr, state, indirect); - } else { - trace_dump_member(uint, state, indirect->offset); - trace_dump_member(uint, state, indirect->stride); - trace_dump_member(uint, state, indirect->draw_count); - trace_dump_member(uint, state, indirect->indirect_draw_count_offset); - trace_dump_member(ptr, state, indirect->buffer); - trace_dump_member(ptr, state, indirect->indirect_draw_count); - trace_dump_member(ptr, state, indirect->count_from_stream_output); +void trace_dump_draw_indirect_info(const struct pipe_draw_indirect_info *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if (!state) { + trace_dump_null(); + return; } + trace_dump_struct_begin("pipe_draw_indirect_info"); + trace_dump_member(uint, state, offset); + trace_dump_member(uint, state, stride); + trace_dump_member(uint, state, draw_count); + trace_dump_member(uint, state, indirect_draw_count_offset); + trace_dump_member(ptr, state, buffer); + trace_dump_member(ptr, state, indirect_draw_count); + trace_dump_member(ptr, state, count_from_stream_output); trace_dump_struct_end(); } diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.h b/src/gallium/auxiliary/driver_trace/tr_dump_state.h index baff0252f9baa94615ee2ab887d8f811396fb64f..d7e624f5714abe54555bef86f01fbdd0fb53ef7d 100644 --- a/src/gallium/auxiliary/driver_trace/tr_dump_state.h +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.h @@ -82,6 +82,8 @@ void trace_dump_shader_buffer(const struct pipe_shader_buffer *buffer); void trace_dump_draw_info(const struct pipe_draw_info *state); +void trace_dump_draw_indirect_info(const struct pipe_draw_indirect_info *state); + void trace_dump_blit_info(const struct pipe_blit_info *); void trace_dump_query_result(unsigned query_type, diff --git a/src/gallium/auxiliary/indices/u_primconvert.c b/src/gallium/auxiliary/indices/u_primconvert.c index 337ee5b9460e8cd8803b22a10f572b158e5a4722..18a9e5133f6e82f2bd214eae75241495c08cddd9 100644 --- a/src/gallium/auxiliary/indices/u_primconvert.c +++ b/src/gallium/auxiliary/indices/u_primconvert.c @@ -172,7 +172,7 @@ util_primconvert_draw_vbo(struct primconvert_context *pc, u_upload_unmap(pc->pipe->stream_uploader); /* to the translated draw: */ - pc->pipe->draw_vbo(pc->pipe, &new_info); + pc->pipe->draw_vbo(pc->pipe, &new_info, NULL); pipe_resource_reference(&new_info.index.resource, NULL); } diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c index a6835204c72aee819d9d185ee4f7ef747c997db0..5481aa2ef32cd34a66c1e26cc45fd17305352bc1 100644 --- a/src/gallium/auxiliary/util/u_draw.c +++ b/src/gallium/auxiliary/util/u_draw.c @@ -126,30 +126,31 @@ util_draw_max_index( } -/* This extracts the draw arguments from the info_in->indirect resource, +/* This extracts the draw arguments from the 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) + const struct pipe_draw_info *info_in, + const struct pipe_draw_indirect_info *indirect) { struct pipe_draw_info info; struct pipe_transfer *transfer; uint32_t *params; unsigned num_params = info_in->index_size ? 5 : 4; - assert(info_in->indirect); - assert(!info_in->indirect->count_from_stream_output); + assert(indirect); + assert(!indirect->count_from_stream_output); memcpy(&info, info_in, sizeof(info)); - uint32_t draw_count = info_in->indirect->draw_count; + uint32_t draw_count = indirect->draw_count; - if (info_in->indirect->indirect_draw_count) { + if (indirect->indirect_draw_count) { struct pipe_transfer *dc_transfer; uint32_t *dc_param = pipe_buffer_map_range(pipe, - info_in->indirect->indirect_draw_count, - info_in->indirect->indirect_draw_count_offset, + indirect->indirect_draw_count, + indirect->indirect_draw_count_offset, 4, PIPE_MAP_READ, &dc_transfer); if (!dc_transfer) { debug_printf("%s: failed to map indirect draw count buffer\n", __FUNCTION__); @@ -160,13 +161,13 @@ util_draw_indirect(struct pipe_context *pipe, pipe_buffer_unmap(pipe, dc_transfer); } - if (info_in->indirect->stride) - num_params = MIN2(info_in->indirect->stride / 4, num_params); + if (indirect->stride) + num_params = MIN2(indirect->stride / 4, num_params); params = (uint32_t *) pipe_buffer_map_range(pipe, - info_in->indirect->buffer, - info_in->indirect->offset, - (num_params * info_in->indirect->draw_count) * sizeof(uint32_t), + indirect->buffer, + indirect->offset, + (num_params * indirect->draw_count) * sizeof(uint32_t), PIPE_MAP_READ, &transfer); if (!transfer) { @@ -181,11 +182,10 @@ util_draw_indirect(struct pipe_context *pipe, info.index_bias = info_in->index_size ? params[3] : 0; info.start_instance = info_in->index_size ? params[4] : params[3]; info.drawid = i; - info.indirect = NULL; - pipe->draw_vbo(pipe, &info); + pipe->draw_vbo(pipe, &info, NULL); - params += info_in->indirect->stride / 4; + params += indirect->stride / 4; } pipe_buffer_unmap(pipe, transfer); } diff --git a/src/gallium/auxiliary/util/u_draw.h b/src/gallium/auxiliary/util/u_draw.h index d0955fa3f978d041803bd4ec76741743c1b35432..ac1605228a3e5cd733d3f7bf6e4a45bc387c4d21 100644 --- a/src/gallium/auxiliary/util/u_draw.h +++ b/src/gallium/auxiliary/util/u_draw.h @@ -63,7 +63,7 @@ util_draw_arrays(struct pipe_context *pipe, info.min_index = start; info.max_index = start + count - 1; - pipe->draw_vbo(pipe, &info); + pipe->draw_vbo(pipe, &info, NULL); } static inline void @@ -85,7 +85,7 @@ util_draw_elements(struct pipe_context *pipe, info.count = count; info.index_bias = index_bias; - pipe->draw_vbo(pipe, &info); + pipe->draw_vbo(pipe, &info, NULL); } static inline void @@ -107,7 +107,7 @@ util_draw_arrays_instanced(struct pipe_context *pipe, info.min_index = start; info.max_index = start + count - 1; - pipe->draw_vbo(pipe, &info); + pipe->draw_vbo(pipe, &info, NULL); } static inline void @@ -134,7 +134,7 @@ util_draw_elements_instanced(struct pipe_context *pipe, info.start_instance = start_instance; info.instance_count = instance_count; - pipe->draw_vbo(pipe, &info); + pipe->draw_vbo(pipe, &info, NULL); } @@ -143,7 +143,8 @@ util_draw_elements_instanced(struct pipe_context *pipe, */ void util_draw_indirect(struct pipe_context *pipe, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); unsigned diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h index 8c1a8f3f4ee9fa5b2a445acbbc015c9476b269b5..2d0cac50a28bffe4144c6dd41b1c87bd7145364a 100644 --- a/src/gallium/auxiliary/util/u_dump.h +++ b/src/gallium/auxiliary/util/u_dump.h @@ -200,6 +200,10 @@ util_dump_stream_output_target(FILE *stream, void util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state); +void +util_dump_draw_indirect_info(FILE *stream, + const struct pipe_draw_indirect_info *indirect); + void util_dump_grid_info(FILE *stream, const struct pipe_grid_info *state); diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index 3cbd779bfd14734a86b4d28d73b9aeb9a6120da2..432b6567b51ca92fc5ee9a736a9b92410376619b 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -941,19 +941,26 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) else util_dump_member(stream, ptr, state, index.resource); } + util_dump_struct_end(stream); +} - if (!state->indirect) { - util_dump_member(stream, ptr, state, indirect); - } else { - util_dump_member(stream, uint, state, indirect->offset); - util_dump_member(stream, uint, state, indirect->stride); - util_dump_member(stream, uint, state, indirect->draw_count); - util_dump_member(stream, uint, state, indirect->indirect_draw_count_offset); - util_dump_member(stream, ptr, state, indirect->buffer); - util_dump_member(stream, ptr, state, indirect->indirect_draw_count); - util_dump_member(stream, ptr, state, indirect->count_from_stream_output); +void +util_dump_draw_indirect_info(FILE *stream, + const struct pipe_draw_indirect_info *state) +{ + if (!state) { + util_dump_null(stream); + return; } + util_dump_struct_begin(stream, "pipe_draw_indirect_info"); + util_dump_member(stream, uint, state, offset); + util_dump_member(stream, uint, state, stride); + util_dump_member(stream, uint, state, draw_count); + util_dump_member(stream, uint, state, indirect_draw_count_offset); + util_dump_member(stream, ptr, state, buffer); + util_dump_member(stream, ptr, state, indirect_draw_count); + util_dump_member(stream, ptr, state, count_from_stream_output); util_dump_struct_end(stream); } diff --git a/src/gallium/auxiliary/util/u_prim_restart.c b/src/gallium/auxiliary/util/u_prim_restart.c index f7b34f9ebc8ddcc60152b7434a18e9334d6422c7..d3a5e6343870cf2c224cd706aab1123fb2e62c9e 100644 --- a/src/gallium/auxiliary/util/u_prim_restart.c +++ b/src/gallium/auxiliary/util/u_prim_restart.c @@ -38,7 +38,7 @@ typedef struct { } DrawElementsIndirectCommand; static DrawElementsIndirectCommand -read_indirect_elements(struct pipe_context *context, struct pipe_draw_indirect_info *indirect) +read_indirect_elements(struct pipe_context *context, const struct pipe_draw_indirect_info *indirect) { DrawElementsIndirectCommand ret; struct pipe_transfer *transfer = NULL; @@ -99,6 +99,7 @@ util_translate_prim_restart_data(unsigned index_size, enum pipe_error util_translate_prim_restart_ib(struct pipe_context *context, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect_info, struct pipe_resource **dst_buffer) { struct pipe_screen *screen = context->screen; @@ -114,8 +115,8 @@ util_translate_prim_restart_ib(struct pipe_context *context, dst_index_size = MAX2(2, info->index_size); assert(dst_index_size == 2 || dst_index_size == 4); - if (info->indirect && info->indirect->buffer) { - indirect = read_indirect_elements(context, info->indirect); + if (indirect_info && indirect_info->buffer) { + indirect = read_indirect_elements(context, indirect_info); count = indirect.count; start = indirect.firstIndex; } @@ -220,7 +221,8 @@ add_range(struct range_info *info, unsigned start, unsigned count) */ enum pipe_error util_draw_vbo_without_prim_restart(struct pipe_context *context, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect_info) { const void *src_map; struct range_info ranges = {0}; @@ -235,8 +237,8 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context, assert(info->index_size); assert(info->primitive_restart); - if (info->indirect && info->indirect->buffer) { - indirect = read_indirect_elements(context, info->indirect); + if (indirect_info && indirect_info->buffer) { + indirect = read_indirect_elements(context, indirect_info); info_count = indirect.count; info_start = indirect.firstIndex; info_instance_count = indirect.primCount; @@ -307,13 +309,12 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context, /* draw ranges between the restart indexes */ new_info = *info; /* we've effectively remapped this to a direct draw */ - new_info.indirect = NULL; new_info.instance_count = info_instance_count; new_info.primitive_restart = FALSE; for (i = 0; i < ranges.count; i++) { new_info.start = ranges.ranges[i].start; new_info.count = ranges.ranges[i].count; - context->draw_vbo(context, &new_info); + context->draw_vbo(context, &new_info, NULL); } FREE(ranges.ranges); diff --git a/src/gallium/auxiliary/util/u_prim_restart.h b/src/gallium/auxiliary/util/u_prim_restart.h index 82f0409a8351785311ccce8a1cf6c139f440aadb..de7d93303e7b20cdc3d0d9dc4766c723414a46d6 100644 --- a/src/gallium/auxiliary/util/u_prim_restart.h +++ b/src/gallium/auxiliary/util/u_prim_restart.h @@ -49,11 +49,13 @@ util_translate_prim_restart_data(unsigned index_size, enum pipe_error util_translate_prim_restart_ib(struct pipe_context *context, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, struct pipe_resource **dst_buffer); enum pipe_error util_draw_vbo_without_prim_restart(struct pipe_context *context, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); static inline unsigned util_prim_restart_index_from_size(unsigned index_size) diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index f66280da6f62f429aa0e17669aceade35e8ae49f..da3f11a06a92447954065ec7fccea86ab1ec26f5 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -125,7 +125,6 @@ tc_batch_execute(void *job, UNUSED int thread_index) /* If at least 2 consecutive draw calls can be merged... */ if (next != last && next->call_id == TC_CALL_draw_vbo && first_info->draw.drawid == 0 && - !first_info->draw.indirect && is_next_call_a_mergeable_draw(first_info, next, &next_info)) { /* Merge up to 256 draw calls. */ struct pipe_draw_start_count multi[256]; @@ -151,7 +150,7 @@ tc_batch_execute(void *job, UNUSED int thread_index) pipe_resource_reference(&next_info->draw.index.resource, NULL); } - pipe->multi_draw(pipe, &first_info->draw, multi, num_draws); + pipe->multi_draw(pipe, &first_info->draw, NULL, multi, num_draws); if (first_info->draw.index_size) pipe_resource_reference(&first_info->draw.index.resource, NULL); iter = next; @@ -2197,40 +2196,69 @@ tc_call_draw_vbo(struct pipe_context *pipe, union tc_payload *payload) { struct tc_full_draw_info *info = (struct tc_full_draw_info*)payload; - pipe->draw_vbo(pipe, &info->draw); + pipe->draw_vbo(pipe, &info->draw, NULL); if (info->draw.index_size) pipe_resource_reference(&info->draw.index.resource, NULL); - if (info->draw.indirect) { - pipe_resource_reference(&info->indirect.buffer, NULL); - pipe_resource_reference(&info->indirect.indirect_draw_count, NULL); - pipe_so_target_reference(&info->indirect.count_from_stream_output, NULL); - } +} + +static void +tc_call_draw_indirect(struct pipe_context *pipe, union tc_payload *payload) +{ + struct tc_full_draw_info *info = (struct tc_full_draw_info*)payload; + + pipe->draw_vbo(pipe, &info->draw, &info->indirect); + if (info->draw.index_size) + pipe_resource_reference(&info->draw.index.resource, NULL); + + pipe_resource_reference(&info->indirect.buffer, NULL); + pipe_resource_reference(&info->indirect.indirect_draw_count, NULL); + pipe_so_target_reference(&info->indirect.count_from_stream_output, NULL); } static struct tc_full_draw_info * tc_add_draw_vbo(struct pipe_context *_pipe, bool indirect) { - return (struct tc_full_draw_info*) - tc_add_sized_call(threaded_context(_pipe), TC_CALL_draw_vbo, - indirect ? sizeof(struct tc_full_draw_info) : - sizeof(struct pipe_draw_info)); + if (indirect) { + return (struct tc_full_draw_info*) + tc_add_sized_call(threaded_context(_pipe), TC_CALL_draw_indirect, + sizeof(struct tc_full_draw_info)); + } else { + return (struct tc_full_draw_info*) + tc_add_sized_call(threaded_context(_pipe), TC_CALL_draw_vbo, + sizeof(struct pipe_draw_info)); + } } static void -tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) +tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct threaded_context *tc = threaded_context(_pipe); - struct pipe_draw_indirect_info *indirect = info->indirect; unsigned index_size = info->index_size; bool has_user_indices = info->has_user_indices; - if (index_size && has_user_indices) { + if (unlikely(indirect)) { + assert(!has_user_indices); + + struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, true); + if (index_size) { + tc_set_resource_reference(&p->draw.index.resource, + info->index.resource); + } + memcpy(&p->draw, info, sizeof(*info)); + + tc_set_resource_reference(&p->indirect.buffer, indirect->buffer); + tc_set_resource_reference(&p->indirect.indirect_draw_count, + indirect->indirect_draw_count); + p->indirect.count_from_stream_output = NULL; + pipe_so_target_reference(&p->indirect.count_from_stream_output, + indirect->count_from_stream_output); + memcpy(&p->indirect, indirect, sizeof(*indirect)); + } else if (index_size && has_user_indices) { unsigned size = info->count * index_size; struct pipe_resource *buffer = NULL; unsigned offset; - tc_assert(!indirect); - /* This must be done before adding draw_vbo, because it could generate * e.g. transfer_unmap and flush partially-uninitialized draw_vbo * to the driver if it was done afterwards. @@ -2248,23 +2276,12 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) p->draw.start = offset >> util_logbase2(index_size); } else { /* Non-indexed call or indexed with a real index buffer. */ - struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, indirect != NULL); + struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, false); if (index_size) { tc_set_resource_reference(&p->draw.index.resource, info->index.resource); } memcpy(&p->draw, info, sizeof(*info)); - - if (indirect) { - tc_set_resource_reference(&p->draw.indirect->buffer, indirect->buffer); - tc_set_resource_reference(&p->indirect.indirect_draw_count, - indirect->indirect_draw_count); - p->indirect.count_from_stream_output = NULL; - pipe_so_target_reference(&p->indirect.count_from_stream_output, - indirect->count_from_stream_output); - memcpy(&p->indirect, indirect, sizeof(*indirect)); - p->draw.indirect = &p->indirect; - } } } diff --git a/src/gallium/auxiliary/util/u_threaded_context_calls.h b/src/gallium/auxiliary/util/u_threaded_context_calls.h index 3bd43d9803abedc43858413ef0ebffd596959b27..a3551a908e70e5cea750869c31e5bdf915515e03 100644 --- a/src/gallium/auxiliary/util/u_threaded_context_calls.h +++ b/src/gallium/auxiliary/util/u_threaded_context_calls.h @@ -27,6 +27,7 @@ CALL(buffer_subdata) CALL(texture_subdata) CALL(emit_string_marker) CALL(draw_vbo) +CALL(draw_indirect) CALL(launch_grid) CALL(resource_copy_region) CALL(blit) diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 19898dc7dc5b18d874c68e391e347b7f2f7da27c..d7be7ef82ed86e180d6e94d28b009ebd4489ede5 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -1257,7 +1257,6 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info, unsigned draw_count) { assert(info->index_size); - info->indirect = NULL; for (unsigned i = 0; i < draw_count; i++) { unsigned offset = i * stride / 4; @@ -1272,11 +1271,12 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info, info->index_bias = indirect_data[offset + 3]; info->start_instance = indirect_data[offset + 4]; - u_vbuf_draw_vbo(mgr, info); + u_vbuf_draw_vbo(mgr, info, NULL); } } -void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) +void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct pipe_context *pipe = mgr->pipe; int start_vertex; @@ -1299,15 +1299,14 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) u_vbuf_set_driver_vertex_buffers(mgr); } - pipe->draw_vbo(pipe, info); + pipe->draw_vbo(pipe, info, indirect); return; } new_info = *info; /* Handle indirect (multi)draws. */ - if (new_info.indirect && new_info.indirect->buffer) { - const struct pipe_draw_indirect_info *indirect = new_info.indirect; + if (indirect && indirect->buffer) { unsigned draw_count = 0; /* Get the number of draws. */ @@ -1487,7 +1486,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) * We would have to break this drawing operation into several ones. */ /* Use some heuristic to see if unrolling indices improves * performance. */ - if (!info->indirect && + if (!indirect && !new_info.primitive_restart && util_is_vbo_upload_ratio_too_large(new_info.count, num_vertices) && !u_vbuf_mapping_vertex_buffer_blocks(mgr)) { @@ -1565,7 +1564,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) u_upload_unmap(pipe->stream_uploader); u_vbuf_set_driver_vertex_buffers(mgr); - pipe->draw_vbo(pipe, &new_info); + pipe->draw_vbo(pipe, &new_info, indirect); if (mgr->using_translate) { u_vbuf_translate_end(mgr); diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h index 1b09bf02e2d64fb860f224b54d1b21dba5c087bf..c2f21878aac4723f932629580db18699ecd9b8ca 100644 --- a/src/gallium/auxiliary/util/u_vbuf.h +++ b/src/gallium/auxiliary/util/u_vbuf.h @@ -77,7 +77,8 @@ void u_vbuf_unset_vertex_elements(struct u_vbuf *mgr); void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned start_slot, unsigned count, const struct pipe_vertex_buffer *bufs); -void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info); +void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); void u_vbuf_get_minmax_index(struct pipe_context *pipe, const struct pipe_draw_info *info, unsigned *out_min_index, unsigned *out_max_index); diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index b805218a949f624bdd97b2eeb4b0c01013a3d336..0fec54159932e1160573eed226befaf3f39f66ed 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -319,7 +319,8 @@ d3d12_apply_resource_states(struct d3d12_context* ctx); void d3d12_draw_vbo(struct pipe_context *pctx, - const struct pipe_draw_info *dinfo); + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *indirect); void d3d12_blit(struct pipe_context *pctx, diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index 44a5f01437bdc18f6158bbc1e689a94473dde627..af5506314ba68afc7b66cecd3633b1a466effa71 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -357,7 +357,7 @@ twoface_emulation(struct d3d12_context *ctx, { /* draw backfaces */ ctx->base.bind_rasterizer_state(&ctx->base, rast->twoface_back); - d3d12_draw_vbo(&ctx->base, dinfo); + d3d12_draw_vbo(&ctx->base, dinfo, NULL); /* restore real state */ ctx->base.bind_rasterizer_state(&ctx->base, rast); @@ -416,7 +416,8 @@ d3d12_last_vertex_stage(struct d3d12_context *ctx) void d3d12_draw_vbo(struct pipe_context *pctx, - const struct pipe_draw_info *dinfo) + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *indirect) { struct d3d12_context *ctx = d3d12_context(pctx); struct d3d12_batch *batch; diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 40d9656affdb4b78c6191f0f625e831eaa09a01b..180ff95ee9bc51bf3f9ae8e716c49ffe132798d7 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -223,7 +223,8 @@ etna_get_fs(struct etna_context *ctx, struct etna_shader_key key) } static void -etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) +etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct etna_context *ctx = etna_context(pctx); struct etna_screen *screen = ctx->screen; @@ -231,7 +232,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) uint32_t draw_mode; unsigned i; - if (!info->indirect && + if (!indirect && !info->primitive_restart && !u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) return; diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c index 938c0ba9d34c500586358e192be64ed76bf59532..30130c92ea730eb0aabd13fbaaf8a5152f11eba2 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c @@ -152,6 +152,7 @@ draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info, static bool fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *pinfo, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { if (!ctx->prog.fs || !ctx->prog.vs) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index e5485a0a01185379c690161d94fe961cbf2d9311..9e29dfd4b4106839c15d10f3652dd32b2c5c37fc 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -114,6 +114,7 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key) static bool fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { struct fd3_context *fd3_ctx = fd3_context(ctx); @@ -122,6 +123,7 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, .vtx = &ctx->vtx, .prog = &ctx->prog, .info = info, + .indirect = indirect, .key = { .color_two_side = ctx->rasterizer->light_twoside, .vclamp_color = ctx->rasterizer->clamp_vertex_color, diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index e62bcb8d7d955ab78f47070ebe88adb677731fd3..b6c22f609f0d080fff576df5b9308fd8d9f28328 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -747,7 +747,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, HLSQ_FLUSH); if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */ - ir3_emit_vs_consts(vp, ring, ctx, emit->info); + ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect); if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h index 95af61c6009f474ae3af6f630c0799f0e5985c8c..8f88684f7c78a9611c195b05f5b8f7efedef1410 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h @@ -46,6 +46,7 @@ struct fd3_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + const struct pipe_draw_indirect_info *indirect; bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c index fadc1511e628a1dc3d4f8a8a54b535c305fe5e12..304fb6b075f7dafd692088985a5cf3ab1c3adc38 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c @@ -68,7 +68,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring, fd4_draw_emit(ctx->batch, ring, primtype, emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, - info, index_offset); + info, emit->indirect, index_offset); } /* fixup dirty shader state in case some "unrelated" (from the state- @@ -98,6 +98,7 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key) static bool fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { struct fd4_context *fd4_ctx = fd4_context(ctx); @@ -106,6 +107,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, .vtx = &ctx->vtx, .prog = &ctx->prog, .info = info, + .indirect = indirect, .key = { .color_two_side = ctx->rasterizer->light_twoside, .vclamp_color = ctx->rasterizer->clamp_vertex_color, diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.h b/src/gallium/drivers/freedreno/a4xx/fd4_draw.h index bf3a6346aa6d218e4978bd5a1f080e69460ee152..cadea8f9268bf8bcd6909a053f96a0001e2a8537 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.h +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.h @@ -90,6 +90,7 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, enum pc_di_primtype primtype, enum pc_di_vis_cull_mode vismode, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { struct pipe_resource *idx_buffer = NULL; @@ -97,8 +98,8 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, enum pc_di_src_sel src_sel; uint32_t idx_size, idx_offset; - if (info->indirect && info->indirect->buffer) { - struct fd_resource *ind = fd_resource(info->indirect->buffer); + if (indirect && indirect->buffer) { + struct fd_resource *ind = fd_resource(indirect->buffer); emit_marker(ring, 7); @@ -112,12 +113,12 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, OUT_RELOC(ring, fd_resource(idx)->bo, index_offset, 0, 0); OUT_RING(ring, A4XX_CP_DRAW_INDX_INDIRECT_2_INDX_SIZE( idx->width0 - index_offset)); - OUT_RELOC(ring, ind->bo, info->indirect->offset, 0, 0); + OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); } else { OUT_PKT3(ring, CP_DRAW_INDIRECT, 2); OUT_RINGP(ring, DRAW4(primtype, DI_SRC_SEL_AUTO_INDEX, 0, 0), &batch->draw_patches); - OUT_RELOC(ring, ind->bo, info->indirect->offset, 0, 0); + OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); } emit_marker(ring, 7); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 809822feaac1fb0c3a978e8198af117713a6cd9b..fc1f54307f5432063d5569ab415eab12b64257cd 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -700,7 +700,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, } if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */ - ir3_emit_vs_consts(vp, ring, ctx, emit->info); + ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect); if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); } diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.h b/src/gallium/drivers/freedreno/a4xx/fd4_emit.h index 0d0a755c03f36818ff8f353572d9fa814dd98433..a0f01eb9fd1b1e15f798a57a5bc8c6750131ba09 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.h +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.h @@ -45,6 +45,7 @@ struct fd4_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + const struct pipe_draw_indirect_info *indirect; bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c index 0d7514de6e8d1a012c75dd5db5dbebd2e0e19b79..17a0a11eb184d160db2bc4d106deca429ae1d22f 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c @@ -63,7 +63,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring, fd5_emit_render_cntl(ctx, false, emit->binning_pass); fd5_draw_emit(ctx->batch, ring, primtype, emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY, - info, index_offset); + info, emit->indirect, index_offset); } /* fixup dirty shader state in case some "unrelated" (from the state- @@ -93,6 +93,7 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key) static bool fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { struct fd5_context *fd5_ctx = fd5_context(ctx); @@ -101,6 +102,7 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, .vtx = &ctx->vtx, .prog = &ctx->prog, .info = info, + .indirect = indirect, .key = { .color_two_side = ctx->rasterizer->light_twoside, .vclamp_color = ctx->rasterizer->clamp_vertex_color, diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.h b/src/gallium/drivers/freedreno/a5xx/fd5_draw.h index 71ede21a96fcb8dcdf35ea625720a95540f86365..5160a11a7bde8cb742cd8e057584e632cdc0b810 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.h @@ -84,6 +84,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, enum pc_di_primtype primtype, enum pc_di_vis_cull_mode vismode, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { struct pipe_resource *idx_buffer = NULL; @@ -91,8 +92,8 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, enum pc_di_src_sel src_sel; uint32_t max_indices, idx_offset; - if (info->indirect && info->indirect->buffer) { - struct fd_resource *ind = fd_resource(info->indirect->buffer); + if (indirect && indirect->buffer) { + struct fd_resource *ind = fd_resource(indirect->buffer); emit_marker5(ring, 7); @@ -107,12 +108,12 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, OUT_RELOC(ring, fd_resource(idx)->bo, index_offset, 0, 0); OUT_RING(ring, A5XX_CP_DRAW_INDX_INDIRECT_3_MAX_INDICES(max_indices)); - OUT_RELOC(ring, ind->bo, info->indirect->offset, 0, 0); + OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); } else { OUT_PKT7(ring, CP_DRAW_INDIRECT, 3); OUT_RINGP(ring, DRAW4(primtype, DI_SRC_SEL_AUTO_INDEX, 0, 0), &batch->draw_patches); - OUT_RELOC(ring, ind->bo, info->indirect->offset, 0, 0); + OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); } emit_marker5(ring, 7); diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index 0a6db47a3cd9ae1a5ccc27c589cda1e2abec93a1..58a3c1022f7f71426d0f911fcf56023222352704 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -707,7 +707,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, A5XX_SP_FS_OUTPUT_CNTL_SAMPLEMASK_REGID(regid(63, 0))); } - ir3_emit_vs_consts(vp, ring, ctx, emit->info); + ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect); if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h index 14e8aa0ce67d41ded27ad44ede10e095205975f4..e2d4dad88d9a4b7a8e201b62b5567ccf33e0e76d 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h @@ -45,6 +45,7 @@ struct fd5_emit { const struct fd_vertex_state *vtx; const struct fd_program_stateobj *prog; const struct pipe_draw_info *info; + const struct pipe_draw_indirect_info *indirect; bool binning_pass; struct ir3_shader_key key; enum fd_dirty_3d_state dirty; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_const.c b/src/gallium/drivers/freedreno/a6xx/fd6_const.c index 78b7b05a32c31cd514f890492fa626a4c5003238..8476353c59608d07728db76fb7fb742f8be106be 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_const.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_const.c @@ -359,7 +359,7 @@ fd6_emit_consts(struct fd6_emit *emit) if (ir3_needs_vs_driver_params(vs)) { struct fd_ringbuffer *dpconstobj = fd_submit_new_ringbuffer( ctx->batch->submit, IR3_DP_VS_COUNT * 4, FD_RINGBUFFER_STREAMING); - ir3_emit_vs_driver_params(vs, dpconstobj, ctx, emit->info); + ir3_emit_vs_driver_params(vs, dpconstobj, ctx, emit->info, emit->indirect); fd6_emit_take_group(emit, dpconstobj, FD6_GROUP_VS_DRIVER_PARAMS, ENABLE_ALL); fd6_ctx->has_dp_state = true; } else if (fd6_ctx->has_dp_state) { diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index 3f23289baa346f1de1c6defa2224a1a5b6b906ce..5ca23828b1942aab9fa345a2112a92496448cee3 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -47,9 +47,10 @@ static void draw_emit_indirect(struct fd_ringbuffer *ring, struct CP_DRAW_INDX_OFFSET_0 *draw0, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { - struct fd_resource *ind = fd_resource(info->indirect->buffer); + struct fd_resource *ind = fd_resource(indirect->buffer); if (info->index_size) { struct pipe_resource *idx = info->index.resource; @@ -61,13 +62,13 @@ draw_emit_indirect(struct fd_ringbuffer *ring, fd_resource(idx)->bo, index_offset), A5XX_CP_DRAW_INDX_INDIRECT_3(.max_indices = max_indices), A5XX_CP_DRAW_INDX_INDIRECT_INDIRECT( - ind->bo, info->indirect->offset) + ind->bo, indirect->offset) ); } else { OUT_PKT(ring, CP_DRAW_INDIRECT, pack_CP_DRAW_INDX_OFFSET_0(*draw0), A5XX_CP_DRAW_INDIRECT_INDIRECT( - ind->bo, info->indirect->offset) + ind->bo, indirect->offset) ); } } @@ -140,6 +141,7 @@ fixup_draw_state(struct fd_context *ctx, struct fd6_emit *emit) static bool fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset) { struct fd6_context *fd6_ctx = fd6_context(ctx); @@ -148,6 +150,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, .ctx = ctx, .vtx = &ctx->vtx, .info = info, + .indirect = indirect, .key = { .vs = ctx->prog.vs, .gs = ctx->prog.gs, @@ -195,7 +198,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, if (emit.key.gs) emit.key.key.has_gs = true; - if (!(emit.key.hs || emit.key.ds || emit.key.gs || (info->indirect && info->indirect->buffer))) + if (!(emit.key.hs || emit.key.ds || emit.key.gs || (indirect && indirect->buffer))) fd6_vsc_update_sizes(ctx->batch, info); fixup_shader_state(ctx, &emit.key.key); @@ -315,8 +318,8 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, */ emit_marker6(ring, 7); - if (info->indirect && info->indirect->buffer) { - draw_emit_indirect(ring, &draw0, info, index_offset); + if (indirect && indirect->buffer) { + draw_emit_indirect(ring, &draw0, info, indirect, index_offset); } else { draw_emit(ring, &draw0, info, index_offset); } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h index c66418b1644640e2ba6e2bf7216d142be2240a9c..bf7700f1a7b67efe420a07193e9ce2cf72b5c59e 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h @@ -86,6 +86,7 @@ struct fd6_emit { struct fd_context *ctx; const struct fd_vertex_state *vtx; const struct pipe_draw_info *info; + const struct pipe_draw_indirect_info *indirect; struct ir3_cache_key key; enum fd_dirty_3d_state dirty; diff --git a/src/gallium/drivers/freedreno/freedreno_blitter.c b/src/gallium/drivers/freedreno/freedreno_blitter.c index 59e3546833623c3d0536868365a6dd3e91628b5a..55773af10bb7edc84042c8201b61488cad3e0ace 100644 --- a/src/gallium/drivers/freedreno/freedreno_blitter.c +++ b/src/gallium/drivers/freedreno/freedreno_blitter.c @@ -238,7 +238,7 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers, .max_index = 1, .instance_count = 1, }; - pctx->draw_vbo(pctx, &info); + pctx->draw_vbo(pctx, &info, NULL); /* We expect that this should not have triggered a change in pfb: */ assert(util_framebuffer_state_equal(pfb, &ctx->framebuffer)); diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index e2064c0d5d48782bf15d0c9905581f25c23055e0..d3812279a4906ca1d9f2cd35b106b7267a35e056 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -390,6 +390,7 @@ struct fd_context { /* draw: */ bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, unsigned index_offset); bool (*clear)(struct fd_context *ctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil); diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 9e432b0e173e8968618d700ecec85ec49111d88b..fdeb9ddc5c1ba2950909d39b66fea2fa616dc242 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -59,7 +59,8 @@ resource_written(struct fd_batch *batch, struct pipe_resource *prsc) } static void -batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info) +batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct fd_context *ctx = batch->ctx; struct pipe_framebuffer_state *pfb = &batch->framebuffer; @@ -175,8 +176,8 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info) resource_read(batch, info->index.resource); /* Mark indirect draw buffer as being read */ - if (info->indirect && info->indirect->buffer) - resource_read(batch, info->indirect->buffer); + if (indirect && indirect->buffer) + resource_read(batch, indirect->buffer); /* Mark textures as being read */ if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX) { @@ -210,7 +211,8 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info) } static void -fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) +fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct fd_context *ctx = fd_context(pctx); @@ -218,13 +220,13 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) * to be able to emulate it, to determine if game is feeding us * bogus data: */ - if (info->indirect && info->indirect->buffer && (fd_mesa_debug & FD_DBG_NOINDR)) { - util_draw_indirect(pctx, info); + if (indirect && indirect->buffer && (fd_mesa_debug & FD_DBG_NOINDR)) { + util_draw_indirect(pctx, info, indirect); return; } if (info->mode != PIPE_PRIM_MAX && - !info->indirect && + !indirect && !info->primitive_restart && !u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) return; @@ -266,7 +268,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) fd_context_all_dirty(ctx); } - batch_draw_tracking(batch, info); + batch_draw_tracking(batch, info, indirect); while (unlikely(!fd_batch_lock_submit(batch))) { /* The current batch was flushed in batch_draw_tracking() @@ -275,7 +277,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) */ fd_batch_reference(&batch, NULL); batch = fd_context_batch(ctx); - batch_draw_tracking(batch, info); + batch_draw_tracking(batch, info, indirect); assert(ctx->batch == batch); } @@ -318,7 +320,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) util_format_short_name(pipe_surface_format(pfb->cbufs[0])), util_format_short_name(pipe_surface_format(pfb->zsbuf))); - if (ctx->draw_vbo(ctx, info, index_offset)) + if (ctx->draw_vbo(ctx, info, indirect, index_offset)) batch->needs_flush = true; batch->num_vertices += info->count * info->instance_count; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_const.h b/src/gallium/drivers/freedreno/ir3/ir3_const.h index 4dc36c47c5d5e6733938b8f633a71f40d284e31e..4db055cd552a164271fec75918bd82d648bb4376 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_const.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_const.h @@ -513,8 +513,9 @@ ir3_needs_vs_driver_params(const struct ir3_shader_variant *v) static inline void ir3_emit_vs_driver_params(const struct ir3_shader_variant *v, - struct fd_ringbuffer *ring, struct fd_context *ctx, - const struct pipe_draw_info *info) + struct fd_ringbuffer *ring, struct fd_context *ctx, + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { debug_assert(ir3_needs_vs_driver_params(v)); @@ -555,13 +556,12 @@ ir3_emit_vs_driver_params(const struct ir3_shader_variant *v, * and means we can't easily emit these consts in cmd * stream so need to copy them to bo. */ - if (info->indirect && needs_vtxid_base) { - struct pipe_draw_indirect_info *indirect = info->indirect; + if (indirect && needs_vtxid_base) { struct pipe_resource *vertex_params_rsc = pipe_buffer_create(&ctx->screen->base, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM, vertex_params_size * 4); - unsigned src_off = info->indirect->offset;; + unsigned src_off = indirect->offset;; void *ptr; ptr = fd_bo_map(fd_resource(vertex_params_rsc)->bo); @@ -596,7 +596,8 @@ ir3_emit_vs_driver_params(const struct ir3_shader_variant *v, static inline void ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring, - struct fd_context *ctx, const struct pipe_draw_info *info) + struct fd_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { debug_assert(v->type == MESA_SHADER_VERTEX); @@ -605,7 +606,7 @@ ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin /* emit driver params every time: */ if (info && ir3_needs_vs_driver_params(v)) { ring_wfi(ctx->batch, ring); - ir3_emit_vs_driver_params(v, ring, ctx, info); + ir3_emit_vs_driver_params(v, ring, ctx, info, indirect); } } @@ -621,7 +622,7 @@ ir3_emit_fs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin /* emit compute-shader consts: */ static inline void ir3_emit_cs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring, - struct fd_context *ctx, const struct pipe_grid_info *info) + struct fd_context *ctx, const struct pipe_grid_info *info) { debug_assert(gl_shader_stage_is_compute(v->type)); diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index f5116b80043ac10134bf5e5174ad0e74ac85195a..7750f906405aa6c29381b9fc9da268cbcf5c7d30 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -51,7 +51,8 @@ DEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE) static void -i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; @@ -109,7 +110,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* * Do the drawing */ - draw_vbo(i915->draw, info); + draw_vbo(i915->draw, info, NULL); /* * unmap vertex/index buffers diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 83d013802388401df043715b23e2b812ae5971b9..05e8ae32d6aca346d99040ff337519fa8f257c25 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -822,7 +822,8 @@ void iris_copy_region(struct blorp_context *blorp, /* iris_draw.c */ -void iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info); +void iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); void iris_launch_grid(struct pipe_context *, const struct pipe_grid_info *); /* iris_pipe_control.c */ diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c index 171ce4f5a6e98ecaf18677a0cee43f9c452b197a..844887c37631955aee81160a62f79f54e8dafb54 100644 --- a/src/gallium/drivers/iris/iris_draw.c +++ b/src/gallium/drivers/iris/iris_draw.c @@ -111,17 +111,18 @@ iris_update_draw_info(struct iris_context *ice, */ static void iris_update_draw_parameters(struct iris_context *ice, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { bool changed = false; if (ice->state.vs_uses_draw_params) { struct iris_state_ref *draw_params = &ice->draw.draw_params; - if (info->indirect && info->indirect->buffer) { - pipe_resource_reference(&draw_params->res, info->indirect->buffer); + if (indirect && indirect->buffer) { + pipe_resource_reference(&draw_params->res, indirect->buffer); draw_params->offset = - info->indirect->offset + (info->index_size ? 12 : 8); + indirect->offset + (info->index_size ? 12 : 8); changed = true; ice->draw.params_valid = false; @@ -171,12 +172,14 @@ iris_update_draw_parameters(struct iris_context *ice, static void iris_indirect_draw_vbo(struct iris_context *ice, - const struct pipe_draw_info *dinfo) + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *dindirect) { struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; struct pipe_draw_info info = *dinfo; + struct pipe_draw_indirect_info indirect = *dindirect; - if (info.indirect->indirect_draw_count && + if (indirect.indirect_draw_count && ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) { /* Upload MI_PREDICATE_RESULT to GPR15.*/ batch->screen->vtbl.load_register_reg64(batch, CS_GPR(15), MI_PREDICATE_RESULT); @@ -185,22 +188,22 @@ iris_indirect_draw_vbo(struct iris_context *ice, const uint64_t orig_dirty = ice->state.dirty; const uint64_t orig_stage_dirty = ice->state.stage_dirty; - for (int i = 0; i < info.indirect->draw_count; i++) { + for (int i = 0; i < indirect.draw_count; i++) { info.drawid = i; iris_batch_maybe_flush(batch, 1500); - iris_update_draw_parameters(ice, &info); + iris_update_draw_parameters(ice, &info, &indirect); - batch->screen->vtbl.upload_render_state(ice, batch, &info, info.indirect); + batch->screen->vtbl.upload_render_state(ice, batch, &info, &indirect); ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER; ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER; - info.indirect->offset += info.indirect->stride; + indirect.offset += indirect.stride; } - if (info.indirect->indirect_draw_count && + if (indirect.indirect_draw_count && ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) { /* Restore MI_PREDICATE_RESULT. */ batch->screen->vtbl.load_register_reg64(batch, MI_PREDICATE_RESULT, CS_GPR(15)); @@ -213,28 +216,29 @@ iris_indirect_draw_vbo(struct iris_context *ice, static void iris_simple_draw_vbo(struct iris_context *ice, - const struct pipe_draw_info *draw) + const struct pipe_draw_info *draw, + const struct pipe_draw_indirect_info *indirect) { struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; iris_batch_maybe_flush(batch, 1500); - iris_update_draw_parameters(ice, draw); + iris_update_draw_parameters(ice, draw, indirect); - batch->screen->vtbl.upload_render_state(ice, batch, draw, draw->indirect); + batch->screen->vtbl.upload_render_state(ice, batch, draw, indirect); } /** * The pipe->draw_vbo() driver hook. Performs a draw on the GPU. */ void -iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) +iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct iris_context *ice = (struct iris_context *) ctx; struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen; const struct gen_device_info *devinfo = &screen->devinfo; struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; - struct pipe_draw_indirect_info *indirect = info->indirect; if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER) return; @@ -271,9 +275,9 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) iris_handle_always_flush_cache(batch); if (indirect && indirect->buffer) - iris_indirect_draw_vbo(ice, info); + iris_indirect_draw_vbo(ice, info, indirect); else - iris_simple_draw_vbo(ice, info); + iris_simple_draw_vbo(ice, info, indirect); iris_handle_always_flush_cache(batch); diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 5c60eee2c701a39ca4f6cb69f5ed2835678b5e4d..f489b6e3e542fed945522010a869a2907683341b 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -1121,7 +1121,8 @@ lima_draw_vbo_count(struct pipe_context *pctx, static void lima_draw_vbo(struct pipe_context *pctx, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { /* check if draw mode and vertex/index count match, * otherwise gp will hang */ diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 4ee88c888e8deee802547dad25a7d25d424ba17f..c5e5ab0b6711e0248528da325a35d008ee81827d 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -51,7 +51,8 @@ * the drawing to the 'draw' module. */ static void -llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; @@ -61,8 +62,8 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (!llvmpipe_check_render_cond(lp)) return; - if (info->indirect && info->indirect->buffer) { - util_draw_indirect(pipe, info); + if (indirect && indirect->buffer) { + util_draw_indirect(pipe, info, indirect); return; } @@ -139,7 +140,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) !lp->queries_disabled); /* draw! */ - draw_vbo(draw, info); + draw_vbo(draw, info, indirect); /* * unmap vertex/index buffers diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c index 5f3b697a37b67e25e2f5502cf00ebd193934e25d..884fd56cc3755451c699f92c38656430e4f8a442 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c @@ -443,7 +443,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) draw_set_indexes(draw, NULL, 0, 0); } - draw_vbo(draw, info); + draw_vbo(draw, info, NULL); draw_flush(draw); if (info->index_size && transferi) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c index b50157c3b1ad53e6fbf083377dea95f3977b08ad..6f941d0700892b74f0c0b9bd7ef8ac1933ef3bb2 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c @@ -544,7 +544,8 @@ nv30_draw_elements(struct nv30_context *nv30, bool shorten, } static void -nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct nv30_context *nv30 = nv30_context(pipe); struct nouveau_pushbuf *push = nv30->base.pushbuf; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h index 9894e9d613fd08a403dcdd5362eade17dd7a172f..ff7edc67918d72ab4feca08cd8cd70d9cdc1396f 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_context.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h @@ -291,7 +291,8 @@ nv50_cb_push(struct nouveau_context *nv, unsigned offset, unsigned words, const uint32_t *data); /* nv50_vbo.c */ -void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *); +void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *, + const struct pipe_draw_indirect_info *indirect); void * nv50_vertex_state_create(struct pipe_context *pipe, @@ -303,7 +304,8 @@ nv50_vertex_state_delete(struct pipe_context *pipe, void *hwcso); void nv50_vertex_arrays_validate(struct nv50_context *nv50); /* nv50_push.c */ -void nv50_push_vbo(struct nv50_context *, const struct pipe_draw_info *); +void nv50_push_vbo(struct nv50_context *, const struct pipe_draw_info *, + const struct pipe_draw_indirect_info *indirect); /* nv84_video.c */ struct pipe_video_codec * diff --git a/src/gallium/drivers/nouveau/nv50/nv50_push.c b/src/gallium/drivers/nouveau/nv50/nv50_push.c index d10399530c9afa87bea1e04847689431552e51c3..39798ee6ae09638ea2d846953d1c69d500e07294 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_push.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_push.c @@ -238,7 +238,8 @@ nv50_prim_gl(unsigned prim) } void -nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) +nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct push_context ctx; unsigned i, index_size; @@ -292,10 +293,10 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) ctx.primitive_restart = info->primitive_restart; ctx.restart_index = info->restart_index; } else { - if (unlikely(info->indirect && info->indirect->count_from_stream_output)) { + if (unlikely(indirect && indirect->count_from_stream_output)) { struct pipe_context *pipe = &nv50->base.pipe; struct nv50_so_target *targ; - targ = nv50_so_target(info->indirect->count_from_stream_output); + targ = nv50_so_target(indirect->count_from_stream_output); if (!targ->pq) { NOUVEAU_ERR("draw_stream_output not supported on pre-NVA0 cards\n"); return; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c index 7d9c47df037450e7c68dfc62e2c167347c4cbdd7..10906c7f56457c7b7c49137a43f77f788952537f 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c @@ -699,10 +699,11 @@ nv50_draw_elements(struct nv50_context *nv50, bool shorten, static void nva0_draw_stream_output(struct nv50_context *nv50, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct nouveau_pushbuf *push = nv50->base.pushbuf; - struct nv50_so_target *so = nv50_so_target(info->indirect->count_from_stream_output); + struct nv50_so_target *so = nv50_so_target(indirect->count_from_stream_output); struct nv04_resource *res = nv04_resource(so->pipe.buffer); unsigned num_instances = info->instance_count; unsigned mode = nv50_prim_gl(info->mode); @@ -753,7 +754,8 @@ nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan) } void -nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; @@ -826,7 +828,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } if (nv50->vbo_fifo) { - nv50_push_vbo(nv50, info); + nv50_push_vbo(nv50, info, indirect); goto cleanup; } @@ -874,8 +876,8 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start, info->count, info->instance_count, info->index_bias, info->index_size); } else - if (unlikely(info->indirect && info->indirect->count_from_stream_output)) { - nva0_draw_stream_output(nv50, info); + if (unlikely(indirect && indirect->count_from_stream_output)) { + nva0_draw_stream_output(nv50, info, indirect); } else { nv50_draw_arrays(nv50, info->mode, info->start, info->count, diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h index 282a643b8db7fb42a4ad8f43497c42dfb348872f..53e13cf82f892327e303c86e7a1da52297329125 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h @@ -413,7 +413,8 @@ nvc0_cb_bo_push(struct nouveau_context *, unsigned offset, unsigned words, const uint32_t *data); /* nvc0_vbo.c */ -void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *); +void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *, + const struct pipe_draw_indirect_info *indirect); void * nvc0_vertex_state_create(struct pipe_context *pipe, @@ -436,8 +437,10 @@ nvc0_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *templat); /* nvc0_push.c */ -void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *); -void nvc0_push_vbo_indirect(struct nvc0_context *, const struct pipe_draw_info *); +void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *, + const struct pipe_draw_indirect_info *indirect); +void nvc0_push_vbo_indirect(struct nvc0_context *, const struct pipe_draw_info *, + const struct pipe_draw_indirect_info *indirect); /* nve4_compute.c */ void nve4_launch_grid(struct pipe_context *, const struct pipe_grid_info *); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index 3b44d6605c988796f4122ca94977b0a0310519be..6e84c04cbc05e88ad7f5e6e4dcbdc1ea25c2cb27 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -766,10 +766,11 @@ nvc0_draw_elements(struct nvc0_context *nvc0, bool shorten, static void nvc0_draw_stream_output(struct nvc0_context *nvc0, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; - struct nvc0_so_target *so = nvc0_so_target(info->indirect->count_from_stream_output); + struct nvc0_so_target *so = nvc0_so_target(indirect->count_from_stream_output); struct nv04_resource *res = nv04_resource(so->pipe.buffer); unsigned mode = nvc0_prim_gl(info->mode); unsigned num_instances = info->instance_count; @@ -802,13 +803,14 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0, } static void -nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info) +nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; - struct nv04_resource *buf = nv04_resource(info->indirect->buffer); - struct nv04_resource *buf_count = nv04_resource(info->indirect->indirect_draw_count); - unsigned size, macro, count = info->indirect->draw_count, drawid = info->drawid; - uint32_t offset = buf->offset + info->indirect->offset; + struct nv04_resource *buf = nv04_resource(indirect->buffer); + struct nv04_resource *buf_count = nv04_resource(indirect->indirect_draw_count); + unsigned size, macro, count = indirect->draw_count, drawid = info->drawid; + uint32_t offset = buf->offset + indirect->offset; struct nvc0_screen *screen = nvc0->screen; PUSH_SPACE(push, 7); @@ -857,7 +859,7 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info) */ while (count) { unsigned draws = count, pushes, i; - if (info->indirect->stride == size * 4) { + if (indirect->stride == size * 4) { draws = MIN2(draws, (NV04_PFIFO_MAX_PACKET_LEN - 4) / size); pushes = 1; } else { @@ -877,20 +879,20 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info) if (buf_count) { nouveau_pushbuf_data(push, buf_count->bo, - buf_count->offset + info->indirect->indirect_draw_count_offset, + buf_count->offset + indirect->indirect_draw_count_offset, NVC0_IB_ENTRY_1_NO_PREFETCH | 4); } if (pushes == 1) { nouveau_pushbuf_data(push, buf->bo, offset, NVC0_IB_ENTRY_1_NO_PREFETCH | (size * 4 * draws)); - offset += draws * info->indirect->stride; + offset += draws * indirect->stride; } else { for (i = 0; i < pushes; i++) { nouveau_pushbuf_data(push, buf->bo, offset, NVC0_IB_ENTRY_1_NO_PREFETCH | (size * 4)); - offset += info->indirect->stride; + offset += indirect->stride; } } count -= draws; @@ -920,7 +922,8 @@ nvc0_update_prim_restart(struct nvc0_context *nvc0, bool en, uint32_t index) } void -nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_pushbuf *push = nvc0->base.pushbuf; @@ -938,7 +941,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) * if index count is larger and we expect repeated vertices, suggest upload. */ nvc0->vbo_push_hint = - (!info->indirect || info->indirect->count_from_stream_output) && info->index_size && + (!indirect || indirect->count_from_stream_output) && info->index_size && (nvc0->vb_elt_limit >= (info->count * 2)); /* Check whether we want to switch vertex-submission mode. */ @@ -1005,7 +1008,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nvc0_state_validate_3d(nvc0, ~0); - if (nvc0->vertprog->vp.need_draw_parameters && (!info->indirect || info->indirect->count_from_stream_output)) { + if (nvc0->vertprog->vp.need_draw_parameters && (!indirect || indirect->count_from_stream_output)) { PUSH_SPACE(push, 9); BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); PUSH_DATA (push, NVC0_CB_AUX_SIZE); @@ -1057,10 +1060,10 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } if (nvc0->state.vbo_mode) { - if (info->indirect && info->indirect->buffer) - nvc0_push_vbo_indirect(nvc0, info); + if (indirect && indirect->buffer) + nvc0_push_vbo_indirect(nvc0, info, indirect); else - nvc0_push_vbo(nvc0, info); + nvc0_push_vbo(nvc0, info, indirect); goto cleanup; } @@ -1088,11 +1091,11 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nvc0->base.vbo_dirty = false; } - if (unlikely(info->indirect && info->indirect->buffer)) { - nvc0_draw_indirect(nvc0, info); + if (unlikely(indirect && indirect->buffer)) { + nvc0_draw_indirect(nvc0, info, indirect); } else - if (unlikely(info->indirect && info->indirect->count_from_stream_output)) { - nvc0_draw_stream_output(nvc0, info); + if (unlikely(indirect && indirect->count_from_stream_output)) { + nvc0_draw_stream_output(nvc0, info, indirect); } else if (info->index_size) { bool shorten = info->max_index <= 65535; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c index de08b9e6a19fb190643de0f7dcbb224959528f0b..abf10ac2f3c73c694b55833f9876b41e56bd0ef3 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c @@ -490,7 +490,8 @@ typedef struct { } DrawElementsIndirectCommand; void -nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info) +nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { /* The strategy here is to just read the commands from the indirect buffer * and do the draws. This is suboptimal, but will only happen in the case @@ -498,23 +499,22 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i */ struct nvc0_screen *screen = nvc0->screen; struct nouveau_pushbuf *push = nvc0->base.pushbuf; - struct nv04_resource *buf = nv04_resource(info->indirect->buffer); - struct nv04_resource *buf_count = nv04_resource(info->indirect->indirect_draw_count); + struct nv04_resource *buf = nv04_resource(indirect->buffer); + struct nv04_resource *buf_count = nv04_resource(indirect->indirect_draw_count); unsigned i; - unsigned draw_count = info->indirect->draw_count; + unsigned draw_count = indirect->draw_count; if (buf_count) { uint32_t *count = nouveau_resource_map_offset( - &nvc0->base, buf_count, info->indirect->indirect_draw_count_offset, + &nvc0->base, buf_count, indirect->indirect_draw_count_offset, NOUVEAU_BO_RD); draw_count = *count; } uint8_t *buf_data = nouveau_resource_map_offset( - &nvc0->base, buf, info->indirect->offset, NOUVEAU_BO_RD); + &nvc0->base, buf, indirect->offset, NOUVEAU_BO_RD); struct pipe_draw_info single = *info; - single.indirect = NULL; - for (i = 0; i < draw_count; i++, buf_data += info->indirect->stride) { + for (i = 0; i < draw_count; i++, buf_data += indirect->stride) { if (info->index_size) { DrawElementsIndirectCommand *cmd = (void *)buf_data; single.start = info->start + cmd->firstIndex; @@ -543,7 +543,7 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i PUSH_DATA (push, single.drawid + i); } - nvc0_push_vbo(nvc0, &single); + nvc0_push_vbo(nvc0, &single, NULL); } nouveau_resource_unmap(buf); @@ -552,7 +552,8 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i } void -nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) +nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct push_context ctx; unsigned i, index_size; @@ -596,10 +597,10 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) nvc0_push_map_idxbuf(&ctx, nvc0, info); index_size = info->index_size; } else { - if (unlikely(info->indirect && info->indirect->count_from_stream_output)) { + if (unlikely(indirect && indirect->count_from_stream_output)) { struct pipe_context *pipe = &nvc0->base.pipe; struct nvc0_so_target *targ; - targ = nvc0_so_target(info->indirect->count_from_stream_output); + targ = nvc0_so_target(indirect->count_from_stream_output); pipe->get_query_result(pipe, targ->pq, true, (void *)&vert_count); vert_count /= targ->stride; } diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 56f10361064adaab40de88a97e174efc486a5db3..2500226fb239861b6cf7d255ff59c3b0298e631f 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -330,6 +330,7 @@ panfrost_emit_primitive_size(struct panfrost_context *ctx, static void panfrost_draw_emit_tiler(struct panfrost_batch *batch, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, void *invocation_template, mali_ptr shared_mem, mali_ptr indices, mali_ptr fs_vary, mali_ptr varyings, @@ -363,8 +364,8 @@ panfrost_draw_emit_tiler(struct panfrost_batch *batch, cfg.base_vertex_offset = info->index_bias - ctx->offset_start; cfg.index_count = info->count; } else { - cfg.index_count = info->indirect && info->indirect->count_from_stream_output ? - pan_so_target(info->indirect->count_from_stream_output)->offset : + cfg.index_count = indirect && indirect->count_from_stream_output ? + pan_so_target(indirect->count_from_stream_output)->offset : ctx->vertex_count; } } @@ -422,7 +423,8 @@ panfrost_draw_emit_tiler(struct panfrost_batch *batch, static void panfrost_draw_vbo( struct pipe_context *pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct panfrost_context *ctx = pan_context(pipe); struct panfrost_device *device = pan_device(ctx->base.screen); @@ -441,7 +443,7 @@ panfrost_draw_vbo( if (info->primitive_restart && info->index_size && info->restart_index != primitive_index) { - util_draw_vbo_without_prim_restart(pipe, info); + util_draw_vbo_without_prim_restart(pipe, info, indirect); return; } @@ -527,7 +529,7 @@ panfrost_draw_vbo( /* Fire off the draw itself */ panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem, vs_vary, varyings, vertex.cpu); - panfrost_draw_emit_tiler(batch, info, &invocation, shared_mem, indices, + panfrost_draw_emit_tiler(batch, info, indirect, &invocation, shared_mem, indices, fs_vary, varyings, pos, psiz, tiler.cpu); panfrost_emit_vertex_tiler_jobs(batch, &vertex, &tiler); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index b2fb8c37d9cca698de2b77023a009566b355692e..bec657022fb124ad26bd6207de7e4243dc56043d 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -780,7 +780,8 @@ static unsigned r300_max_vertex_count(struct r300_context *r300) static void r300_draw_vbo(struct pipe_context* pipe, - const struct pipe_draw_info *dinfo) + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *indirect) { struct r300_context* r300 = r300_context(pipe); struct pipe_draw_info info = *dinfo; @@ -838,7 +839,8 @@ static void r300_draw_vbo(struct pipe_context* pipe, /* SW TCL elements, using Draw. */ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct r300_context* r300 = r300_context(pipe); @@ -859,7 +861,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, r300_update_derived_state(r300); - draw_vbo(r300->draw, info); + draw_vbo(r300->draw, info, NULL); draw_flush(r300->draw); } diff --git a/src/gallium/drivers/r300/r300_render_stencilref.c b/src/gallium/drivers/r300/r300_render_stencilref.c index 747594afaf2763fa7952afeb176c5f2564e7d82a..d0261a251f72bef65eaee268274461370f36b45c 100644 --- a/src/gallium/drivers/r300/r300_render_stencilref.c +++ b/src/gallium/drivers/r300/r300_render_stencilref.c @@ -35,7 +35,8 @@ struct r300_stencilref_context { void (*draw_vbo)(struct pipe_context *pipe, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); uint32_t rs_cull_mode; uint32_t zb_stencilrefmask; @@ -101,18 +102,19 @@ static void r300_stencilref_end(struct r300_context *r300) } static void r300_stencilref_draw_vbo(struct pipe_context *pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct r300_context *r300 = r300_context(pipe); struct r300_stencilref_context *sr = r300->stencilref_fallback; if (!r300_stencilref_needed(r300)) { - sr->draw_vbo(pipe, info); + sr->draw_vbo(pipe, info, NULL); } else { r300_stencilref_begin(r300); - sr->draw_vbo(pipe, info); + sr->draw_vbo(pipe, info, NULL); r300_stencilref_switch_side(r300); - sr->draw_vbo(pipe, info); + sr->draw_vbo(pipe, info, NULL); r300_stencilref_end(r300); } } diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index a192d457b6d43ed1781ebe6e45059b3dea89b0d0..4772b448434d908b4b8b79e43076e2554923710c 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -2052,7 +2052,8 @@ static inline void r600_emit_rasterizer_prim_state(struct r600_context *rctx) rctx->last_rast_prim = rast_prim; } -static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) +static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct r600_context *rctx = (struct r600_context *)ctx; struct pipe_resource *indexbuf = info->has_user_indices ? NULL : info->index.resource; @@ -2065,7 +2066,6 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info int index_bias; struct r600_shader_atomic combined_atomics[8]; uint8_t atomic_used_mask = 0; - struct pipe_draw_indirect_info *indirect = info->indirect; struct pipe_stream_output_target *count_from_so = NULL; if (indirect && indirect->count_from_stream_output) { diff --git a/src/gallium/drivers/radeonsi/si_compute_prim_discard.c b/src/gallium/drivers/radeonsi/si_compute_prim_discard.c index d540f260c9b88255dcfb897c0f02fecf4c7032b6..e989590121cdc5fda2080a67ba96a8657a464e58 100644 --- a/src/gallium/drivers/radeonsi/si_compute_prim_discard.c +++ b/src/gallium/drivers/radeonsi/si_compute_prim_discard.c @@ -1000,7 +1000,7 @@ si_prepare_prim_discard_or_split_draw(struct si_context *sctx, const struct pipe for (unsigned i = 0; i < num_draws; i++) { if (count && count + draws[i].count > vert_count_per_subdraw) { /* Submit previous draws. */ - sctx->b.multi_draw(&sctx->b, info, draws + first_draw, num_draws_split); + sctx->b.multi_draw(&sctx->b, info, NULL, draws + first_draw, num_draws_split); count = 0; first_draw = i; num_draws_split = 0; @@ -1008,7 +1008,7 @@ si_prepare_prim_discard_or_split_draw(struct si_context *sctx, const struct pipe if (draws[i].count > vert_count_per_subdraw) { /* Submit just 1 draw. It will be split. */ - sctx->b.multi_draw(&sctx->b, info, draws + i, 1); + sctx->b.multi_draw(&sctx->b, info, NULL, draws + i, 1); assert(count == 0); assert(first_draw == i); assert(num_draws_split == 0); @@ -1036,7 +1036,7 @@ si_prepare_prim_discard_or_split_draw(struct si_context *sctx, const struct pipe split_draw_range.start = base_start + start; split_draw_range.count = MIN2(count - start, vert_count_per_subdraw); - sctx->b.multi_draw(&sctx->b, &split_draw, &split_draw_range, 1); + sctx->b.multi_draw(&sctx->b, &split_draw, NULL, &split_draw_range, 1); } } else if (prim == PIPE_PRIM_TRIANGLE_STRIP) { /* No primitive pair can be split, because strips reverse orientation @@ -1047,7 +1047,7 @@ si_prepare_prim_discard_or_split_draw(struct si_context *sctx, const struct pipe split_draw_range.start = base_start + start; split_draw_range.count = MIN2(count - start, vert_count_per_subdraw + 2); - sctx->b.multi_draw(&sctx->b, &split_draw, &split_draw_range, 1); + sctx->b.multi_draw(&sctx->b, &split_draw, NULL, &split_draw_range, 1); if (start == 0 && primitive_restart && sctx->cs_prim_discard_state.current->key.opt.cs_need_correct_orientation) diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 695995a3baf6500733d3c30dfcdc1fa97aff4797..5b0a72b7886331bc16a8692be55813291b05f2fc 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -496,11 +496,11 @@ static bool num_instanced_prims_less_than(const struct pipe_draw_info *info, ALWAYS_INLINE static unsigned si_get_ia_multi_vgt_param(struct si_context *sctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, enum pipe_prim_type prim, unsigned num_patches, unsigned instance_count, bool primitive_restart, unsigned min_vertex_count) { - const struct pipe_draw_indirect_info *indirect = info->indirect; union si_vgt_param_key key = sctx->ia_multi_vgt_param_key; unsigned primgroup_size; unsigned ia_multi_vgt_param; @@ -657,6 +657,7 @@ static bool si_prim_restart_index_changed(struct si_context *sctx, bool primitiv ALWAYS_INLINE static void si_emit_ia_multi_vgt_param(struct si_context *sctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, enum pipe_prim_type prim, unsigned num_patches, unsigned instance_count, bool primitive_restart, unsigned min_vertex_count) @@ -665,8 +666,8 @@ static void si_emit_ia_multi_vgt_param(struct si_context *sctx, const struct pip unsigned ia_multi_vgt_param; ia_multi_vgt_param = - si_get_ia_multi_vgt_param(sctx, info, prim, num_patches, instance_count, primitive_restart, - min_vertex_count); + si_get_ia_multi_vgt_param(sctx, info, indirect, prim, num_patches, instance_count, + primitive_restart, min_vertex_count); /* Draw state. */ if (ia_multi_vgt_param != sctx->last_multi_vgt_param) { @@ -729,6 +730,7 @@ static void gfx10_emit_ge_cntl(struct si_context *sctx, unsigned num_patches) ALWAYS_INLINE static void si_emit_draw_registers(struct si_context *sctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, enum pipe_prim_type prim, unsigned num_patches, unsigned instance_count, bool primitive_restart, unsigned min_vertex_count) @@ -739,8 +741,8 @@ static void si_emit_draw_registers(struct si_context *sctx, const struct pipe_dr if (sctx->chip_class >= GFX10) gfx10_emit_ge_cntl(sctx, num_patches); else - si_emit_ia_multi_vgt_param(sctx, info, prim, num_patches, instance_count, primitive_restart, - min_vertex_count); + si_emit_ia_multi_vgt_param(sctx, info, indirect, prim, num_patches, instance_count, + primitive_restart, min_vertex_count); if (vgt_prim != sctx->last_prim) { if (sctx->chip_class >= GFX10) @@ -770,13 +772,13 @@ static void si_emit_draw_registers(struct si_context *sctx, const struct pipe_dr } static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count *draws, unsigned num_draws, struct pipe_resource *indexbuf, unsigned index_size, unsigned index_offset, unsigned instance_count, bool dispatch_prim_discard_cs, unsigned original_index_size) { - struct pipe_draw_indirect_info *indirect = info->indirect; struct radeon_cmdbuf *cs = sctx->gfx_cs; unsigned sh_base_reg = sctx->shader_pointers.sh_base[PIPE_SHADER_VERTEX]; bool render_cond_bit = sctx->render_cond && !sctx->render_cond_force_off; @@ -1570,11 +1572,10 @@ static bool si_upload_vertex_buffer_descriptors(struct si_context *sctx) } static void si_get_draw_start_count(struct si_context *sctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count *draws, unsigned num_draws, unsigned *start, unsigned *count) { - struct pipe_draw_indirect_info *indirect = info->indirect; - if (indirect && !indirect->count_from_stream_output) { unsigned indirect_count; struct pipe_transfer *transfer; @@ -1641,6 +1642,7 @@ static void si_get_draw_start_count(struct si_context *sctx, const struct pipe_d } static void si_emit_all_states(struct si_context *sctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, enum pipe_prim_type prim, unsigned instance_count, unsigned min_vertex_count, bool primitive_restart, unsigned skip_atom_mask) @@ -1674,8 +1676,8 @@ static void si_emit_all_states(struct si_context *sctx, const struct pipe_draw_i /* Emit draw states. */ si_emit_vs_state(sctx, info); - si_emit_draw_registers(sctx, info, prim, num_patches, instance_count, primitive_restart, - min_vertex_count); + si_emit_draw_registers(sctx, info, indirect, prim, num_patches, instance_count, + primitive_restart, min_vertex_count); } static bool si_all_vs_resources_read_only(struct si_context *sctx, struct pipe_resource *indexbuf) @@ -1768,12 +1770,12 @@ static ALWAYS_INLINE bool pd_msg(const char *s) static void si_multi_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count *draws, unsigned num_draws) { struct si_context *sctx = (struct si_context *)ctx; struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; - struct pipe_draw_indirect_info *indirect = info->indirect; struct pipe_resource *indexbuf = info->index.resource; unsigned dirty_tex_counter, dirty_buf_counter; enum pipe_prim_type rast_prim, prim = info->mode; @@ -1887,7 +1889,7 @@ static void si_multi_draw_vbo(struct pipe_context *ctx, unsigned start, count, start_offset, size, offset; void *ptr; - si_get_draw_start_count(sctx, info, draws, num_draws, &start, &count); + si_get_draw_start_count(sctx, info, indirect, draws, num_draws, &start, &count); start_offset = start * 2; size = count * 2; @@ -2155,7 +2157,7 @@ static void si_multi_draw_vbo(struct pipe_context *ctx, masked_atoms |= si_get_atom_bit(sctx, &sctx->atoms.s.render_cond); /* Emit all states except possibly render condition. */ - si_emit_all_states(sctx, info, prim, instance_count, min_direct_count, + si_emit_all_states(sctx, info, indirect, prim, instance_count, min_direct_count, primitive_restart, masked_atoms); sctx->emit_cache_flush(sctx); /* <-- CUs are idle here. */ @@ -2172,7 +2174,7 @@ static void si_multi_draw_vbo(struct pipe_context *ctx, } assert(sctx->dirty_atoms == 0); - si_emit_draw_packets(sctx, info, draws, num_draws, + si_emit_draw_packets(sctx, info, indirect, draws, num_draws, indexbuf, index_size, index_offset, instance_count, dispatch_prim_discard_cs, original_index_size); /* <-- CUs are busy here. */ @@ -2193,7 +2195,7 @@ static void si_multi_draw_vbo(struct pipe_context *ctx, if (sctx->chip_class >= GFX7 && sctx->prefetch_L2_mask) cik_emit_prefetch_L2(sctx, true); - si_emit_all_states(sctx, info, prim, instance_count, min_direct_count, + si_emit_all_states(sctx, info, indirect, prim, instance_count, min_direct_count, primitive_restart, masked_atoms); if (gfx9_scissor_bug && @@ -2203,7 +2205,7 @@ static void si_multi_draw_vbo(struct pipe_context *ctx, } assert(sctx->dirty_atoms == 0); - si_emit_draw_packets(sctx, info, draws, num_draws, + si_emit_draw_packets(sctx, info, indirect, draws, num_draws, indexbuf, index_size, index_offset, instance_count, dispatch_prim_discard_cs, original_index_size); @@ -2246,11 +2248,12 @@ return_cleanup: } static void si_draw_vbo(struct pipe_context *ctx, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct pipe_draw_start_count draw = {info->start, info->count}; - si_multi_draw_vbo(ctx, info, &draw, 1); + si_multi_draw_vbo(ctx, info, indirect, &draw, 1); } static void si_draw_rectangle(struct blitter_context *blitter, void *vertex_elements_cso, @@ -2289,7 +2292,7 @@ static void si_draw_rectangle(struct blitter_context *blitter, void *vertex_elem sctx->vertex_buffer_pointer_dirty = false; sctx->vertex_buffer_user_sgprs_dirty = false; - si_draw_vbo(pipe, &info); + si_draw_vbo(pipe, &info, NULL); } void si_trace_emit(struct si_context *sctx) diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 1dd42594da5429c590bdad81df3206f714b6dbeb..dd8d9f266fec2ca517e0ded8d463eba89e2bb4ed 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -59,7 +59,8 @@ */ void softpipe_draw_vbo(struct pipe_context *pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; @@ -69,8 +70,8 @@ softpipe_draw_vbo(struct pipe_context *pipe, if (!softpipe_check_render_cond(sp)) return; - if (info->indirect && info->indirect->buffer) { - util_draw_indirect(pipe, info); + if (indirect && indirect->buffer) { + util_draw_indirect(pipe, info, indirect); return; } @@ -129,7 +130,7 @@ softpipe_draw_vbo(struct pipe_context *pipe, sp->active_statistics_queries > 0); /* draw! */ - draw_vbo(draw, info); + draw_vbo(draw, info, indirect); /* unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < sp->num_vertex_buffers; i++) { diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index af6b9782afa42111d1c6bb6238fbae463a15b682..2c43a4aeea732ee3fc41d786222e6a0b695e916b 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -180,7 +180,8 @@ softpipe_set_sampler_views(struct pipe_context *pipe, void softpipe_draw_vbo(struct pipe_context *pipe, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); void softpipe_map_texture_surfaces(struct softpipe_context *sp); diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 0986a1800d6c06c691fe297d28b3b96cc912a5c8..363661aae1d0375b13219779a4a5fd0cd225acc8 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -80,10 +80,11 @@ retry_draw_arrays( struct svga_context *svga, */ static enum pipe_error retry_draw_auto(struct svga_context *svga, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { assert(svga_have_sm5(svga)); - assert(info->indirect->count_from_stream_output); + assert(indirect->count_from_stream_output); assert(info->instance_count == 1); /* SO drawing implies core profile and none of these prim types */ assert(info->mode != PIPE_PRIM_QUADS && @@ -117,7 +118,7 @@ retry_draw_auto(struct svga_context *svga, 0, /* start instance */ 1, /* only 1 instance supported */ NULL, /* indirect drawing info */ - info->indirect->count_from_stream_output)); + indirect->count_from_stream_output)); return PIPE_OK; } @@ -129,10 +130,11 @@ retry_draw_auto(struct svga_context *svga, */ static enum pipe_error retry_draw_indirect(struct svga_context *svga, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { assert(svga_have_sm5(svga)); - assert(info->indirect && info->indirect->buffer); + assert(indirect && indirect->buffer); /* indirect drawing implies core profile and none of these prim types */ assert(info->mode != PIPE_PRIM_QUADS && info->mode != PIPE_PRIM_QUAD_STRIP && @@ -140,7 +142,7 @@ retry_draw_indirect(struct svga_context *svga, if (info->mode == PIPE_PRIM_LINE_LOOP) { /* need to do a fallback */ - util_draw_indirect(&svga->pipe, info); + util_draw_indirect(&svga->pipe, info, indirect); return PIPE_OK; } else { @@ -164,7 +166,7 @@ retry_draw_indirect(struct svga_context *svga, info->index.resource, info->start_instance, 0, /* don't know instance count */ - info->indirect, + indirect, NULL)); /* SO vertex count */ return PIPE_OK; @@ -214,7 +216,8 @@ get_vcount_from_stream_output(struct svga_context *svga, static void -svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct svga_context *svga = svga_context(pipe); enum pipe_prim_type reduced_prim = u_reduced_prim(info->mode); @@ -267,13 +270,13 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (need_fallback_prim_restart(svga, info)) { enum pipe_error r; - r = util_draw_vbo_without_prim_restart(pipe, info); + r = util_draw_vbo_without_prim_restart(pipe, info, indirect); assert(r == PIPE_OK); (void) r; goto done; } - if (!info->indirect && !u_trim_pipe_prim(info->mode, &count)) + if (!indirect && !u_trim_pipe_prim(info->mode, &count)) goto done; needed_swtnl = svga->state.sw.need_swtnl; @@ -296,7 +299,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* Avoid leaking the previous hwtnl bias to swtnl */ svga_hwtnl_set_index_bias(svga->hwtnl, 0); - ret = svga_swtnl_draw_vbo(svga, info); + ret = svga_swtnl_draw_vbo(svga, info, indirect); } else { if (!svga_update_state_retry(svga, SVGA_STATE_HW_DRAW)) { @@ -317,7 +320,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) svga_is_using_flat_shading(svga), svga->curr.rast->templ.flatshade_first); - if (info->indirect && info->indirect->count_from_stream_output) { + if (indirect && indirect->count_from_stream_output) { unsigned stream = 0; assert(count == 0); @@ -331,7 +334,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* Check the stream index of the specified stream output target */ for (unsigned i = 0; i < ARRAY_SIZE(svga->so_targets); i++) { - if (svga->vcount_so_targets[i] == info->indirect->count_from_stream_output) { + if (svga->vcount_so_targets[i] == indirect->count_from_stream_output) { stream = (svga->vcount_buffer_stream >> (i * 4)) & 0xf; break; } @@ -341,11 +344,11 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } } - if (info->indirect && info->indirect->count_from_stream_output && count == 0) { - ret = retry_draw_auto(svga, info); + if (indirect && indirect->count_from_stream_output && count == 0) { + ret = retry_draw_auto(svga, info, indirect); } - else if (info->indirect && info->indirect->buffer) { - ret = retry_draw_indirect(svga, info); + else if (indirect && indirect->buffer) { + ret = retry_draw_indirect(svga, info, indirect); } else if (info->index_size) { ret = retry_draw_range_elements(svga, info, count); diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h index fc094e514282deb200f9d2d474fd35a938e94f6d..6bffe95d4713a5b7429c403ea1e48988d74f7384 100644 --- a/src/gallium/drivers/svga/svga_swtnl.h +++ b/src/gallium/drivers/svga/svga_swtnl.h @@ -39,7 +39,8 @@ void svga_destroy_swtnl( struct svga_context *svga ); enum pipe_error svga_swtnl_draw_vbo(struct svga_context *svga, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); #endif diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index e3f6fdfd47d62a63c5d90e1d37be3ea42cdb92f9..46fb83502e71cbd0424171ded00618f98b84f831 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -38,7 +38,8 @@ enum pipe_error svga_swtnl_draw_vbo(struct svga_context *svga, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = { 0 }; struct pipe_transfer *ib_transfer = NULL; @@ -112,7 +113,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga, svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer->width0); } - draw_vbo(draw, info); + draw_vbo(draw, info, indirect); draw_flush(svga->swtnl.draw); diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp index 0bf29ef77a3cb18dad6f1394a662b334edf5f2c7..c8765900d328df1d08d833c7b31791313d2ec159 100644 --- a/src/gallium/drivers/swr/swr_draw.cpp +++ b/src/gallium/drivers/swr/swr_draw.cpp @@ -37,11 +37,12 @@ * Draw vertex arrays, with optional indexing, optional instancing. */ static void -swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct swr_context *ctx = swr_context(pipe); - if (!info->indirect && + if (!indirect && !info->primitive_restart && !u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) return; @@ -49,8 +50,8 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (!swr_check_render_cond(pipe)) return; - if (info->indirect && info->indirect->buffer) { - util_draw_indirect(pipe, info); + if (indirect && indirect->buffer) { + util_draw_indirect(pipe, info, indirect); return; } @@ -66,13 +67,13 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) struct pipe_draw_info resolved_info; /* DrawTransformFeedback */ - if (info->indirect && info->indirect->count_from_stream_output) { + if (indirect && indirect->count_from_stream_output) { // trick copied from softpipe to modify const struct *info memcpy(&resolved_info, (void*)info, sizeof(struct pipe_draw_info)); resolved_info.count = ctx->so_primCounter * resolved_info.vertices_per_patch; resolved_info.max_index = resolved_info.count - 1; - resolved_info.indirect = NULL; info = &resolved_info; + indirect = NULL; } if (ctx->vs->pipe.stream_output.num_outputs) { diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c index 1b15ba2fce10baca29ca1fa595f82b4b8f6f5f9d..59313a218f4257c70c77e07690b03e898c7809fe 100644 --- a/src/gallium/drivers/tegra/tegra_context.c +++ b/src/gallium/drivers/tegra/tegra_context.c @@ -46,28 +46,29 @@ tegra_destroy(struct pipe_context *pcontext) static void tegra_draw_vbo(struct pipe_context *pcontext, - const struct pipe_draw_info *pinfo) + const struct pipe_draw_info *pinfo, + const struct pipe_draw_indirect_info *pindirect) { struct tegra_context *context = to_tegra_context(pcontext); struct pipe_draw_indirect_info indirect; struct pipe_draw_info info; - if (pinfo && ((pinfo->indirect && pinfo->indirect->buffer) || pinfo->index_size)) { + if (pinfo && ((pindirect && pindirect->buffer) || pinfo->index_size)) { memcpy(&info, pinfo, sizeof(info)); - if (pinfo->indirect && pinfo->indirect->buffer) { - memcpy(&indirect, pinfo->indirect, sizeof(indirect)); - indirect.buffer = tegra_resource_unwrap(info.indirect->buffer); - info.indirect = &indirect; + if (pindirect && pindirect->buffer) { + memcpy(&indirect, pindirect, sizeof(indirect)); + indirect.buffer = tegra_resource_unwrap(pindirect->buffer); } if (pinfo->index_size && !pinfo->has_user_indices) info.index.resource = tegra_resource_unwrap(info.index.resource); pinfo = &info; + pindirect = &indirect; } - context->gpu->draw_vbo(context->gpu, pinfo); + context->gpu->draw_vbo(context->gpu, pinfo, pindirect); } static void diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index 1957f88d127fe13b09b0e29aadcd87235d11b9a0..54ef02a7bbd916b437cec55b47d67b2e65fe3a44 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -1084,11 +1084,12 @@ v3d_check_compiled_shaders(struct v3d_context *v3d) } static void -v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) +v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct v3d_context *v3d = v3d_context(pctx); - if (!info->indirect && + if (!indirect && !info->primitive_restart && !u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) return; @@ -1108,7 +1109,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) } if (info->restart_index != mask) { - util_draw_vbo_without_prim_restart(pctx, info); + util_draw_vbo_without_prim_restart(pctx, info, indirect); return; } } @@ -1127,8 +1128,8 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) for (int s = 0; s < PIPE_SHADER_COMPUTE; s++) v3d_predraw_check_stage_inputs(pctx, s); - if (info->indirect && info->indirect->buffer) { - v3d_flush_jobs_writing_resource(v3d, info->indirect->buffer, + if (indirect && indirect->buffer) { + v3d_flush_jobs_writing_resource(v3d, indirect->buffer, V3D_FLUSH_DEFAULT, false); } @@ -1155,7 +1156,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) * on the last submitted render, rather than tracking the last * rendering to each texture's BO. */ - if (v3d->tex[PIPE_SHADER_VERTEX].num_textures || (info->indirect && info->indirect->buffer)) { + if (v3d->tex[PIPE_SHADER_VERTEX].num_textures || (indirect && indirect->buffer)) { perf_debug("Blocking binner on last render " "due to vertex texturing or indirect drawing.\n"); job->submit.in_sync_bcl = v3d->out_sync; @@ -1284,7 +1285,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) } #endif - if (info->indirect && info->indirect->buffer) { + if (indirect && indirect->buffer) { cl_emit(&job->bcl, INDIRECT_INDEXED_INSTANCED_PRIM_LIST, prim) { prim.index_type = ffs(info->index_size) - 1; #if V3D_VERSION < 40 @@ -1294,11 +1295,11 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) prim.mode = hw_prim_type | prim_tf_enable; prim.enable_primitive_restarts = info->primitive_restart; - prim.number_of_draw_indirect_indexed_records = info->indirect->draw_count; + prim.number_of_draw_indirect_indexed_records = indirect->draw_count; - prim.stride_in_multiples_of_4_bytes = info->indirect->stride >> 2; - prim.address = cl_address(v3d_resource(info->indirect->buffer)->bo, - info->indirect->offset); + prim.stride_in_multiples_of_4_bytes = indirect->stride >> 2; + prim.address = cl_address(v3d_resource(indirect->buffer)->bo, + indirect->offset); } } else if (info->instance_count > 1) { cl_emit(&job->bcl, INDEXED_INSTANCED_PRIM_LIST, prim) { @@ -1335,19 +1336,19 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) if (info->has_user_indices) pipe_resource_reference(&prsc, NULL); } else { - if (info->indirect && info->indirect->buffer) { + if (indirect && indirect->buffer) { cl_emit(&job->bcl, INDIRECT_VERTEX_ARRAY_INSTANCED_PRIMS, prim) { prim.mode = hw_prim_type | prim_tf_enable; - prim.number_of_draw_indirect_array_records = info->indirect->draw_count; + prim.number_of_draw_indirect_array_records = indirect->draw_count; - prim.stride_in_multiples_of_4_bytes = info->indirect->stride >> 2; - prim.address = cl_address(v3d_resource(info->indirect->buffer)->bo, - info->indirect->offset); + prim.stride_in_multiples_of_4_bytes = indirect->stride >> 2; + prim.address = cl_address(v3d_resource(indirect->buffer)->bo, + indirect->offset); } } else if (info->instance_count > 1) { struct pipe_stream_output_target *so = - info->indirect && info->indirect->count_from_stream_output ? - info->indirect->count_from_stream_output : NULL; + indirect && indirect->count_from_stream_output ? + indirect->count_from_stream_output : NULL; uint32_t vert_count = so ? v3d_stream_output_target_get_vertex_count(so) : info->count; @@ -1359,8 +1360,8 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) } } else { struct pipe_stream_output_target *so = - info->indirect && info->indirect->count_from_stream_output ? - info->indirect->count_from_stream_output : NULL; + indirect && indirect->count_from_stream_output ? + indirect->count_from_stream_output : NULL; uint32_t vert_count = so ? v3d_stream_output_target_get_vertex_count(so) : info->count; diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c index bd54df0cdda541643017d130392c818602e13c03..6a1c0e36694959653b7bc96229a844f15cf3662b 100644 --- a/src/gallium/drivers/vc4/vc4_draw.c +++ b/src/gallium/drivers/vc4/vc4_draw.c @@ -286,12 +286,13 @@ vc4_hw_2116_workaround(struct pipe_context *pctx, int vert_count) } static void -vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) +vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { struct vc4_context *vc4 = vc4_context(pctx); struct pipe_draw_info local_info; - if (!info->indirect && + if (!indirect && !info->primitive_restart && !u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) return; diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 8aaceda2fb4e62bb5940ce6706c97131db188631..5769e301040db4b79100141ccaba4d62b118b7f6 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -848,14 +848,15 @@ static void virgl_clear_texture(struct pipe_context *ctx, } static void virgl_draw_vbo(struct pipe_context *ctx, - const struct pipe_draw_info *dinfo) + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *indirect) { struct virgl_context *vctx = virgl_context(ctx); struct virgl_screen *rs = virgl_screen(ctx->screen); struct virgl_indexbuf ib = {}; struct pipe_draw_info info = *dinfo; - if (!dinfo->indirect && + if (!indirect && !dinfo->primitive_restart && !u_trim_pipe_prim(dinfo->mode, (unsigned*)&dinfo->count)) return; @@ -886,7 +887,7 @@ static void virgl_draw_vbo(struct pipe_context *ctx, if (info.index_size) virgl_hw_set_index_buffer(vctx, &ib); - virgl_encoder_draw_vbo(vctx, &info); + virgl_encoder_draw_vbo(vctx, &info, indirect); pipe_resource_reference(&ib.buffer, NULL); diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c index dc51178f802b94221b347e2f71e3268ea51321cc..494eedafa5197e4981b981b3fb4d0e35b8f36676 100644 --- a/src/gallium/drivers/virgl/virgl_encode.c +++ b/src/gallium/drivers/virgl/virgl_encode.c @@ -707,12 +707,13 @@ int virgl_encoder_set_index_buffer(struct virgl_context *ctx, } int virgl_encoder_draw_vbo(struct virgl_context *ctx, - const struct pipe_draw_info *info) + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) { uint32_t length = VIRGL_DRAW_VBO_SIZE; if (info->mode == PIPE_PRIM_PATCHES) length = VIRGL_DRAW_VBO_SIZE_TESS; - if (info->indirect && info->indirect->buffer) + if (indirect && indirect->buffer) length = VIRGL_DRAW_VBO_SIZE_INDIRECT; virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DRAW_VBO, 0, length)); virgl_encoder_write_dword(ctx->cbuf, info->start); @@ -726,8 +727,8 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx, virgl_encoder_write_dword(ctx->cbuf, info->restart_index); virgl_encoder_write_dword(ctx->cbuf, info->min_index); virgl_encoder_write_dword(ctx->cbuf, info->max_index); - if (info->indirect && info->indirect->count_from_stream_output) - virgl_encoder_write_dword(ctx->cbuf, info->indirect->count_from_stream_output->buffer_size); + if (indirect && indirect->count_from_stream_output) + virgl_encoder_write_dword(ctx->cbuf, indirect->count_from_stream_output->buffer_size); else virgl_encoder_write_dword(ctx->cbuf, 0); if (length >= VIRGL_DRAW_VBO_SIZE_TESS) { @@ -735,13 +736,13 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx, virgl_encoder_write_dword(ctx->cbuf, info->drawid); /* drawid */ } if (length == VIRGL_DRAW_VBO_SIZE_INDIRECT) { - virgl_encoder_write_res(ctx, virgl_resource(info->indirect->buffer)); - virgl_encoder_write_dword(ctx->cbuf, info->indirect->offset); - virgl_encoder_write_dword(ctx->cbuf, info->indirect->stride); /* indirect stride */ - virgl_encoder_write_dword(ctx->cbuf, info->indirect->draw_count); /* indirect draw count */ - virgl_encoder_write_dword(ctx->cbuf, info->indirect->indirect_draw_count_offset); /* indirect draw count offset */ - if (info->indirect->indirect_draw_count) - virgl_encoder_write_res(ctx, virgl_resource(info->indirect->indirect_draw_count)); + virgl_encoder_write_res(ctx, virgl_resource(indirect->buffer)); + virgl_encoder_write_dword(ctx->cbuf, indirect->offset); + virgl_encoder_write_dword(ctx->cbuf, indirect->stride); /* indirect stride */ + virgl_encoder_write_dword(ctx->cbuf, indirect->draw_count); /* indirect draw count */ + virgl_encoder_write_dword(ctx->cbuf, indirect->indirect_draw_count_offset); /* indirect draw count offset */ + if (indirect->indirect_draw_count) + virgl_encoder_write_res(ctx, virgl_resource(indirect->indirect_draw_count)); else virgl_encoder_write_dword(ctx->cbuf, 0); /* indirect draw count handle */ } diff --git a/src/gallium/drivers/virgl/virgl_encode.h b/src/gallium/drivers/virgl/virgl_encode.h index 2b87fb943b0afb6fb720ff75fed32073167bae01..b80d0bcef7df6909e8ca770ccefddcfa2c70e11c 100644 --- a/src/gallium/drivers/virgl/virgl_encode.h +++ b/src/gallium/drivers/virgl/virgl_encode.h @@ -135,7 +135,8 @@ int virgl_encoder_set_viewport_states(struct virgl_context *ctx, const struct pipe_viewport_state *states); int virgl_encoder_draw_vbo(struct virgl_context *ctx, - const struct pipe_draw_info *info); + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); int virgl_encoder_create_surface(struct virgl_context *ctx, diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index d0d0b79b986bc95db5bed4c0b24518b1bb660ea6..2d8502daa1ccab239b701386f9390bbae9e2b824 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -187,6 +187,7 @@ zink_blit(struct pipe_context *pctx, void zink_draw_vbo(struct pipe_context *pctx, - const struct pipe_draw_info *dinfo); + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *indirect); #endif diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index ae57550fed0af06c8103327d34d3dda10d3f4aa0..0dbe7c73ebe7b4552e8a8c1faae6711568a5d887 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -208,22 +208,23 @@ restart_supported(enum pipe_prim_type mode) void zink_draw_vbo(struct pipe_context *pctx, - const struct pipe_draw_info *dinfo) + const struct pipe_draw_info *dinfo, + const struct pipe_draw_indirect_info *dindirect) { struct zink_context *ctx = zink_context(pctx); struct zink_screen *screen = zink_screen(pctx->screen); struct zink_rasterizer_state *rast_state = ctx->rast_state; struct zink_depth_stencil_alpha_state *dsa_state = ctx->dsa_state; struct zink_so_target *so_target = - dinfo->indirect && dinfo->indirect->count_from_stream_output ? - zink_so_target(dinfo->indirect->count_from_stream_output) : NULL; + dindirect && dindirect->count_from_stream_output ? + zink_so_target(dindirect->count_from_stream_output) : NULL; VkBuffer counter_buffers[PIPE_MAX_SO_OUTPUTS]; VkDeviceSize counter_buffer_offsets[PIPE_MAX_SO_OUTPUTS] = {}; bool need_index_buffer_unref = false; if (dinfo->primitive_restart && !restart_supported(dinfo->mode)) { - util_draw_vbo_without_prim_restart(pctx, dinfo); + util_draw_vbo_without_prim_restart(pctx, dinfo, dindirect); return; } if (dinfo->mode == PIPE_PRIM_QUADS || @@ -277,7 +278,7 @@ zink_draw_vbo(struct pipe_context *pctx, uint32_t restart_index = util_prim_restart_index_from_size(dinfo->index_size); if ((dinfo->primitive_restart && (dinfo->restart_index != restart_index)) || (!screen->info.have_EXT_index_type_uint8 && dinfo->index_size == 8)) { - util_translate_prim_restart_ib(pctx, dinfo, &index_buffer); + util_translate_prim_restart_ib(pctx, dinfo, dindirect, &index_buffer); need_index_buffer_unref = true; } else { if (dinfo->has_user_indices) { @@ -516,10 +517,10 @@ zink_draw_vbo(struct pipe_context *pctx, struct zink_resource *res = zink_resource(index_buffer); vkCmdBindIndexBuffer(batch->cmdbuf, res->buffer, index_offset, index_type); zink_batch_reference_resource_rw(batch, res, false); - if (dinfo->indirect && dinfo->indirect->buffer) { - struct zink_resource *indirect = zink_resource(dinfo->indirect->buffer); + if (dindirect && dindirect->buffer) { + struct zink_resource *indirect = zink_resource(dindirect->buffer); zink_batch_reference_resource_rw(batch, indirect, false); - vkCmdDrawIndexedIndirect(batch->cmdbuf, indirect->buffer, dinfo->indirect->offset, dinfo->indirect->draw_count, dinfo->indirect->stride); + vkCmdDrawIndexedIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride); } else vkCmdDrawIndexed(batch->cmdbuf, dinfo->count, dinfo->instance_count, @@ -530,10 +531,10 @@ zink_draw_vbo(struct pipe_context *pctx, screen->vk_CmdDrawIndirectByteCountEXT(batch->cmdbuf, dinfo->instance_count, dinfo->start_instance, zink_resource(so_target->counter_buffer)->buffer, so_target->counter_buffer_offset, 0, MIN2(so_target->stride, screen->info.tf_props.maxTransformFeedbackBufferDataStride)); - } else if (dinfo->indirect && dinfo->indirect->buffer) { - struct zink_resource *indirect = zink_resource(dinfo->indirect->buffer); + } else if (dindirect && dindirect->buffer) { + struct zink_resource *indirect = zink_resource(dindirect->buffer); zink_batch_reference_resource_rw(batch, indirect, false); - vkCmdDrawIndirect(batch->cmdbuf, indirect->buffer, dinfo->indirect->offset, dinfo->indirect->draw_count, dinfo->indirect->stride); + vkCmdDrawIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride); } else vkCmdDraw(batch->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance); } diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 15c105faa86bbbc1270f45e2e9d6f281d13553cc..6ee7b0be016bbdce5a72a4b403154197e40ca199 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -1301,13 +1301,12 @@ static void handle_draw(struct lvp_cmd_buffer_entry *cmd, struct rendering_state *state) { state->info.index_size = 0; - state->info.indirect = NULL; state->info.index.resource = NULL; state->info.start = cmd->u.draw.first_vertex; state->info.count = cmd->u.draw.vertex_count; state->info.start_instance = cmd->u.draw.first_instance; state->info.instance_count = cmd->u.draw.instance_count; - state->pctx->draw_vbo(state->pctx, &state->info); + state->pctx->draw_vbo(state->pctx, &state->info, NULL); } static void handle_set_viewport(struct lvp_cmd_buffer_entry *cmd, @@ -1841,7 +1840,6 @@ static void handle_update_buffer(struct lvp_cmd_buffer_entry *cmd, static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd, struct rendering_state *state) { - state->info.indirect = NULL; state->info.min_index = 0; state->info.max_index = ~0; state->info.index_size = state->index_size; @@ -1859,7 +1857,7 @@ static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd, state->info.restart_index = 0xffff; } - state->pctx->draw_vbo(state->pctx, &state->info); + state->pctx->draw_vbo(state->pctx, &state->info, NULL); } static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd, @@ -1875,8 +1873,7 @@ static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd, state->indirect_info.stride = cmd->u.draw_indirect.stride; state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count; state->indirect_info.buffer = cmd->u.draw_indirect.buffer->bo; - state->info.indirect = &state->indirect_info; - state->pctx->draw_vbo(state->pctx, &state->info); + state->pctx->draw_vbo(state->pctx, &state->info, &state->indirect_info); } static void handle_index_buffer(struct lvp_cmd_buffer_entry *cmd, diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c index a7587cc95170773195349ea50d43bee9ecd746e7..3f8643ef793b7754a219b07242161e6d26b13de1 100644 --- a/src/gallium/frontends/nine/device9.c +++ b/src/gallium/frontends/nine/device9.c @@ -3174,7 +3174,6 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This, draw.start_instance = 0; draw.primitive_restart = FALSE; draw.restart_index = 0; - draw.indirect = NULL; draw.instance_count = 1; draw.index_size = 0; draw.start = 0; @@ -3185,7 +3184,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This, pipe_sw->set_stream_output_targets(pipe_sw, 1, &target, offsets); - pipe_sw->draw_vbo(pipe_sw, &draw); + pipe_sw->draw_vbo(pipe_sw, &draw, NULL); pipe_sw->set_stream_output_targets(pipe_sw, 0, NULL, 0); pipe_sw->stream_output_target_destroy(pipe_sw, target); diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index e4d72c62ae8774230d2d70e1aa8bec29000d0c94..c93bca047a6697daa6b0d763807ad90b748fc1f0 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -2318,7 +2318,6 @@ init_draw_info(struct pipe_draw_info *info, info->primitive_restart = FALSE; info->has_user_indices = FALSE; info->restart_index = 0; - info->indirect = NULL; } CSMT_ITEM_NO_WAIT(nine_context_draw_primitive, @@ -2339,7 +2338,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive, info.max_index = info.count - 1; info.index.resource = NULL; - context->pipe->draw_vbo(context->pipe, &info); + context->pipe->draw_vbo(context->pipe, &info, NULL); } CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive, @@ -2364,7 +2363,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive, info.max_index = MinVertexIndex + NumVertices - 1; info.index.resource = context->idxbuf; - context->pipe->draw_vbo(context->pipe, &info); + context->pipe->draw_vbo(context->pipe, &info, NULL); } CSMT_ITEM_NO_WAIT(nine_context_draw_primitive_from_vtxbuf, @@ -2387,7 +2386,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive_from_vtxbuf, context->pipe->set_vertex_buffers(context->pipe, 0, 1, vtxbuf); - context->pipe->draw_vbo(context->pipe, &info); + context->pipe->draw_vbo(context->pipe, &info, NULL); } CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf, @@ -2420,7 +2419,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf, context->pipe->set_vertex_buffers(context->pipe, 0, 1, vbuf); - context->pipe->draw_vbo(context->pipe, &info); + context->pipe->draw_vbo(context->pipe, &info, NULL); } CSMT_ITEM_NO_WAIT(nine_context_resource_copy_region, diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index b961c7780b5ea1ab0f0f3d620704f0e2fe6cb316..05aca7ef033f3ec230d203fe5790d9f3a3e42cee 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -49,6 +49,7 @@ struct pipe_debug_callback; struct pipe_depth_stencil_alpha_state; struct pipe_device_reset_callback; struct pipe_draw_info; +struct pipe_draw_indirect_info; struct pipe_draw_start_count; struct pipe_grid_info; struct pipe_fence_handle; @@ -107,8 +108,9 @@ struct pipe_context { * VBO drawing */ /*@{*/ - void (*draw_vbo)( struct pipe_context *pipe, - const struct pipe_draw_info *info ); + void (*draw_vbo)(struct pipe_context *pipe, + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect); /** * Direct multi draw specifying "start" and "count" for each draw. @@ -142,6 +144,7 @@ struct pipe_context { */ void (*multi_draw)(struct pipe_context *pipe, const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count *draws, unsigned num_draws); /*@}*/ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index ad5701ba9c54c76d68ce8235ee3defe90dcb76cd..4ab4cb12e1aa9734befc297c34048f9068cc5fa5 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -793,8 +793,6 @@ struct pipe_draw_info struct pipe_resource *resource; /**< real buffer */ const void *user; /**< pointer to a user buffer */ } index; - - struct pipe_draw_indirect_info *indirect; /**< Indirect draw. */ }; diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index 8294147e040814c3817a0c2b2958d695d2b43b6e..dae7b45a9d60c058fdf6bfee909946967c2fe40a 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -209,7 +209,7 @@ static void draw( void ) indices); } - ctx->draw_vbo(ctx, &info); + ctx->draw_vbo(ctx, &info, NULL); pipe_resource_reference(&info.index.resource, NULL); diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index ef8d5b0b1493693730cc9d416bcd921f35c6abfa..4d90042bdeaca4e6c20745bc969b4629d98a8f8c 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -176,7 +176,6 @@ st_draw_vbo(struct gl_context *ctx, /* Initialize pipe_draw_info. */ info.primitive_restart = false; info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; - info.indirect = NULL; info.restart_index = 0; info.start_instance = base_instance; info.instance_count = num_instances; @@ -246,7 +245,7 @@ st_draw_vbo(struct gl_context *ctx, } /* Don't call u_trim_pipe_prim. Drivers should do it if they need it. */ - cso_draw_vbo(st->cso_context, &info); + cso_draw_vbo(st->cso_context, &info, NULL); } } @@ -289,7 +288,6 @@ st_indirect_draw_vbo(struct gl_context *ctx, info.mode = translate_prim(ctx, mode); info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; - info.indirect = &indirect; indirect.buffer = st_buffer_object(indirect_data)->buffer; indirect.offset = indirect_offset; @@ -307,7 +305,7 @@ st_indirect_draw_vbo(struct gl_context *ctx, indirect.draw_count = 1; for (i = 0; i < draw_count; i++) { info.drawid = i; - cso_draw_vbo(st->cso_context, &info); + cso_draw_vbo(st->cso_context, &info, &indirect); indirect.offset += stride; } } else { @@ -318,7 +316,7 @@ st_indirect_draw_vbo(struct gl_context *ctx, st_buffer_object(indirect_draw_count)->buffer; indirect.indirect_draw_count_offset = indirect_draw_count_offset; } - cso_draw_vbo(st->cso_context, &info); + cso_draw_vbo(st->cso_context, &info, &indirect); } } @@ -340,7 +338,6 @@ st_draw_transform_feedback(struct gl_context *ctx, GLenum mode, info.mode = translate_prim(ctx, mode); info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.instance_count = num_instances; - info.indirect = &indirect; if (ST_DEBUG & DEBUG_DRAW) { debug_printf("st/draw transform feedback: mode %s\n", @@ -352,7 +349,7 @@ st_draw_transform_feedback(struct gl_context *ctx, GLenum mode, if (!st_transform_feedback_draw_init(tfb_vertcount, stream, &indirect)) return; - cso_draw_vbo(st->cso_context, &info); + cso_draw_vbo(st->cso_context, &info, &indirect); } void diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 9129162554c8062181cd5aa2bde1ee7ef64ebeec..62804151f636b9037d5e9b7fceeebec2f6ab1b35 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -123,7 +123,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, /* Initialize pipe_draw_info. */ info.primitive_restart = false; info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; - info.indirect = NULL; info.restart_index = 0; st_flush_bitmap_cache(st); @@ -437,7 +436,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, info.max_index = info.start + info.count - 1; } - draw_vbo(draw, &info); + draw_vbo(draw, &info, NULL); } /* unmap images */