diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c index ca786489786..e7abbfc422b 100644 --- a/src/gallium/auxiliary/util/u_draw.c +++ b/src/gallium/auxiliary/util/u_draw.c @@ -145,8 +145,8 @@ util_draw_indirect(struct pipe_context *pipe, params = (uint32_t *) pipe_buffer_map_range(pipe, - info_in->indirect, - info_in->indirect_offset, + info_in->indirect->buffer, + info_in->indirect->offset, num_params * sizeof(uint32_t), PIPE_TRANSFER_READ, &transfer); diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index b9e6b522589..5e42bdd3028 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -941,11 +941,16 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) util_dump_member(stream, ptr, state, count_from_stream_output); - util_dump_member(stream, ptr, state, indirect); - util_dump_member(stream, uint, state, indirect_offset); - util_dump_member(stream, uint, state, indirect_stride); - util_dump_member(stream, uint, state, indirect_count); - util_dump_member(stream, uint, state, indirect_params_offset); + 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_struct_end(stream); } diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 62b88acca58..9d6d5297e6a 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -1168,15 +1168,15 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) int *data; if (new_info.indexed) { - data = pipe_buffer_map_range(pipe, new_info.indirect, - new_info.indirect_offset, 20, + data = pipe_buffer_map_range(pipe, new_info.indirect->buffer, + new_info.indirect->offset, 20, PIPE_TRANSFER_READ, &transfer); new_info.index_bias = data[3]; new_info.start_instance = data[4]; } else { - data = pipe_buffer_map_range(pipe, new_info.indirect, - new_info.indirect_offset, 16, + data = pipe_buffer_map_range(pipe, new_info.indirect->buffer, + new_info.indirect->offset, 16, PIPE_TRANSFER_READ, &transfer); new_info.start_instance = data[3]; } diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index de9de05b402..03a37f0bd29 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -217,7 +217,7 @@ The integer capabilities: pipe_draw_info::indirect_stride and ::indirect_count * ``PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS``: Whether the driver supports taking the number of indirect draws from a separate parameter - buffer, see pipe_draw_info::indirect_params. + buffer, see pipe_draw_indirect_info::indirect_draw_count. * ``PIPE_CAP_TGSI_FS_FINE_DERIVATIVE``: Whether the fragment shader supports the FINE versions of DDX/DDY. * ``PIPE_CAP_VENDOR_ID``: The vendor ID of the underlying hardware. If it's diff --git a/src/gallium/drivers/ddebug/dd_draw.c b/src/gallium/drivers/ddebug/dd_draw.c index 90ccf160e68..4b14516fb25 100644 --- a/src/gallium/drivers/ddebug/dd_draw.c +++ b/src/gallium/drivers/ddebug/dd_draw.c @@ -297,10 +297,12 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE if (info->count_from_stream_output) DUMP_M(stream_output_target, info, count_from_stream_output); - if (info->indirect) - DUMP_M(resource, info, indirect); - if (info->indirect_params) - DUMP_M(resource, info, indirect_params); + if (info->indirect) { + DUMP_M(resource, info, indirect->buffer); + if (info->indirect->indirect_draw_count) + DUMP_M(resource, info, indirect->indirect_draw_count); + } + fprintf(f, "\n"); /* TODO: dump active queries */ @@ -500,7 +502,7 @@ dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call) { switch (call->type) { case CALL_DRAW_VBO: - dd_dump_draw_vbo(state, &call->info.draw_vbo, f); + dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f); break; case CALL_LAUNCH_GRID: dd_dump_launch_grid(state, &call->info.launch_grid, f); @@ -619,9 +621,9 @@ dd_unreference_copy_of_call(struct dd_call *dst) { switch (dst->type) { case CALL_DRAW_VBO: - pipe_so_target_reference(&dst->info.draw_vbo.count_from_stream_output, NULL); - pipe_resource_reference(&dst->info.draw_vbo.indirect, NULL); - pipe_resource_reference(&dst->info.draw_vbo.indirect_params, NULL); + pipe_so_target_reference(&dst->info.draw_vbo.draw.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); break; case CALL_LAUNCH_GRID: pipe_resource_reference(&dst->info.launch_grid.indirect, NULL); @@ -661,13 +663,17 @@ dd_copy_call(struct dd_call *dst, struct dd_call *src) switch (src->type) { case CALL_DRAW_VBO: - pipe_so_target_reference(&dst->info.draw_vbo.count_from_stream_output, - src->info.draw_vbo.count_from_stream_output); - pipe_resource_reference(&dst->info.draw_vbo.indirect, - src->info.draw_vbo.indirect); - pipe_resource_reference(&dst->info.draw_vbo.indirect_params, - src->info.draw_vbo.indirect_params); + pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, + src->info.draw_vbo.draw.count_from_stream_output); + pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, + src->info.draw_vbo.indirect.buffer); + pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, + src->info.draw_vbo.indirect.indirect_draw_count); dst->info.draw_vbo = src->info.draw_vbo; + if (!src->info.draw_vbo.draw.indirect) + dst->info.draw_vbo.draw.indirect = NULL; + else + dst->info.draw_vbo.draw.indirect = &dst->info.draw_vbo.indirect; break; case CALL_LAUNCH_GRID: pipe_resource_reference(&dst->info.launch_grid.indirect, @@ -1173,7 +1179,13 @@ dd_context_draw_vbo(struct pipe_context *_pipe, struct dd_call call; call.type = CALL_DRAW_VBO; - call.info.draw_vbo = *info; + call.info.draw_vbo.draw = *info; + if (info->indirect) { + call.info.draw_vbo.indirect = *info->indirect; + call.info.draw_vbo.draw.indirect = &call.info.draw_vbo.indirect; + } else { + memset(&call.info.draw_vbo.indirect, 0, sizeof(*info->indirect)); + } dd_before_draw(dctx); pipe->draw_vbo(pipe, info); diff --git a/src/gallium/drivers/ddebug/dd_pipe.h b/src/gallium/drivers/ddebug/dd_pipe.h index deae1f5bc3d..ea3319397a5 100644 --- a/src/gallium/drivers/ddebug/dd_pipe.h +++ b/src/gallium/drivers/ddebug/dd_pipe.h @@ -104,12 +104,17 @@ struct call_generate_mipmap { unsigned last_layer; }; +struct call_draw_info { + struct pipe_draw_info draw; + struct pipe_draw_indirect_info indirect; +}; + struct dd_call { enum call_type type; union { - struct pipe_draw_info draw_vbo; + struct call_draw_info draw_vbo; struct pipe_grid_info launch_grid; struct call_resource_copy_region resource_copy_region; struct pipe_blit_info blit; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index b42b4685607..7cea5fb692e 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -818,10 +818,10 @@ static void nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; - struct nv04_resource *buf = nv04_resource(info->indirect); - struct nv04_resource *buf_count = nv04_resource(info->indirect_params); - unsigned size, macro, count = info->indirect_count, drawid = info->drawid; - uint32_t offset = buf->offset + info->indirect_offset; + 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 nvc0_screen *screen = nvc0->screen; PUSH_SPACE(push, 7); @@ -870,7 +870,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 (info->indirect->stride == size * 4) { draws = MIN2(draws, (NV04_PFIFO_MAX_PACKET_LEN - 4) / size); pushes = 1; } else { @@ -890,20 +890,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_params_offset, + buf_count->offset + info->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 * info->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 += info->indirect->stride; } } count -= draws; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index f3011c82cf9..ee6fd2667b3 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -1770,11 +1770,11 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info } else { /* Have to get start/count from indirect buffer, slow path ahead... */ - struct r600_resource *indirect_resource = (struct r600_resource *)info->indirect; + struct r600_resource *indirect_resource = (struct r600_resource *)info->indirect->buffer; unsigned *data = r600_buffer_map_sync_with_rings(&rctx->b, indirect_resource, PIPE_TRANSFER_READ); if (data) { - data += info->indirect_offset / sizeof(unsigned); + data += info->indirect->offset / sizeof(unsigned); start = data[2] * ib.index_size; count = data[0]; } @@ -1918,7 +1918,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0)); radeon_emit(cs, info->instance_count); } else { - uint64_t va = r600_resource(info->indirect)->gpu_address; + uint64_t va = r600_resource(info->indirect->buffer)->gpu_address; assert(rctx->b.chip_class >= EVERGREEN); // Invalidate so non-indirect draw calls reset this state @@ -1932,7 +1932,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, - (struct r600_resource*)info->indirect, + (struct r600_resource*)info->indirect->buffer, RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT)); } @@ -1982,7 +1982,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info radeon_emit(cs, max_size); radeon_emit(cs, PKT3(EG_PKT3_DRAW_INDEX_INDIRECT, 1, render_cond_bit)); - radeon_emit(cs, info->indirect_offset); + radeon_emit(cs, info->indirect->offset); radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA); } } @@ -2012,7 +2012,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info } else { radeon_emit(cs, PKT3(EG_PKT3_DRAW_INDIRECT, 1, render_cond_bit)); - radeon_emit(cs, info->indirect_offset); + radeon_emit(cs, info->indirect->offset); } radeon_emit(cs, V_0287F0_DI_SRC_SEL_AUTO_INDEX | (info->count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0)); diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index f7190055e3b..50bf8293465 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -627,6 +627,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw_info *info, const struct pipe_index_buffer *ib) { + struct pipe_draw_indirect_info *indirect = info->indirect; struct radeon_winsys_cs *cs = sctx->b.gfx.cs; unsigned sh_base_reg = sctx->shader_userdata.sh_base[PIPE_SHADER_VERTEX]; bool render_cond_bit = sctx->b.render_cond && !sctx->b.render_cond_force_off; @@ -707,8 +708,8 @@ static void si_emit_draw_packets(struct si_context *sctx, sctx->last_index_size = -1; } - if (info->indirect) { - uint64_t indirect_va = r600_resource(info->indirect)->gpu_address; + if (indirect) { + uint64_t indirect_va = r600_resource(indirect->buffer)->gpu_address; assert(indirect_va % 8 == 0); @@ -720,13 +721,13 @@ static void si_emit_draw_packets(struct si_context *sctx, radeon_emit(cs, indirect_va >> 32); radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - (struct r600_resource *)info->indirect, + (struct r600_resource *)indirect->buffer, RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT); unsigned di_src_sel = info->indexed ? V_0287F0_DI_SRC_SEL_DMA : V_0287F0_DI_SRC_SEL_AUTO_INDEX; - assert(info->indirect_offset % 4 == 0); + assert(indirect->offset % 4 == 0); if (info->indexed) { radeon_emit(cs, PKT3(PKT3_INDEX_BASE, 1, 0)); @@ -741,37 +742,37 @@ static void si_emit_draw_packets(struct si_context *sctx, radeon_emit(cs, PKT3(info->indexed ? PKT3_DRAW_INDEX_INDIRECT : PKT3_DRAW_INDIRECT, 3, render_cond_bit)); - radeon_emit(cs, info->indirect_offset); + radeon_emit(cs, indirect->offset); radeon_emit(cs, (sh_base_reg + SI_SGPR_BASE_VERTEX * 4 - SI_SH_REG_OFFSET) >> 2); radeon_emit(cs, (sh_base_reg + SI_SGPR_START_INSTANCE * 4 - SI_SH_REG_OFFSET) >> 2); radeon_emit(cs, di_src_sel); } else { uint64_t count_va = 0; - if (info->indirect_params) { + if (indirect->indirect_draw_count) { struct r600_resource *params_buf = - (struct r600_resource *)info->indirect_params; + (struct r600_resource *)indirect->indirect_draw_count; radeon_add_to_buffer_list( &sctx->b, &sctx->b.gfx, params_buf, RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT); - count_va = params_buf->gpu_address + info->indirect_params_offset; + count_va = params_buf->gpu_address + indirect->indirect_draw_count_offset; } radeon_emit(cs, PKT3(info->indexed ? PKT3_DRAW_INDEX_INDIRECT_MULTI : PKT3_DRAW_INDIRECT_MULTI, 8, render_cond_bit)); - radeon_emit(cs, info->indirect_offset); + radeon_emit(cs, indirect->offset); radeon_emit(cs, (sh_base_reg + SI_SGPR_BASE_VERTEX * 4 - SI_SH_REG_OFFSET) >> 2); radeon_emit(cs, (sh_base_reg + SI_SGPR_START_INSTANCE * 4 - SI_SH_REG_OFFSET) >> 2); radeon_emit(cs, ((sh_base_reg + SI_SGPR_DRAWID * 4 - SI_SH_REG_OFFSET) >> 2) | S_2C3_DRAW_INDEX_ENABLE(1) | - S_2C3_COUNT_INDIRECT_ENABLE(!!info->indirect_params)); - radeon_emit(cs, info->indirect_count); + S_2C3_COUNT_INDIRECT_ENABLE(!!indirect->indirect_draw_count)); + radeon_emit(cs, indirect->draw_count); radeon_emit(cs, count_va); radeon_emit(cs, count_va >> 32); - radeon_emit(cs, info->indirect_stride); + radeon_emit(cs, indirect->stride); radeon_emit(cs, di_src_sel); } } else { @@ -1072,17 +1073,19 @@ static void si_get_draw_start_count(struct si_context *sctx, const struct pipe_draw_info *info, unsigned *start, unsigned *count) { - if (info->indirect) { + struct pipe_draw_indirect_info *indirect = info->indirect; + + if (indirect) { unsigned indirect_count; struct pipe_transfer *transfer; unsigned begin, end; unsigned map_size; unsigned *data; - if (info->indirect_params) { + if (indirect->indirect_draw_count) { data = pipe_buffer_map_range(&sctx->b.b, - info->indirect_params, - info->indirect_params_offset, + indirect->indirect_draw_count, + indirect->indirect_draw_count_offset, sizeof(unsigned), PIPE_TRANSFER_READ, &transfer); @@ -1090,7 +1093,7 @@ static void si_get_draw_start_count(struct si_context *sctx, pipe_buffer_unmap(&sctx->b.b, transfer); } else { - indirect_count = info->indirect_count; + indirect_count = indirect->draw_count; } if (!indirect_count) { @@ -1098,9 +1101,9 @@ static void si_get_draw_start_count(struct si_context *sctx, return; } - map_size = (indirect_count - 1) * info->indirect_stride + 3 * sizeof(unsigned); - data = pipe_buffer_map_range(&sctx->b.b, info->indirect, - info->indirect_offset, map_size, + map_size = (indirect_count - 1) * indirect->stride + 3 * sizeof(unsigned); + data = pipe_buffer_map_range(&sctx->b.b, indirect->buffer, + indirect->offset, map_size, PIPE_TRANSFER_READ, &transfer); begin = UINT_MAX; @@ -1115,7 +1118,7 @@ static void si_get_draw_start_count(struct si_context *sctx, end = MAX2(end, start + count); } - data += info->indirect_stride / sizeof(unsigned); + data += indirect->stride / sizeof(unsigned); } pipe_buffer_unmap(&sctx->b.b, transfer); @@ -1301,18 +1304,20 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) } if (info->indirect) { - /* Add the buffer size for memory checking in need_cs_space. */ - r600_context_add_resource_size(ctx, info->indirect); + struct pipe_draw_indirect_info *indirect = info->indirect; - if (r600_resource(info->indirect)->TC_L2_dirty) { + /* Add the buffer size for memory checking in need_cs_space. */ + r600_context_add_resource_size(ctx, indirect->buffer); + + if (r600_resource(indirect->buffer)->TC_L2_dirty) { sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2; - r600_resource(info->indirect)->TC_L2_dirty = false; + r600_resource(indirect->buffer)->TC_L2_dirty = false; } - if (info->indirect_params && - r600_resource(info->indirect_params)->TC_L2_dirty) { + if (indirect->indirect_draw_count && + r600_resource(indirect->indirect_draw_count)->TC_L2_dirty) { sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2; - r600_resource(info->indirect_params)->TC_L2_dirty = false; + r600_resource(indirect->indirect_draw_count)->TC_L2_dirty = false; } } diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 13c0a9d5bcb..e4a5e3b693c 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -812,8 +812,16 @@ void trace_dump_draw_info(const struct pipe_draw_info *state) trace_dump_member(ptr, state, count_from_stream_output); - trace_dump_member(ptr, state, indirect); - trace_dump_member(uint, state, indirect_offset); + 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_struct_end(); } diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 0c9b4b45915..3cfdd349feb 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -641,6 +641,40 @@ struct pipe_index_buffer }; +struct pipe_draw_indirect_info +{ + unsigned offset; /**< must be 4 byte aligned */ + unsigned stride; /**< must be 4 byte aligned */ + unsigned draw_count; /**< number of indirect draws */ + unsigned indirect_draw_count_offset; /**< must be 4 byte aligned */ + + /* Indirect draw parameters resource is laid out as follows: + * + * if indexed is TRUE: + * struct { + * uint32_t count; + * uint32_t instance_count; + * uint32_t start; + * int32_t index_bias; + * uint32_t start_instance; + * }; + * otherwise: + * struct { + * uint32_t count; + * uint32_t instance_count; + * uint32_t start; + * uint32_t start_instance; + * }; + */ + struct pipe_resource *buffer; + + /* Indirect draw count resource: If not NULL, contains a 32-bit value which + * is to be used as the real draw_count. + */ + struct pipe_resource *indirect_draw_count; +}; + + /** * Information to describe a draw_vbo call. */ @@ -671,40 +705,9 @@ struct pipe_draw_info */ unsigned restart_index; - unsigned indirect_offset; /**< must be 4 byte aligned */ - unsigned indirect_stride; /**< must be 4 byte aligned */ - unsigned indirect_count; /**< number of indirect draws */ - - unsigned indirect_params_offset; /**< must be 4 byte aligned */ - /* Pointers must be at the end for an optimal structure layout on 64-bit. */ - /* Indirect draw parameters resource: If not NULL, most values are taken - * from this buffer instead, which is laid out as follows: - * - * if indexed is TRUE: - * struct { - * uint32_t count; - * uint32_t instance_count; - * uint32_t start; - * int32_t index_bias; - * uint32_t start_instance; - * }; - * otherwise: - * struct { - * uint32_t count; - * uint32_t instance_count; - * uint32_t start; - * uint32_t start_instance; - * }; - */ - struct pipe_resource *indirect; - - /* Indirect draw count resource: If not NULL, contains a 32-bit value which - * is to be used as the real indirect_count. In that case indirect_count - * becomes the maximum possible value. - */ - struct pipe_resource *indirect_params; + struct pipe_draw_indirect_info *indirect; /**< Indirect draw. */ /** * Stream output target. If not NULL, it's used to provide the 'count' diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c index 6f97ddd647b..6390735ac57 100644 --- a/src/gallium/state_trackers/nine/device9.c +++ b/src/gallium/state_trackers/nine/device9.c @@ -3031,7 +3031,6 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This, draw.restart_index = 0; draw.count_from_stream_output = NULL; draw.indirect = NULL; - draw.indirect_params = NULL; draw.instance_count = 1; draw.indexed = FALSE; draw.start = 0; diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c index 2046d9dbf2a..3b1cd7ced6d 100644 --- a/src/gallium/state_trackers/nine/nine_state.c +++ b/src/gallium/state_trackers/nine/nine_state.c @@ -2559,7 +2559,6 @@ init_draw_info(struct pipe_draw_info *info, info->restart_index = 0; info->count_from_stream_output = NULL; info->indirect = NULL; - info->indirect_params = NULL; } CSMT_ITEM_NO_WAIT(nine_context_draw_primitive, diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 5c9f7ea7917..29381b654dd 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -264,6 +264,7 @@ st_indirect_draw_vbo(struct gl_context *ctx, { struct st_context *st = st_context(ctx); struct pipe_draw_info info; + struct pipe_draw_indirect_info indirect; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); @@ -281,6 +282,7 @@ st_indirect_draw_vbo(struct gl_context *ctx, return; } + memset(&indirect, 0, sizeof(indirect)); util_draw_init_info(&info); if (ib) { @@ -294,8 +296,9 @@ st_indirect_draw_vbo(struct gl_context *ctx, info.mode = translate_prim(ctx, mode); info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; - info.indirect = st_buffer_object(indirect_data)->buffer; - info.indirect_offset = indirect_offset; + info.indirect = &indirect; + indirect.buffer = st_buffer_object(indirect_data)->buffer; + indirect.offset = indirect_offset; if (ST_DEBUG & DEBUG_DRAW) { debug_printf("st/draw indirect: mode %s drawcount %d indexed %d\n", @@ -308,18 +311,18 @@ st_indirect_draw_vbo(struct gl_context *ctx, int i; assert(!indirect_params); - info.indirect_count = 1; + indirect.draw_count = 1; for (i = 0; i < draw_count; i++) { info.drawid = i; cso_draw_vbo(st->cso_context, &info); - info.indirect_offset += stride; + indirect.offset += stride; } } else { - info.indirect_count = draw_count; - info.indirect_stride = stride; + indirect.draw_count = draw_count; + indirect.stride = stride; if (indirect_params) { - info.indirect_params = st_buffer_object(indirect_params)->buffer; - info.indirect_params_offset = indirect_params_offset; + indirect.indirect_draw_count = st_buffer_object(indirect_params)->buffer; + indirect.indirect_draw_count_offset = indirect_params_offset; } cso_draw_vbo(st->cso_context, &info); }