Commit 1a717dca authored by Marek Olšák's avatar Marek Olšák Committed by Marge Bot

gallium: move count_from_stream_output into pipe_draw_indirect_info

This removes some overhead from tc_draw_vbo and increases the maximum number
of draws per batch from 153 to 192 in u_threaded_context.
Reviewed-by: Pierre-Eric Pelloux-Prayer's avatarPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <!7441>
parent 238ee7b8
...@@ -1727,10 +1727,14 @@ cso_draw_vbo(struct cso_context *cso, ...@@ -1727,10 +1727,14 @@ cso_draw_vbo(struct cso_context *cso,
struct u_vbuf *vbuf = cso->vbuf_current; struct u_vbuf *vbuf = cso->vbuf_current;
/* We can't have both indirect drawing and SO-vertex-count drawing */ /* We can't have both indirect drawing and SO-vertex-count drawing */
assert(info->indirect == NULL || info->count_from_stream_output == NULL); assert(!info->indirect ||
info->indirect->buffer == NULL ||
info->indirect->count_from_stream_output == NULL);
/* We can't have SO-vertex-count drawing with an index buffer */ /* We can't have SO-vertex-count drawing with an index buffer */
assert(info->count_from_stream_output == NULL || info->index_size == 0); assert(info->index_size == 0 ||
!info->indirect ||
info->indirect->count_from_stream_output == NULL);
if (vbuf) { if (vbuf) {
u_vbuf_draw_vbo(vbuf, info); u_vbuf_draw_vbo(vbuf, info);
......
...@@ -445,9 +445,9 @@ resolve_draw_info(const struct pipe_draw_info *raw_info, ...@@ -445,9 +445,9 @@ resolve_draw_info(const struct pipe_draw_info *raw_info,
{ {
memcpy(info, raw_info, sizeof(struct pipe_draw_info)); memcpy(info, raw_info, sizeof(struct pipe_draw_info));
if (raw_info->count_from_stream_output) { if (raw_info->indirect && raw_info->indirect->count_from_stream_output) {
struct draw_so_target *target = struct draw_so_target *target =
(struct draw_so_target *)info->count_from_stream_output; (struct draw_so_target *)info->indirect->count_from_stream_output;
assert(vertex_buffer != NULL); assert(vertex_buffer != NULL);
info->count = vertex_buffer->stride == 0 ? 0 : info->count = vertex_buffer->stride == 0 ? 0 :
target->internal_offset / vertex_buffer->stride; target->internal_offset / vertex_buffer->stride;
...@@ -455,6 +455,7 @@ resolve_draw_info(const struct pipe_draw_info *raw_info, ...@@ -455,6 +455,7 @@ resolve_draw_info(const struct pipe_draw_info *raw_info,
/* Stream output draw can not be indexed */ /* Stream output draw can not be indexed */
debug_assert(!info->index_size); debug_assert(!info->index_size);
info->max_index = info->count - 1; info->max_index = info->count - 1;
info->indirect = NULL;
} }
} }
......
...@@ -356,13 +356,14 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE ...@@ -356,13 +356,14 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE
int sh, i; int sh, i;
DUMP(draw_info, info); DUMP(draw_info, info);
if (info->count_from_stream_output)
DUMP_M(stream_output_target, info,
count_from_stream_output);
if (info->indirect) { if (info->indirect) {
DUMP_M(resource, info, indirect->buffer); if (info->indirect->buffer)
DUMP_M(resource, info, indirect->buffer);
if (info->indirect->indirect_draw_count) if (info->indirect->indirect_draw_count)
DUMP_M(resource, 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);
} }
fprintf(f, "\n"); fprintf(f, "\n");
...@@ -705,7 +706,7 @@ dd_unreference_copy_of_call(struct dd_call *dst) ...@@ -705,7 +706,7 @@ dd_unreference_copy_of_call(struct dd_call *dst)
case CALL_FLUSH: case CALL_FLUSH:
break; break;
case CALL_DRAW_VBO: case CALL_DRAW_VBO:
pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL); pipe_so_target_reference(&dst->info.draw_vbo.indirect.count_from_stream_output, NULL);
pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL); pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL);
pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL); pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL);
if (dst->info.draw_vbo.draw.index_size && if (dst->info.draw_vbo.draw.index_size &&
...@@ -1305,9 +1306,6 @@ dd_context_draw_vbo(struct pipe_context *_pipe, ...@@ -1305,9 +1306,6 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
record->call.type = CALL_DRAW_VBO; record->call.type = CALL_DRAW_VBO;
record->call.info.draw_vbo.draw = *info; record->call.info.draw_vbo.draw = *info;
record->call.info.draw_vbo.draw.count_from_stream_output = NULL;
pipe_so_target_reference(&record->call.info.draw_vbo.draw.count_from_stream_output,
info->count_from_stream_output);
if (info->index_size && !info->has_user_indices) { if (info->index_size && !info->has_user_indices) {
record->call.info.draw_vbo.draw.index.resource = NULL; record->call.info.draw_vbo.draw.index.resource = NULL;
pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource, pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource,
...@@ -1324,6 +1322,9 @@ dd_context_draw_vbo(struct pipe_context *_pipe, ...@@ -1324,6 +1322,9 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
record->call.info.draw_vbo.indirect.indirect_draw_count = NULL; record->call.info.draw_vbo.indirect.indirect_draw_count = NULL;
pipe_resource_reference(&record->call.info.draw_vbo.indirect.indirect_draw_count, pipe_resource_reference(&record->call.info.draw_vbo.indirect.indirect_draw_count,
info->indirect->indirect_draw_count); info->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);
} else { } else {
memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*info->indirect)); memset(&record->call.info.draw_vbo.indirect, 0, sizeof(*info->indirect));
} }
......
...@@ -793,7 +793,6 @@ void trace_dump_draw_info(const struct pipe_draw_info *state) ...@@ -793,7 +793,6 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
trace_dump_member(uint, state, restart_index); trace_dump_member(uint, state, restart_index);
trace_dump_member(ptr, state, index.resource); trace_dump_member(ptr, state, index.resource);
trace_dump_member(ptr, state, count_from_stream_output);
if (!state->indirect) { if (!state->indirect) {
trace_dump_member(ptr, state, indirect); trace_dump_member(ptr, state, indirect);
...@@ -804,6 +803,7 @@ void trace_dump_draw_info(const struct pipe_draw_info *state) ...@@ -804,6 +803,7 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
trace_dump_member(uint, state, indirect->indirect_draw_count_offset); trace_dump_member(uint, state, indirect->indirect_draw_count_offset);
trace_dump_member(ptr, state, indirect->buffer); trace_dump_member(ptr, state, indirect->buffer);
trace_dump_member(ptr, state, indirect->indirect_draw_count); trace_dump_member(ptr, state, indirect->indirect_draw_count);
trace_dump_member(ptr, state, indirect->count_from_stream_output);
} }
trace_dump_struct_end(); trace_dump_struct_end();
......
...@@ -139,7 +139,7 @@ util_draw_indirect(struct pipe_context *pipe, ...@@ -139,7 +139,7 @@ util_draw_indirect(struct pipe_context *pipe,
unsigned num_params = info_in->index_size ? 5 : 4; unsigned num_params = info_in->index_size ? 5 : 4;
assert(info_in->indirect); assert(info_in->indirect);
assert(!info_in->count_from_stream_output); assert(!info_in->indirect->count_from_stream_output);
memcpy(&info, info_in, sizeof(info)); memcpy(&info, info_in, sizeof(info));
......
...@@ -941,7 +941,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) ...@@ -941,7 +941,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
else else
util_dump_member(stream, ptr, state, index.resource); util_dump_member(stream, ptr, state, index.resource);
} }
util_dump_member(stream, ptr, state, count_from_stream_output);
if (!state->indirect) { if (!state->indirect) {
util_dump_member(stream, ptr, state, indirect); util_dump_member(stream, ptr, state, indirect);
...@@ -952,6 +951,7 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) ...@@ -952,6 +951,7 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
util_dump_member(stream, uint, state, indirect->indirect_draw_count_offset); 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->buffer);
util_dump_member(stream, ptr, state, indirect->indirect_draw_count); util_dump_member(stream, ptr, state, indirect->indirect_draw_count);
util_dump_member(stream, ptr, state, indirect->count_from_stream_output);
} }
util_dump_struct_end(stream); util_dump_struct_end(stream);
......
...@@ -114,7 +114,7 @@ util_translate_prim_restart_ib(struct pipe_context *context, ...@@ -114,7 +114,7 @@ util_translate_prim_restart_ib(struct pipe_context *context,
dst_index_size = MAX2(2, info->index_size); dst_index_size = MAX2(2, info->index_size);
assert(dst_index_size == 2 || dst_index_size == 4); assert(dst_index_size == 2 || dst_index_size == 4);
if (info->indirect) { if (info->indirect && info->indirect->buffer) {
indirect = read_indirect_elements(context, info->indirect); indirect = read_indirect_elements(context, info->indirect);
count = indirect.count; count = indirect.count;
start = indirect.firstIndex; start = indirect.firstIndex;
...@@ -235,7 +235,7 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context, ...@@ -235,7 +235,7 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context,
assert(info->index_size); assert(info->index_size);
assert(info->primitive_restart); assert(info->primitive_restart);
if (info->indirect) { if (info->indirect && info->indirect->buffer) {
indirect = read_indirect_elements(context, info->indirect); indirect = read_indirect_elements(context, info->indirect);
info_count = indirect.count; info_count = indirect.count;
info_start = indirect.firstIndex; info_start = indirect.firstIndex;
......
...@@ -126,7 +126,6 @@ tc_batch_execute(void *job, UNUSED int thread_index) ...@@ -126,7 +126,6 @@ tc_batch_execute(void *job, UNUSED int thread_index)
if (next != last && next->call_id == TC_CALL_draw_vbo && if (next != last && next->call_id == TC_CALL_draw_vbo &&
first_info->draw.drawid == 0 && first_info->draw.drawid == 0 &&
!first_info->draw.indirect && !first_info->draw.indirect &&
!first_info->draw.count_from_stream_output &&
is_next_call_a_mergeable_draw(first_info, next, &next_info)) { is_next_call_a_mergeable_draw(first_info, next, &next_info)) {
/* Merge up to 256 draw calls. */ /* Merge up to 256 draw calls. */
struct pipe_draw_start_count multi[256]; struct pipe_draw_start_count multi[256];
...@@ -2199,12 +2198,12 @@ tc_call_draw_vbo(struct pipe_context *pipe, union tc_payload *payload) ...@@ -2199,12 +2198,12 @@ tc_call_draw_vbo(struct pipe_context *pipe, union tc_payload *payload)
struct tc_full_draw_info *info = (struct tc_full_draw_info*)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);
pipe_so_target_reference(&info->draw.count_from_stream_output, NULL);
if (info->draw.index_size) if (info->draw.index_size)
pipe_resource_reference(&info->draw.index.resource, NULL); pipe_resource_reference(&info->draw.index.resource, NULL);
if (info->draw.indirect) { if (info->draw.indirect) {
pipe_resource_reference(&info->indirect.buffer, NULL); pipe_resource_reference(&info->indirect.buffer, NULL);
pipe_resource_reference(&info->indirect.indirect_draw_count, NULL); pipe_resource_reference(&info->indirect.indirect_draw_count, NULL);
pipe_so_target_reference(&info->indirect.count_from_stream_output, NULL);
} }
} }
...@@ -2243,9 +2242,6 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) ...@@ -2243,9 +2242,6 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
return; return;
struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, false); struct tc_full_draw_info *p = tc_add_draw_vbo(_pipe, false);
p->draw.count_from_stream_output = NULL;
pipe_so_target_reference(&p->draw.count_from_stream_output,
info->count_from_stream_output);
memcpy(&p->draw, info, sizeof(*info)); memcpy(&p->draw, info, sizeof(*info));
p->draw.has_user_indices = false; p->draw.has_user_indices = false;
p->draw.index.resource = buffer; p->draw.index.resource = buffer;
...@@ -2253,9 +2249,6 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) ...@@ -2253,9 +2249,6 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
} else { } else {
/* Non-indexed call or indexed with a real index buffer. */ /* 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, indirect != NULL);
p->draw.count_from_stream_output = NULL;
pipe_so_target_reference(&p->draw.count_from_stream_output,
info->count_from_stream_output);
if (index_size) { if (index_size) {
tc_set_resource_reference(&p->draw.index.resource, tc_set_resource_reference(&p->draw.index.resource,
info->index.resource); info->index.resource);
...@@ -2266,6 +2259,9 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) ...@@ -2266,6 +2259,9 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
tc_set_resource_reference(&p->draw.indirect->buffer, indirect->buffer); tc_set_resource_reference(&p->draw.indirect->buffer, indirect->buffer);
tc_set_resource_reference(&p->indirect.indirect_draw_count, tc_set_resource_reference(&p->indirect.indirect_draw_count,
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)); memcpy(&p->indirect, indirect, sizeof(*indirect));
p->draw.indirect = &p->indirect; p->draw.indirect = &p->indirect;
} }
......
...@@ -1306,7 +1306,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) ...@@ -1306,7 +1306,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
new_info = *info; new_info = *info;
/* Handle indirect (multi)draws. */ /* Handle indirect (multi)draws. */
if (new_info.indirect) { if (new_info.indirect && new_info.indirect->buffer) {
const struct pipe_draw_indirect_info *indirect = new_info.indirect; const struct pipe_draw_indirect_info *indirect = new_info.indirect;
unsigned draw_count = 0; unsigned draw_count = 0;
......
...@@ -231,7 +231,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) ...@@ -231,7 +231,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
uint32_t draw_mode; uint32_t draw_mode;
unsigned i; unsigned i;
if (!info->count_from_stream_output && !info->indirect && if (!info->indirect &&
!info->primitive_restart && !info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
return; return;
......
...@@ -97,7 +97,7 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, ...@@ -97,7 +97,7 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
enum pc_di_src_sel src_sel; enum pc_di_src_sel src_sel;
uint32_t idx_size, idx_offset; uint32_t idx_size, idx_offset;
if (info->indirect) { if (info->indirect && info->indirect->buffer) {
struct fd_resource *ind = fd_resource(info->indirect->buffer); struct fd_resource *ind = fd_resource(info->indirect->buffer);
emit_marker(ring, 7); emit_marker(ring, 7);
......
...@@ -91,7 +91,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, ...@@ -91,7 +91,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
enum pc_di_src_sel src_sel; enum pc_di_src_sel src_sel;
uint32_t max_indices, idx_offset; uint32_t max_indices, idx_offset;
if (info->indirect) { if (info->indirect && info->indirect->buffer) {
struct fd_resource *ind = fd_resource(info->indirect->buffer); struct fd_resource *ind = fd_resource(info->indirect->buffer);
emit_marker5(ring, 7); emit_marker5(ring, 7);
......
...@@ -195,7 +195,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, ...@@ -195,7 +195,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
if (emit.key.gs) if (emit.key.gs)
emit.key.key.has_gs = true; emit.key.key.has_gs = true;
if (!(emit.key.hs || emit.key.ds || emit.key.gs || info->indirect)) if (!(emit.key.hs || emit.key.ds || emit.key.gs || (info->indirect && info->indirect->buffer)))
fd6_vsc_update_sizes(ctx->batch, info); fd6_vsc_update_sizes(ctx->batch, info);
fixup_shader_state(ctx, &emit.key.key); fixup_shader_state(ctx, &emit.key.key);
...@@ -315,7 +315,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, ...@@ -315,7 +315,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
*/ */
emit_marker6(ring, 7); emit_marker6(ring, 7);
if (info->indirect) { if (info->indirect && info->indirect->buffer) {
draw_emit_indirect(ring, &draw0, info, index_offset); draw_emit_indirect(ring, &draw0, info, index_offset);
} else { } else {
draw_emit(ring, &draw0, info, index_offset); draw_emit(ring, &draw0, info, index_offset);
......
...@@ -175,7 +175,7 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info) ...@@ -175,7 +175,7 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info)
resource_read(batch, info->index.resource); resource_read(batch, info->index.resource);
/* Mark indirect draw buffer as being read */ /* Mark indirect draw buffer as being read */
if (info->indirect) if (info->indirect && info->indirect->buffer)
resource_read(batch, info->indirect->buffer); resource_read(batch, info->indirect->buffer);
/* Mark textures as being read */ /* Mark textures as being read */
...@@ -218,13 +218,13 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) ...@@ -218,13 +218,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 * to be able to emulate it, to determine if game is feeding us
* bogus data: * bogus data:
*/ */
if (info->indirect && (fd_mesa_debug & FD_DBG_NOINDR)) { if (info->indirect && info->indirect->buffer && (fd_mesa_debug & FD_DBG_NOINDR)) {
util_draw_indirect(pctx, info); util_draw_indirect(pctx, info);
return; return;
} }
if (info->mode != PIPE_PRIM_MAX && if (info->mode != PIPE_PRIM_MAX &&
!info->count_from_stream_output && !info->indirect && !info->indirect &&
!info->primitive_restart && !info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
return; return;
......
...@@ -118,7 +118,7 @@ iris_update_draw_parameters(struct iris_context *ice, ...@@ -118,7 +118,7 @@ iris_update_draw_parameters(struct iris_context *ice,
if (ice->state.vs_uses_draw_params) { if (ice->state.vs_uses_draw_params) {
struct iris_state_ref *draw_params = &ice->draw.draw_params; struct iris_state_ref *draw_params = &ice->draw.draw_params;
if (info->indirect) { if (info->indirect && info->indirect->buffer) {
pipe_resource_reference(&draw_params->res, info->indirect->buffer); pipe_resource_reference(&draw_params->res, info->indirect->buffer);
draw_params->offset = draw_params->offset =
info->indirect->offset + (info->index_size ? 12 : 8); info->indirect->offset + (info->index_size ? 12 : 8);
...@@ -192,7 +192,7 @@ iris_indirect_draw_vbo(struct iris_context *ice, ...@@ -192,7 +192,7 @@ iris_indirect_draw_vbo(struct iris_context *ice,
iris_update_draw_parameters(ice, &info); iris_update_draw_parameters(ice, &info);
batch->screen->vtbl.upload_render_state(ice, batch, &info); batch->screen->vtbl.upload_render_state(ice, batch, &info, info.indirect);
ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER; ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER; ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
...@@ -221,7 +221,7 @@ iris_simple_draw_vbo(struct iris_context *ice, ...@@ -221,7 +221,7 @@ iris_simple_draw_vbo(struct iris_context *ice,
iris_update_draw_parameters(ice, draw); iris_update_draw_parameters(ice, draw);
batch->screen->vtbl.upload_render_state(ice, batch, draw); batch->screen->vtbl.upload_render_state(ice, batch, draw, draw->indirect);
} }
/** /**
...@@ -234,6 +234,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) ...@@ -234,6 +234,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen; struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen;
const struct gen_device_info *devinfo = &screen->devinfo; const struct gen_device_info *devinfo = &screen->devinfo;
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER]; 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) if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
return; return;
...@@ -269,7 +270,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) ...@@ -269,7 +270,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
iris_handle_always_flush_cache(batch); iris_handle_always_flush_cache(batch);
if (info->indirect) if (indirect && indirect->buffer)
iris_indirect_draw_vbo(ice, info); iris_indirect_draw_vbo(ice, info);
else else
iris_simple_draw_vbo(ice, info); iris_simple_draw_vbo(ice, info);
......
...@@ -60,7 +60,8 @@ struct iris_vtable { ...@@ -60,7 +60,8 @@ struct iris_vtable {
void (*init_compute_context)(struct iris_batch *batch); void (*init_compute_context)(struct iris_batch *batch);
void (*upload_render_state)(struct iris_context *ice, void (*upload_render_state)(struct iris_context *ice,
struct iris_batch *batch, struct iris_batch *batch,
const struct pipe_draw_info *draw); const struct pipe_draw_info *draw,
const struct pipe_draw_indirect_info *indirect);
void (*update_surface_base_address)(struct iris_batch *batch, void (*update_surface_base_address)(struct iris_batch *batch,
struct iris_binder *binder); struct iris_binder *binder);
void (*upload_compute_state)(struct iris_context *ice, void (*upload_compute_state)(struct iris_context *ice,
......
...@@ -6417,7 +6417,8 @@ iris_upload_dirty_render_state(struct iris_context *ice, ...@@ -6417,7 +6417,8 @@ iris_upload_dirty_render_state(struct iris_context *ice,
static void static void
iris_upload_render_state(struct iris_context *ice, iris_upload_render_state(struct iris_context *ice,
struct iris_batch *batch, struct iris_batch *batch,
const struct pipe_draw_info *draw) const struct pipe_draw_info *draw,
const struct pipe_draw_indirect_info *indirect)
{ {
bool use_predicate = ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT; bool use_predicate = ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT;
...@@ -6492,14 +6493,14 @@ iris_upload_render_state(struct iris_context *ice, ...@@ -6492,14 +6493,14 @@ iris_upload_render_state(struct iris_context *ice,
#define _3DPRIM_START_INSTANCE 0x243C #define _3DPRIM_START_INSTANCE 0x243C
#define _3DPRIM_BASE_VERTEX 0x2440 #define _3DPRIM_BASE_VERTEX 0x2440
if (draw->indirect) { if (indirect && !indirect->count_from_stream_output) {
if (draw->indirect->indirect_draw_count) { if (indirect->indirect_draw_count) {
use_predicate = true; use_predicate = true;
struct iris_bo *draw_count_bo = struct iris_bo *draw_count_bo =
iris_resource_bo(draw->indirect->indirect_draw_count); iris_resource_bo(indirect->indirect_draw_count);
unsigned draw_count_offset = unsigned draw_count_offset =
draw->indirect->indirect_draw_count_offset; indirect->indirect_draw_count_offset;
iris_emit_pipe_control_flush(batch, iris_emit_pipe_control_flush(batch,
"ensure indirect draw buffer is flushed", "ensure indirect draw buffer is flushed",
...@@ -6551,43 +6552,43 @@ iris_upload_render_state(struct iris_context *ice, ...@@ -6551,43 +6552,43 @@ iris_upload_render_state(struct iris_context *ice,
iris_batch_emit(batch, &mi_predicate, sizeof(uint32_t)); iris_batch_emit(batch, &mi_predicate, sizeof(uint32_t));
} }
} }
struct iris_bo *bo = iris_resource_bo(draw->indirect->buffer); struct iris_bo *bo = iris_resource_bo(indirect->buffer);
assert(bo); assert(bo);
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) { iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = _3DPRIM_VERTEX_COUNT; lrm.RegisterAddress = _3DPRIM_VERTEX_COUNT;
lrm.MemoryAddress = ro_bo(bo, draw->indirect->offset + 0); lrm.MemoryAddress = ro_bo(bo, indirect->offset + 0);
} }
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm)