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,
struct u_vbuf *vbuf = cso->vbuf_current;
/* 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 */
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) {
u_vbuf_draw_vbo(vbuf, info);
......
......@@ -445,9 +445,9 @@ resolve_draw_info(const struct pipe_draw_info *raw_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 *)info->count_from_stream_output;
(struct draw_so_target *)info->indirect->count_from_stream_output;
assert(vertex_buffer != NULL);
info->count = vertex_buffer->stride == 0 ? 0 :
target->internal_offset / vertex_buffer->stride;
......@@ -455,6 +455,7 @@ 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;
}
}
......
......@@ -356,13 +356,14 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE
int sh, i;
DUMP(draw_info, info);
if (info->count_from_stream_output)
DUMP_M(stream_output_target, info,
count_from_stream_output);
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)
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");
......@@ -705,7 +706,7 @@ dd_unreference_copy_of_call(struct dd_call *dst)
case CALL_FLUSH:
break;
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.indirect_draw_count, NULL);
if (dst->info.draw_vbo.draw.index_size &&
......@@ -1305,9 +1306,6 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
record->call.type = CALL_DRAW_VBO;
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) {
record->call.info.draw_vbo.draw.index.resource = NULL;
pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource,
......@@ -1324,6 +1322,9 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
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);
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 {
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)
trace_dump_member(uint, state, restart_index);
trace_dump_member(ptr, state, index.resource);
trace_dump_member(ptr, state, count_from_stream_output);
if (!state->indirect) {
trace_dump_member(ptr, state, indirect);
......@@ -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(ptr, state, indirect->buffer);
trace_dump_member(ptr, state, indirect->indirect_draw_count);
trace_dump_member(ptr, state, indirect->count_from_stream_output);
}
trace_dump_struct_end();
......
......@@ -139,7 +139,7 @@ util_draw_indirect(struct pipe_context *pipe,
unsigned num_params = info_in->index_size ? 5 : 4;
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));
......
......@@ -941,7 +941,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
else
util_dump_member(stream, ptr, state, index.resource);
}
util_dump_member(stream, ptr, state, count_from_stream_output);
if (!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)
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);
}
util_dump_struct_end(stream);
......
......@@ -114,7 +114,7 @@ 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) {
if (info->indirect && info->indirect->buffer) {
indirect = read_indirect_elements(context, info->indirect);
count = indirect.count;
start = indirect.firstIndex;
......@@ -235,7 +235,7 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context,
assert(info->index_size);
assert(info->primitive_restart);
if (info->indirect) {
if (info->indirect && info->indirect->buffer) {
indirect = read_indirect_elements(context, info->indirect);
info_count = indirect.count;
info_start = indirect.firstIndex;
......
......@@ -126,7 +126,6 @@ tc_batch_execute(void *job, UNUSED int thread_index)
if (next != last && next->call_id == TC_CALL_draw_vbo &&
first_info->draw.drawid == 0 &&
!first_info->draw.indirect &&
!first_info->draw.count_from_stream_output &&
is_next_call_a_mergeable_draw(first_info, next, &next_info)) {
/* Merge up to 256 draw calls. */
struct pipe_draw_start_count multi[256];
......@@ -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;
pipe->draw_vbo(pipe, &info->draw);
pipe_so_target_reference(&info->draw.count_from_stream_output, 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);
}
}
......@@ -2243,9 +2242,6 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
return;
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));
p->draw.has_user_indices = false;
p->draw.index.resource = buffer;
......@@ -2253,9 +2249,6 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
} else {
/* Non-indexed call or indexed with a real index buffer. */
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) {
tc_set_resource_reference(&p->draw.index.resource,
info->index.resource);
......@@ -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->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;
}
......
......@@ -1306,7 +1306,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
new_info = *info;
/* 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;
unsigned draw_count = 0;
......
......@@ -231,7 +231,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
uint32_t draw_mode;
unsigned i;
if (!info->count_from_stream_output && !info->indirect &&
if (!info->indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
return;
......
......@@ -97,7 +97,7 @@ 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) {
if (info->indirect && info->indirect->buffer) {
struct fd_resource *ind = fd_resource(info->indirect->buffer);
emit_marker(ring, 7);
......
......@@ -91,7 +91,7 @@ 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) {
if (info->indirect && info->indirect->buffer) {
struct fd_resource *ind = fd_resource(info->indirect->buffer);
emit_marker5(ring, 7);
......
......@@ -195,7 +195,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))
if (!(emit.key.hs || emit.key.ds || emit.key.gs || (info->indirect && info->indirect->buffer)))
fd6_vsc_update_sizes(ctx->batch, info);
fixup_shader_state(ctx, &emit.key.key);
......@@ -315,7 +315,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
*/
emit_marker6(ring, 7);
if (info->indirect) {
if (info->indirect && info->indirect->buffer) {
draw_emit_indirect(ring, &draw0, info, index_offset);
} else {
draw_emit(ring, &draw0, info, index_offset);
......
......@@ -175,7 +175,7 @@ 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)
if (info->indirect && info->indirect->buffer)
resource_read(batch, info->indirect->buffer);
/* Mark textures as being read */
......@@ -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
* 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);
return;
}
if (info->mode != PIPE_PRIM_MAX &&
!info->count_from_stream_output && !info->indirect &&
!info->indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
return;
......
......@@ -118,7 +118,7 @@ iris_update_draw_parameters(struct iris_context *ice,
if (ice->state.vs_uses_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);
draw_params->offset =
info->indirect->offset + (info->index_size ? 12 : 8);
......@@ -192,7 +192,7 @@ iris_indirect_draw_vbo(struct iris_context *ice,
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.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
......@@ -221,7 +221,7 @@ iris_simple_draw_vbo(struct iris_context *ice,
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)
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;
......@@ -269,7 +270,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
iris_handle_always_flush_cache(batch);
if (info->indirect)
if (indirect && indirect->buffer)
iris_indirect_draw_vbo(ice, info);
else
iris_simple_draw_vbo(ice, info);
......
......@@ -60,7 +60,8 @@ struct iris_vtable {
void (*init_compute_context)(struct iris_batch *batch);
void (*upload_render_state)(struct iris_context *ice,
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,
struct iris_binder *binder);
void (*upload_compute_state)(struct iris_context *ice,
......
......@@ -6417,7 +6417,8 @@ iris_upload_dirty_render_state(struct iris_context *ice,
static void
iris_upload_render_state(struct iris_context *ice,
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;
......@@ -6492,14 +6493,14 @@ iris_upload_render_state(struct iris_context *ice,
#define _3DPRIM_START_INSTANCE 0x243C
#define _3DPRIM_BASE_VERTEX 0x2440
if (draw->indirect) {
if (draw->indirect->indirect_draw_count) {
if (indirect && !indirect->count_from_stream_output) {
if (indirect->indirect_draw_count) {
use_predicate = true;
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 =
draw->indirect->indirect_draw_count_offset;
indirect->indirect_draw_count_offset;
iris_emit_pipe_control_flush(batch,
"ensure indirect draw buffer is flushed",
......@@ -6551,43 +6552,43 @@ iris_upload_render_state(struct iris_context *ice,
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);
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
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) {
lrm.RegisterAddress = _3DPRIM_INSTANCE_COUNT;
lrm.MemoryAddress = ro_bo(bo, draw->indirect->offset + 4);
lrm.MemoryAddress = ro_bo(bo, indirect->offset + 4);
}
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = _3DPRIM_START_VERTEX;
lrm.MemoryAddress = ro_bo(bo, draw->indirect->offset + 8);
lrm.MemoryAddress = ro_bo(bo, indirect->offset + 8);
}
if (draw->index_size) {
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = _3DPRIM_BASE_VERTEX;
lrm.MemoryAddress = ro_bo(bo, draw->indirect->offset + 12);
lrm.MemoryAddress = ro_bo(bo, indirect->offset + 12);
}
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = _3DPRIM_START_INSTANCE;
lrm.MemoryAddress = ro_bo(bo, draw->indirect->offset + 16);
lrm.MemoryAddress = ro_bo(bo, indirect->offset + 16);
}
} else {
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = _3DPRIM_START_INSTANCE;
lrm.MemoryAddress = ro_bo(bo, draw->indirect->offset + 12);
lrm.MemoryAddress = ro_bo(bo, indirect->offset + 12);
}
iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_IMM), lri) {
lri.RegisterOffset = _3DPRIM_BASE_VERTEX;
lri.DataDWord = 0;
}
}
} else if (draw->count_from_stream_output) {
} else if (indirect && indirect->count_from_stream_output) {
struct iris_stream_output_target *so =
(void *) draw->count_from_stream_output;
(void *) indirect->count_from_stream_output;
/* XXX: Replace with actual cache tracking */
iris_emit_pipe_control_flush(batch,
......@@ -6615,7 +6616,7 @@ iris_upload_render_state(struct iris_context *ice,
prim.VertexAccessType = draw->index_size > 0 ? RANDOM : SEQUENTIAL;
prim.PredicateEnable = use_predicate;
if (draw->indirect || draw->count_from_stream_output) {
if (indirect) {
prim.IndirectParameterEnable = true;
} else {
prim.StartInstanceLocation = draw->start_instance;
......
......@@ -61,7 +61,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (!llvmpipe_check_render_cond(lp))
return;
if (info->indirect) {
if (info->indirect && info->indirect->buffer) {
util_draw_indirect(pipe, info);
return;
}
......
......@@ -292,10 +292,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->count_from_stream_output)) {
if (unlikely(info->indirect && info->indirect->count_from_stream_output)) {
struct pipe_context *pipe = &nv50->base.pipe;
struct nv50_so_target *targ;
targ = nv50_so_target(info->count_from_stream_output);
targ = nv50_so_target(info->indirect->count_from_stream_output);
if (!targ->pq) {
NOUVEAU_ERR("draw_stream_output not supported on pre-NVA0 cards\n");
return;
......
......@@ -702,7 +702,7 @@ nva0_draw_stream_output(struct nv50_context *nv50,
const struct pipe_draw_info *info)
{
struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_so_target *so = nv50_so_target(info->count_from_stream_output);
struct nv50_so_target *so = nv50_so_target(info->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);
......@@ -874,7 +874,7 @@ 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->count_from_stream_output)) {
if (unlikely(info->indirect && info->indirect->count_from_stream_output)) {
nva0_draw_stream_output(nv50, info);
} else {
nv50_draw_arrays(nv50,
......
......@@ -769,7 +769,7 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0,
const struct pipe_draw_info *info)
{
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_so_target *so = nvc0_so_target(info->count_from_stream_output);
struct nvc0_so_target *so = nvc0_so_target(info->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;
......@@ -938,7 +938,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->index_size &&
(!info->indirect || info->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 +1005,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) {
if (nvc0->vertprog->vp.need_draw_parameters && (!info->indirect || info->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,7 +1057,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
}
if (nvc0->state.vbo_mode) {
if (info->indirect)
if (info->indirect && info->indirect->buffer)
nvc0_push_vbo_indirect(nvc0, info);
else
nvc0_push_vbo(nvc0, info);
......@@ -1088,10 +1088,10 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nvc0->base.vbo_dirty = false;
}
if (unlikely(info->indirect)) {
if (unlikely(info->indirect && info->indirect->buffer)) {
nvc0_draw_indirect(nvc0, info);
} else
if (unlikely(info->count_from_stream_output)) {
if (unlikely(info->indirect && info->indirect->count_from_stream_output)) {
nvc0_draw_stream_output(nvc0, info);
} else
if (info->index_size) {
......
......@@ -596,10 +596,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->count_from_stream_output)) {
if (unlikely(info->indirect && info->indirect->count_from_stream_output)) {
struct pipe_context *pipe = &nvc0->base.pipe;
struct nvc0_so_target *targ;
targ = nvc0_so_target(info->count_from_stream_output);
targ = nvc0_so_target(info->indirect->count_from_stream_output);
pipe->get_query_result(pipe, targ->pq, true, (void *)&vert_count);
vert_count /= targ->stride;
}
......
......@@ -363,8 +363,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->count_from_stream_output ?
pan_so_target(info->count_from_stream_output)->offset :
cfg.index_count = info->indirect && info->indirect->count_from_stream_output ?
pan_so_target(info->indirect->count_from_stream_output)->offset :
ctx->vertex_count;
}
}
......
......@@ -2065,8 +2065,15 @@ 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 (!info->indirect && !info->count && (index_size || !info->count_from_stream_output)) {
if (indirect && indirect->count_from_stream_output) {
count_from_so = indirect->count_from_stream_output;
indirect = NULL;
}
if (!indirect && !info->count && (index_size || !count_from_so)) {
return;
}
......@@ -2137,17 +2144,17 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
void *ptr;
unsigned start, count;
if (likely(!info->indirect)) {
if (likely(!indirect)) {
start = 0;
count = info->count;
}
else {
/* Have to get start/count from indirect buffer, slow path ahead... */
<