gallium: extend draw_vbo to support multi draws

Essentially rename multi_draw to draw_vbo and remove start and count
from pipe_draw_info.

This is only an interface change. It doesn't add multi draw support
anywhere.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7441>
This commit is contained in:
Marek Olšák 2020-11-01 09:04:40 -05:00 committed by Marge Bot
parent 80b391077f
commit 1cd455b17b
101 changed files with 852 additions and 618 deletions

View File

@ -1723,7 +1723,8 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count draw)
{
struct u_vbuf *vbuf = cso->vbuf_current;
@ -1738,10 +1739,10 @@ cso_draw_vbo(struct cso_context *cso,
indirect->count_from_stream_output == NULL);
if (vbuf) {
u_vbuf_draw_vbo(vbuf, info, indirect);
u_vbuf_draw_vbo(vbuf, info, indirect, draw);
} else {
struct pipe_context *pipe = cso->pipe;
pipe->draw_vbo(pipe, info, indirect);
pipe->draw_vbo(pipe, info, indirect, &draw, 1);
}
}
@ -1749,16 +1750,18 @@ void
cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
{
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
util_draw_init_info(&info);
info.mode = mode;
info.start = start;
info.count = count;
info.min_index = start;
info.max_index = start + count - 1;
cso_draw_vbo(cso, &info, NULL);
draw.start = start;
draw.count = count;
cso_draw_vbo(cso, &info, NULL, draw);
}
void
@ -1767,16 +1770,18 @@ cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
uint start_instance, uint instance_count)
{
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
util_draw_init_info(&info);
info.mode = mode;
info.start = start;
info.count = count;
info.min_index = start;
info.max_index = start + count - 1;
info.start_instance = start_instance;
info.instance_count = instance_count;
cso_draw_vbo(cso, &info, NULL);
draw.start = start;
draw.count = count;
cso_draw_vbo(cso, &info, NULL, draw);
}

View File

@ -218,7 +218,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_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count draw);
void
cso_draw_arrays_instanced(struct cso_context *cso, uint mode,

View File

@ -324,7 +324,9 @@ 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_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
/*******************************************************************************

View File

@ -382,11 +382,12 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
*/
static void
draw_pt_arrays_restart(struct draw_context *draw,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw_info)
{
const unsigned prim = info->mode;
const unsigned start = info->start;
const unsigned count = info->count;
const unsigned start = draw_info->start;
const unsigned count = draw_info->count;
const unsigned elt_max = draw->pt.user.eltMax;
unsigned i, j, cur_start, cur_count;
/* The largest index within a loop using the i variable as the index.
@ -441,21 +442,24 @@ 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,
const struct pipe_draw_start_count *raw_draw,
struct pipe_draw_info *info,
struct pipe_draw_start_count *draw,
struct pipe_vertex_buffer *vertex_buffer)
{
memcpy(info, raw_info, sizeof(struct pipe_draw_info));
memcpy(draw, raw_draw, sizeof(struct pipe_draw_start_count));
if (indirect && indirect->count_from_stream_output) {
struct draw_so_target *target =
(struct draw_so_target *)indirect->count_from_stream_output;
assert(vertex_buffer != NULL);
info->count = vertex_buffer->stride == 0 ? 0 :
draw->count = vertex_buffer->stride == 0 ? 0 :
target->internal_offset / vertex_buffer->stride;
/* Stream output draw can not be indexed */
debug_assert(!info->index_size);
info->max_index = info->count - 1;
info->max_index = draw->count - 1;
}
}
@ -468,13 +472,16 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
unsigned instance;
unsigned index_limit;
unsigned count;
unsigned fpstate = util_fpstate_get();
struct pipe_draw_info resolved_info;
struct pipe_draw_start_count resolved_draw;
if (info->instance_count == 0)
return;
@ -484,13 +491,16 @@ draw_vbo(struct draw_context *draw,
*/
util_fpstate_set_denorms_to_zero(fpstate);
resolve_draw_info(info, indirect, &resolved_info, &(draw->pt.vertex_buffer[0]));
resolve_draw_info(info, indirect, &draws[0], &resolved_info,
&resolved_draw, &(draw->pt.vertex_buffer[0]));
info = &resolved_info;
draws = &resolved_draw;
num_draws = 1;
if (info->index_size)
assert(draw->pt.user.elts);
count = info->count;
count = draws[0].count;
draw->pt.user.eltBias = info->index_bias;
draw->pt.user.min_index = info->min_index;
@ -502,7 +512,7 @@ draw_vbo(struct draw_context *draw,
if (0)
debug_printf("draw_vbo(mode=%u start=%u count=%u):\n",
info->mode, info->start, count);
info->mode, draws[0].start, count);
if (0)
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
@ -530,7 +540,7 @@ draw_vbo(struct draw_context *draw,
}
if (0)
draw_print_arrays(draw, info->mode, info->start, MIN2(count, 20));
draw_print_arrays(draw, info->mode, draws[0].start, MIN2(count, 20));
index_limit = util_draw_max_index(draw->pt.vertex_buffer,
draw->pt.vertex_element,
@ -554,7 +564,7 @@ draw_vbo(struct draw_context *draw,
}
draw->pt.max_index = index_limit - 1;
draw->start_index = info->start;
draw->start_index = draws[0].start;
/*
* TODO: We could use draw->pt.max_index to further narrow
@ -575,10 +585,10 @@ draw_vbo(struct draw_context *draw,
draw_new_instance(draw);
if (info->primitive_restart) {
draw_pt_arrays_restart(draw, info);
draw_pt_arrays_restart(draw, info, &draws[0]);
}
else {
draw_pt_arrays(draw, info->mode, info->start, count);
draw_pt_arrays(draw, info->mode, draws[0].start, count);
}
}

View File

@ -352,11 +352,13 @@ 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,
const struct pipe_draw_indirect_info *indirect, FILE *f)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw, FILE *f)
{
int sh, i;
DUMP(draw_info, info);
DUMP(draw_start_count, draw);
if (indirect) {
if (indirect->buffer)
DUMP_M(resource, indirect, buffer);
@ -633,8 +635,9 @@ 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,
&call->info.draw_vbo.indirect, f);
dd_dump_draw_vbo(state, &call->info.draw_vbo.info,
&call->info.draw_vbo.indirect,
&call->info.draw_vbo.draw, f);
break;
case CALL_LAUNCH_GRID:
dd_dump_launch_grid(state, &call->info.launch_grid, f);
@ -710,11 +713,11 @@ dd_unreference_copy_of_call(struct dd_call *dst)
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 &&
!dst->info.draw_vbo.draw.has_user_indices)
pipe_resource_reference(&dst->info.draw_vbo.draw.index.resource, NULL);
if (dst->info.draw_vbo.info.index_size &&
!dst->info.draw_vbo.info.has_user_indices)
pipe_resource_reference(&dst->info.draw_vbo.info.index.resource, NULL);
else
dst->info.draw_vbo.draw.index.user = NULL;
dst->info.draw_vbo.info.index.user = NULL;
break;
case CALL_LAUNCH_GRID:
pipe_resource_reference(&dst->info.launch_grid.indirect, NULL);
@ -1300,17 +1303,20 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
struct dd_draw_record *record = dd_create_record(dctx);
record->call.type = CALL_DRAW_VBO;
record->call.info.draw_vbo.draw = *info;
record->call.info.draw_vbo.info = *info;
record->call.info.draw_vbo.draw = draws[0];
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,
record->call.info.draw_vbo.info.index.resource = NULL;
pipe_resource_reference(&record->call.info.draw_vbo.info.index.resource,
info->index.resource);
}
@ -1330,7 +1336,7 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
}
dd_before_draw(dctx, record);
pipe->draw_vbo(pipe, info, indirect);
pipe->draw_vbo(pipe, info, indirect, draws, num_draws);
dd_after_draw(dctx, record);
}

View File

@ -122,8 +122,9 @@ struct call_flush {
};
struct call_draw_info {
struct pipe_draw_info draw;
struct pipe_draw_info info;
struct pipe_draw_indirect_info indirect;
struct pipe_draw_start_count draw;
};
struct call_get_query_result_resource {

View File

@ -31,7 +31,9 @@
#include "util/u_transfer.h"
static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
}

View File

@ -115,7 +115,9 @@ 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,
const struct pipe_draw_indirect_info *_indirect)
const struct pipe_draw_indirect_info *_indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
@ -133,7 +135,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, _indirect);
pipe->draw_vbo(pipe, &info, _indirect, draws, num_draws);
mtx_unlock(&rb_pipe->call_mutex);
rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);

View File

@ -90,7 +90,9 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
@ -100,10 +102,12 @@ 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_struct_array(draw_start_count, draws, num_draws);
trace_dump_arg(uint, num_draws);
trace_dump_trace_flush();
pipe->draw_vbo(pipe, info, indirect);
pipe->draw_vbo(pipe, info, indirect, draws, num_draws);
trace_dump_call_end();
}

View File

@ -775,11 +775,7 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
trace_dump_member(uint, state, index_size);
trace_dump_member(uint, state, has_user_indices);
trace_dump_member(uint, state, mode);
trace_dump_member(uint, state, start);
trace_dump_member(uint, state, count);
trace_dump_member(uint, state, start_instance);
trace_dump_member(uint, state, instance_count);
@ -796,6 +792,17 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
trace_dump_struct_end();
}
void trace_dump_draw_start_count(const struct pipe_draw_start_count *state)
{
if (!trace_dumping_enabled_locked())
return;
trace_dump_struct_begin("pipe_draw_start_count");
trace_dump_member(uint, state, start);
trace_dump_member(uint, state, count);
trace_dump_struct_end();
}
void trace_dump_draw_indirect_info(const struct pipe_draw_indirect_info *state)
{
if (!trace_dumping_enabled_locked())

View File

@ -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_start_count(const struct pipe_draw_start_count *state);
void trace_dump_draw_indirect_info(const struct pipe_draw_indirect_info *state);
void trace_dump_blit_info(const struct pipe_blit_info *);

View File

@ -97,9 +97,11 @@ util_primconvert_save_rasterizer_state(struct primconvert_context *pc,
void
util_primconvert_draw_vbo(struct primconvert_context *pc,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct pipe_draw_info new_info;
struct pipe_draw_start_count new_draw;
struct pipe_transfer *src_transfer = NULL;
u_translate_func trans_func;
u_generate_func gen_func;
@ -121,10 +123,10 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
unsigned index_size;
u_index_translator(pc->cfg.primtypes_mask,
info->mode, info->index_size, info->count,
info->mode, info->index_size, draw->count,
pc->api_pv, pc->api_pv,
info->primitive_restart ? PR_ENABLE : PR_DISABLE,
&mode, &index_size, &new_info.count,
&mode, &index_size, &new_draw.count,
&trans_func);
new_info.mode = mode;
new_info.index_size = index_size;
@ -140,31 +142,31 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
unsigned index_size;
u_index_generator(pc->cfg.primtypes_mask,
info->mode, info->start, info->count,
info->mode, draw->start, draw->count,
pc->api_pv, pc->api_pv,
&mode, &index_size, &new_info.count,
&mode, &index_size, &new_draw.count,
&gen_func);
new_info.mode = mode;
new_info.index_size = index_size;
}
u_upload_alloc(pc->pipe->stream_uploader, 0, new_info.index_size * new_info.count, 4,
u_upload_alloc(pc->pipe->stream_uploader, 0, new_info.index_size * new_draw.count, 4,
&ib_offset, &new_info.index.resource, &dst);
new_info.start = ib_offset / new_info.index_size;
new_draw.start = ib_offset / new_info.index_size;
if (info->index_size) {
trans_func(src, info->start, info->count, new_info.count, info->restart_index, dst);
trans_func(src, draw->start, draw->count, new_draw.count, info->restart_index, dst);
if (pc->cfg.fixed_prim_restart && info->primitive_restart) {
new_info.restart_index = (1ull << (new_info.index_size * 8)) - 1;
if (info->restart_index != new_info.restart_index)
util_translate_prim_restart_data(new_info.index_size, dst, dst,
new_info.count,
new_draw.count,
info->restart_index);
}
}
else {
gen_func(info->start, new_info.count, dst);
gen_func(draw->start, new_draw.count, dst);
}
if (src_transfer)
@ -173,7 +175,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, NULL);
pc->pipe->draw_vbo(pc->pipe, &new_info, NULL, &new_draw, 1);
pipe_resource_reference(&new_info.index.resource, NULL);
}

View File

@ -46,6 +46,7 @@ void util_primconvert_save_rasterizer_state(struct primconvert_context *pc,
const struct pipe_rasterizer_state
*rast);
void util_primconvert_draw_vbo(struct primconvert_context *pc,
const struct pipe_draw_info *info);
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw);
#endif /* U_PRIMCONVERT_H_ */

View File

@ -176,14 +176,16 @@ util_draw_indirect(struct pipe_context *pipe,
}
for (unsigned i = 0; i < draw_count; i++) {
info.count = params[0];
struct pipe_draw_start_count draw;
draw.count = params[0];
info.instance_count = params[1];
info.start = params[2];
draw.start = params[2];
info.index_bias = info_in->index_size ? params[3] : 0;
info.start_instance = info_in->index_size ? params[4] : params[3];
info.drawid = i;
pipe->draw_vbo(pipe, &info, NULL);
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
params += indirect->stride / 4;
}

View File

@ -55,15 +55,17 @@ util_draw_arrays(struct pipe_context *pipe,
uint count)
{
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
util_draw_init_info(&info);
info.mode = mode;
info.start = start;
info.count = count;
info.min_index = start;
info.max_index = start + count - 1;
pipe->draw_vbo(pipe, &info, NULL);
draw.start = start;
draw.count = count;
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
}
static inline void
@ -75,17 +77,19 @@ util_draw_elements(struct pipe_context *pipe,
uint count)
{
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
util_draw_init_info(&info);
info.index.user = indices;
info.has_user_indices = true;
info.index_size = index_size;
info.mode = mode;
info.start = start;
info.count = count;
info.index_bias = index_bias;
pipe->draw_vbo(pipe, &info, NULL);
draw.start = start;
draw.count = count;
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
}
static inline void
@ -97,18 +101,20 @@ util_draw_arrays_instanced(struct pipe_context *pipe,
uint instance_count)
{
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
util_draw_init_info(&info);
info.mode = mode;
info.start = start;
info.count = count;
info.start_instance = start_instance;
info.instance_count = instance_count;
info.index_bounds_valid = true;
info.min_index = start;
info.max_index = start + count - 1;
pipe->draw_vbo(pipe, &info, NULL);
draw.start = start;
draw.count = count;
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
}
static inline void
@ -123,19 +129,21 @@ util_draw_elements_instanced(struct pipe_context *pipe,
uint instance_count)
{
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
util_draw_init_info(&info);
info.index.user = indices;
info.has_user_indices = true;
info.index_size = index_size;
info.mode = mode;
info.start = start;
info.count = count;
info.index_bias = index_bias;
info.start_instance = start_instance;
info.instance_count = instance_count;
pipe->draw_vbo(pipe, &info, NULL);
draw.start = start;
draw.count = count;
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
}

View File

@ -200,6 +200,9 @@ util_dump_stream_output_target(FILE *stream,
void
util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state);
void
util_dump_draw_start_count(FILE *stream, const struct pipe_draw_start_count *state);
void
util_dump_draw_indirect_info(FILE *stream,
const struct pipe_draw_indirect_info *indirect);

View File

@ -917,8 +917,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
util_dump_member(stream, uint, state, has_user_indices);
util_dump_member(stream, enum_prim_mode, state, mode);
util_dump_member(stream, uint, state, start);
util_dump_member(stream, uint, state, count);
util_dump_member(stream, uint, state, start_instance);
util_dump_member(stream, uint, state, instance_count);
@ -944,6 +942,15 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
util_dump_struct_end(stream);
}
void
util_dump_draw_start_count(FILE *stream, const struct pipe_draw_start_count *state)
{
util_dump_struct_begin(stream, "pipe_draw_start_count");
util_dump_member(stream, uint, state, start);
util_dump_member(stream, uint, state, count);
util_dump_struct_end(stream);
}
void
util_dump_draw_indirect_info(FILE *stream,
const struct pipe_draw_indirect_info *state)

View File

@ -143,13 +143,14 @@ void util_set_shader_buffers_mask(struct pipe_shader_buffer *dst,
bool
util_upload_index_buffer(struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
struct pipe_resource **out_buffer,
unsigned *out_offset, unsigned alignment)
{
unsigned start_offset = info->start * info->index_size;
unsigned start_offset = draw->start * info->index_size;
u_upload_data(pipe->stream_uploader, start_offset,
info->count * info->index_size, alignment,
draw->count * info->index_size, alignment,
(char*)info->index.user + start_offset,
out_offset, out_buffer);
u_upload_unmap(pipe->stream_uploader);

View File

@ -54,6 +54,7 @@ void util_set_shader_buffers_mask(struct pipe_shader_buffer *dst,
bool util_upload_index_buffer(struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
struct pipe_resource **out_buffer,
unsigned *out_offset, unsigned alignment);

View File

@ -100,6 +100,7 @@ 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,
const struct pipe_draw_start_count *draw,
struct pipe_resource **dst_buffer)
{
struct pipe_screen *screen = context->screen;
@ -108,8 +109,8 @@ util_translate_prim_restart_ib(struct pipe_context *context,
const unsigned src_index_size = info->index_size;
unsigned dst_index_size;
DrawElementsIndirectCommand indirect;
unsigned count = info->count;
unsigned start = info->start;
unsigned count = draw->count;
unsigned start = draw->start;
/* 1-byte indexes are converted to 2-byte indexes, 4-byte stays 4-byte */
dst_index_size = MAX2(2, info->index_size);
@ -147,7 +148,7 @@ util_translate_prim_restart_ib(struct pipe_context *context,
goto error;
util_translate_prim_restart_data(src_index_size, src_map, dst_map,
info->count, info->restart_index);
draw->count, info->restart_index);
if (src_transfer)
pipe_buffer_unmap(context, src_transfer);
@ -222,16 +223,18 @@ 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_indirect_info *indirect_info)
const struct pipe_draw_indirect_info *indirect_info,
const struct pipe_draw_start_count *draw)
{
const void *src_map;
struct range_info ranges = {0};
struct pipe_draw_info new_info;
struct pipe_draw_start_count new_draw;
struct pipe_transfer *src_transfer = NULL;
unsigned i, start, count;
DrawElementsIndirectCommand indirect;
unsigned info_start = info->start;
unsigned info_count = info->count;
unsigned info_start = draw->start;
unsigned info_count = draw->count;
unsigned info_instance_count = info->instance_count;
assert(info->index_size);
@ -308,13 +311,14 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context,
/* draw ranges between the restart indexes */
new_info = *info;
new_draw = *draw;
/* we've effectively remapped this to a direct draw */
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, NULL);
new_draw.start = ranges.ranges[i].start;
new_draw.count = ranges.ranges[i].count;
context->draw_vbo(context, &new_info, NULL, &new_draw, 1);
}
FREE(ranges.ranges);

View File

@ -50,12 +50,14 @@ 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,
const struct pipe_draw_start_count *draw,
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_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw);
static inline unsigned
util_prim_restart_index_from_size(unsigned index_size)

View File

@ -64,6 +64,7 @@ enum tc_call_id {
* not needed. */
struct tc_draw_single {
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
};
typedef void (*tc_execute)(struct pipe_context *pipe, union tc_payload *payload);
@ -124,9 +125,9 @@ is_next_call_a_mergeable_draw(struct tc_draw_single *first_info,
simplify_draw_info(&(*next_info)->info);
/* All fields must be the same except start and count. */
return memcmp((uint32_t*)&first_info->info + 2,
(uint32_t*)&(*next_info)->info + 2,
sizeof(struct pipe_draw_info) - 8) == 0;
return memcmp((uint32_t*)&first_info->info,
(uint32_t*)&(*next_info)->info,
sizeof(struct pipe_draw_info)) == 0;
}
static void
@ -161,10 +162,10 @@ tc_batch_execute(void *job, UNUSED int thread_index)
struct pipe_draw_start_count multi[256];
unsigned num_draws = 2;
multi[0].start = first_info->info.start;
multi[0].count = first_info->info.count;
multi[1].start = next_info->info.start;
multi[1].count = next_info->info.count;
multi[0].start = first_info->draw.start;
multi[0].count = first_info->draw.count;
multi[1].start = next_info->draw.start;
multi[1].count = next_info->draw.count;
if (next_info->info.index_size)
pipe_resource_reference(&next_info->info.index.resource, NULL);
@ -174,14 +175,14 @@ tc_batch_execute(void *job, UNUSED int thread_index)
for (; next != last && num_draws < ARRAY_SIZE(multi) &&
is_next_call_a_mergeable_draw(first_info, next, &next_info);
next += next->num_call_slots, num_draws++) {
multi[num_draws].start = next_info->info.start;
multi[num_draws].count = next_info->info.count;
multi[num_draws].start = next_info->draw.start;
multi[num_draws].count = next_info->draw.count;
if (next_info->info.index_size)
pipe_resource_reference(&next_info->info.index.resource, NULL);
}
pipe->multi_draw(pipe, &first_info->info, NULL, multi, num_draws);
pipe->draw_vbo(pipe, &first_info->info, NULL, multi, num_draws);
if (first_info->info.index_size)
pipe_resource_reference(&first_info->info.index.resource, NULL);
iter = next;
@ -2230,7 +2231,7 @@ tc_call_draw_single(struct pipe_context *pipe, union tc_payload *payload)
{
struct tc_draw_single *info = (struct tc_draw_single*)payload;
pipe->draw_vbo(pipe, &info->info, NULL);
pipe->draw_vbo(pipe, &info->info, NULL, &info->draw, 1);
if (info->info.index_size)
pipe_resource_reference(&info->info.index.resource, NULL);
}
@ -2238,6 +2239,7 @@ tc_call_draw_single(struct pipe_context *pipe, union tc_payload *payload)
struct tc_draw_indirect {
struct pipe_draw_info info;
struct pipe_draw_indirect_info indirect;
struct pipe_draw_start_count draw;
};
static void
@ -2245,7 +2247,7 @@ tc_call_draw_indirect(struct pipe_context *pipe, union tc_payload *payload)
{
struct tc_draw_indirect *info = (struct tc_draw_indirect*)payload;
pipe->draw_vbo(pipe, &info->info, &info->indirect);
pipe->draw_vbo(pipe, &info->info, &info->indirect, &info->draw, 1);
if (info->info.index_size)
pipe_resource_reference(&info->info.index.resource, NULL);
@ -2256,7 +2258,9 @@ tc_call_draw_indirect(struct pipe_context *pipe, union tc_payload *payload)
static void
tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct threaded_context *tc = threaded_context(_pipe);
unsigned index_size = info->index_size;
@ -2264,6 +2268,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
if (unlikely(indirect)) {
assert(!has_user_indices);
assert(num_draws == 1);
struct tc_draw_indirect *p =
tc_add_struct_typed_call(tc, TC_CALL_draw_indirect, tc_draw_indirect);
@ -2280,8 +2285,14 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
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;
p->draw.start = draws[0].start;
return;
}
assert(num_draws == 1); /* TODO: implement multi draws */
if (index_size && has_user_indices) {
unsigned size = draws[0].count * index_size;
struct pipe_resource *buffer = NULL;
unsigned offset;
@ -2290,7 +2301,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
* to the driver if it was done afterwards.
*/
u_upload_data(tc->base.stream_uploader, 0, size, 4,
(uint8_t*)info->index.user + info->start * index_size,
(uint8_t*)info->index.user + draws[0].start * index_size,
&offset, &buffer);
if (unlikely(!buffer))
return;
@ -2300,7 +2311,8 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
memcpy(&p->info, info, sizeof(*info));
p->info.has_user_indices = false;
p->info.index.resource = buffer;
p->info.start = offset >> util_logbase2(index_size);
p->draw.start = offset >> util_logbase2(index_size);
p->draw.count = draws[0].count;
} else {
/* Non-indexed call or indexed with a real index buffer. */
struct tc_draw_single *p =
@ -2310,6 +2322,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
info->index.resource);
}
memcpy(&p->info, info, sizeof(*info));
p->draw = draws[0];
}
}

View File

@ -409,6 +409,7 @@ void u_vbuf_destroy(struct u_vbuf *mgr)
static enum pipe_error
u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned vb_mask, unsigned out_vb,
int start_vertex, unsigned num_vertices,
int min_index, boolean unroll_indices)
@ -475,12 +476,12 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
/* Translate. */
if (unroll_indices) {
struct pipe_transfer *transfer = NULL;
const unsigned offset = info->start * info->index_size;
const unsigned offset = draw->start * info->index_size;
uint8_t *map;
/* Create and map the output buffer. */
u_upload_alloc(mgr->pipe->stream_uploader, 0,
key->output_stride * info->count, 4,
key->output_stride * draw->count, 4,
&out_offset, &out_buffer,
(void**)&out_map);
if (!out_buffer)
@ -490,19 +491,19 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
map = (uint8_t*)info->index.user + offset;
} else {
map = pipe_buffer_map_range(mgr->pipe, info->index.resource, offset,
info->count * info->index_size,
draw->count * info->index_size,
PIPE_MAP_READ, &transfer);
}
switch (info->index_size) {
case 4:
tr->run_elts(tr, (unsigned*)map, info->count, 0, 0, out_map);
tr->run_elts(tr, (unsigned*)map, draw->count, 0, 0, out_map);
break;
case 2:
tr->run_elts16(tr, (uint16_t*)map, info->count, 0, 0, out_map);
tr->run_elts16(tr, (uint16_t*)map, draw->count, 0, 0, out_map);
break;
case 1:
tr->run_elts8(tr, map, info->count, 0, 0, out_map);
tr->run_elts8(tr, map, draw->count, 0, 0, out_map);
break;
}
@ -611,6 +612,7 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
static boolean
u_vbuf_translate_begin(struct u_vbuf *mgr,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
int start_vertex, unsigned num_vertices,
int min_index, boolean unroll_indices)
{
@ -717,8 +719,8 @@ u_vbuf_translate_begin(struct u_vbuf *mgr,
for (type = 0; type < VB_NUM; type++) {
if (key[type].nr_elements) {
enum pipe_error err;
err = u_vbuf_translate_buffers(mgr, &key[type], info, mask[type],
mgr->fallback_vbs[type],
err = u_vbuf_translate_buffers(mgr, &key[type], info, draw,
mask[type], mgr->fallback_vbs[type],
start[type], num[type], min_index,
unroll_indices && type == VB_VERTEX);
if (err != PIPE_OK)
@ -1133,10 +1135,11 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(const struct u_vbuf *mgr)
static void
u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
unsigned count,
const void *indices, unsigned *out_min_index,
unsigned *out_max_index)
{
if (!info->count) {
if (!count) {
*out_min_index = 0;
*out_max_index = 0;
return;
@ -1148,7 +1151,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
unsigned max = 0;
unsigned min = ~0u;
if (info->primitive_restart) {
for (unsigned i = 0; i < info->count; i++) {
for (unsigned i = 0; i < count; i++) {
if (ui_indices[i] != info->restart_index) {
if (ui_indices[i] > max) max = ui_indices[i];
if (ui_indices[i] < min) min = ui_indices[i];
@ -1156,7 +1159,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
}
}
else {
for (unsigned i = 0; i < info->count; i++) {
for (unsigned i = 0; i < count; i++) {
if (ui_indices[i] > max) max = ui_indices[i];
if (ui_indices[i] < min) min = ui_indices[i];
}
@ -1170,7 +1173,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
unsigned short max = 0;
unsigned short min = ~((unsigned short)0);
if (info->primitive_restart) {
for (unsigned i = 0; i < info->count; i++) {
for (unsigned i = 0; i < count; i++) {
if (us_indices[i] != info->restart_index) {
if (us_indices[i] > max) max = us_indices[i];
if (us_indices[i] < min) min = us_indices[i];
@ -1178,7 +1181,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
}
}
else {
for (unsigned i = 0; i < info->count; i++) {
for (unsigned i = 0; i < count; i++) {
if (us_indices[i] > max) max = us_indices[i];
if (us_indices[i] < min) min = us_indices[i];
}
@ -1192,7 +1195,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
unsigned char max = 0;
unsigned char min = ~((unsigned char)0);
if (info->primitive_restart) {
for (unsigned i = 0; i < info->count; i++) {
for (unsigned i = 0; i < count; i++) {
if (ub_indices[i] != info->restart_index) {
if (ub_indices[i] > max) max = ub_indices[i];
if (ub_indices[i] < min) min = ub_indices[i];
@ -1200,7 +1203,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
}
}
else {
for (unsigned i = 0; i < info->count; i++) {
for (unsigned i = 0; i < count; i++) {
if (ub_indices[i] > max) max = ub_indices[i];
if (ub_indices[i] < min) min = ub_indices[i];
}
@ -1216,6 +1219,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned *out_min_index, unsigned *out_max_index)
{
struct pipe_transfer *transfer = NULL;
@ -1223,15 +1227,16 @@ void u_vbuf_get_minmax_index(struct pipe_context *pipe,
if (info->has_user_indices) {
indices = (uint8_t*)info->index.user +
info->start * info->index_size;
draw->start * info->index_size;
} else {
indices = pipe_buffer_map_range(pipe, info->index.resource,
info->start * info->index_size,
info->count * info->index_size,
draw->start * info->index_size,
draw->count * info->index_size,
PIPE_MAP_READ, &transfer);
}
u_vbuf_get_minmax_index_mapped(info, indices, out_min_index, out_max_index);
u_vbuf_get_minmax_index_mapped(info, draw->count, indices,
out_min_index, out_max_index);
if (transfer) {
pipe_buffer_unmap(pipe, transfer);
@ -1259,24 +1264,26 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info,
assert(info->index_size);
for (unsigned i = 0; i < draw_count; i++) {
struct pipe_draw_start_count draw;
unsigned offset = i * stride / 4;
info->count = indirect_data[offset + 0];
draw.count = indirect_data[offset + 0];
info->instance_count = indirect_data[offset + 1];
if (!info->count || !info->instance_count)
if (!draw.count || !info->instance_count)
continue;
info->start = indirect_data[offset + 2];
draw.start = indirect_data[offset + 2];
info->index_bias = indirect_data[offset + 3];
info->start_instance = indirect_data[offset + 4];
u_vbuf_draw_vbo(mgr, info, NULL);
u_vbuf_draw_vbo(mgr, info, NULL, draw);
}
}
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count draw)
{
struct pipe_context *pipe = mgr->pipe;
int start_vertex;
@ -1288,6 +1295,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
const uint32_t incompatible_vb_mask =
mgr->incompatible_vb_mask & used_vb_mask;
struct pipe_draw_info new_info;
struct pipe_draw_start_count new_draw;
/* Normal draw. No fallback and no user buffers. */
if (!incompatible_vb_mask &&
@ -1299,11 +1307,12 @@ 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, indirect);
pipe->draw_vbo(pipe, info, indirect, &draw, 1);
return;
}
new_info = *info;
new_draw = draw;
/* Handle indirect (multi)draws. */
if (indirect && indirect->buffer) {
@ -1406,8 +1415,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
/* Update the index range. */
unsigned min, max;
new_info.count = count; /* only used by get_minmax_index */
u_vbuf_get_minmax_index_mapped(&new_info,
u_vbuf_get_minmax_index_mapped(&new_info, count,
indices +
new_info.index_size * start,
&min, &max);
@ -1435,7 +1443,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
* This efficiently processes the multidraw with the time complexity
* equal to 1 draw call.
*/
new_info.start = ~0u;
new_draw.start = ~0u;
new_info.start_instance = ~0u;
unsigned end_vertex = 0;
unsigned end_instance = 0;
@ -1447,7 +1455,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
unsigned start_instance = data[offset + 3];
unsigned instance_count = data[offset + 1];
new_info.start = MIN2(new_info.start, start);
new_draw.start = MIN2(new_draw.start, start);
new_info.start_instance = MIN2(new_info.start_instance,
start_instance);
@ -1457,10 +1465,10 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
free(data);
/* Set the final counts. */
new_info.count = end_vertex - new_info.start;
new_draw.count = end_vertex - new_draw.start;
new_info.instance_count = end_instance - new_info.start_instance;
if (new_info.start == ~0u || !new_info.count || !new_info.instance_count)
if (new_draw.start == ~0u || !new_draw.count || !new_info.instance_count)
return;
}
}
@ -1474,7 +1482,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
min_index = new_info.min_index;
max_index = new_info.max_index;
} else {
u_vbuf_get_minmax_index(mgr->pipe, &new_info,
u_vbuf_get_minmax_index(mgr->pipe, &new_info, &new_draw,
&min_index, &max_index);
}
@ -1489,7 +1497,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
* performance. */
if (!indirect &&
!new_info.primitive_restart &&
util_is_vbo_upload_ratio_too_large(new_info.count, num_vertices) &&
util_is_vbo_upload_ratio_too_large(new_draw.count, num_vertices) &&
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
unroll_indices = TRUE;
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
@ -1502,8 +1510,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
min_index = 0;
}
} else {
start_vertex = new_info.start;
num_vertices = new_info.count;
start_vertex = new_draw.start;
num_vertices = new_draw.count;
min_index = 0;
}
@ -1511,7 +1519,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
if (unroll_indices ||
incompatible_vb_mask ||
mgr->ve->incompatible_elem_mask) {
if (!u_vbuf_translate_begin(mgr, &new_info, start_vertex, num_vertices,
if (!u_vbuf_translate_begin(mgr, &new_info, &new_draw,
start_vertex, num_vertices,
min_index, unroll_indices)) {
debug_warn_once("u_vbuf_translate_begin() failed");
return;
@ -1521,8 +1530,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
new_info.index_size = 0;
new_info.index_bias = 0;
new_info.min_index = 0;
new_info.max_index = new_info.count - 1;
new_info.start = 0;
new_info.max_index = new_draw.count - 1;
new_draw.start = 0;
}
user_vb_mask &= ~(incompatible_vb_mask |
@ -1565,7 +1574,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, indirect);
pipe->draw_vbo(pipe, &new_info, indirect, &draw, 1);
if (mgr->using_translate) {
u_vbuf_translate_end(mgr);

View File

@ -78,9 +78,11 @@ 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,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count draw);
void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned *out_min_index, unsigned *out_max_index);
/* Save/restore functionality. */

View File

@ -320,7 +320,9 @@ 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_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
void
d3d12_blit(struct pipe_context *pctx,

View File

@ -166,6 +166,7 @@ fill_sampler_descriptors(struct d3d12_context *ctx,
static unsigned
fill_state_vars(struct d3d12_context *ctx,
const struct pipe_draw_info *dinfo,
const struct pipe_draw_start_count *draw,
struct d3d12_shader *shader,
uint32_t *values)
{
@ -187,7 +188,7 @@ fill_state_vars(struct d3d12_context *ctx,
size += 4;
break;
case D3D12_STATE_VAR_FIRST_VERTEX:
ptr[0] = dinfo->index_size ? dinfo->index_bias : dinfo->start;
ptr[0] = dinfo->index_size ? dinfo->index_bias : draw->start;
size += 4;
break;
case D3D12_STATE_VAR_DEPTH_TRANSFORM:
@ -240,7 +241,8 @@ check_descriptors_left(struct d3d12_context *ctx)
static void
set_graphics_root_parameters(struct d3d12_context *ctx,
const struct pipe_draw_info *dinfo)
const struct pipe_draw_info *dinfo,
const struct pipe_draw_start_count *draw)
{
unsigned num_params = 0;
@ -269,7 +271,7 @@ set_graphics_root_parameters(struct d3d12_context *ctx,
/* TODO Don't always update state vars */
if (shader->num_state_vars > 0) {
uint32_t constants[D3D12_MAX_STATE_VARS * 4];
unsigned size = fill_state_vars(ctx, dinfo, shader, constants);
unsigned size = fill_state_vars(ctx, dinfo, draw, shader, constants);
ctx->cmdlist->SetGraphicsRoot32BitConstants(num_params, size, constants, 0);
num_params++;
}
@ -353,11 +355,12 @@ ib_format(unsigned index_size)
static void
twoface_emulation(struct d3d12_context *ctx,
struct d3d12_rasterizer_state *rast,
const struct pipe_draw_info *dinfo)
const struct pipe_draw_info *dinfo,
const struct pipe_draw_start_count *draw)
{
/* draw backfaces */
ctx->base.bind_rasterizer_state(&ctx->base, rast->twoface_back);
d3d12_draw_vbo(&ctx->base, dinfo, NULL);
d3d12_draw_vbo(&ctx->base, dinfo, NULL, draw, 1);
/* restore real state */
ctx->base.bind_rasterizer_state(&ctx->base, rast);
@ -417,7 +420,9 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct d3d12_context *ctx = d3d12_context(pctx);
struct d3d12_batch *batch;
@ -431,12 +436,12 @@ d3d12_draw_vbo(struct pipe_context *pctx,
dinfo->restart_index != 0xffffffff)) {
if (!dinfo->primitive_restart &&
!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
!u_trim_pipe_prim(dinfo->mode, (unsigned *)&draws[0].count))
return;
ctx->initial_api_prim = dinfo->mode;
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->gfx_pipeline_state.rast->base);
util_primconvert_draw_vbo(ctx->primconvert, dinfo);
util_primconvert_draw_vbo(ctx->primconvert, dinfo, &draws[0]);
return;
}
@ -452,7 +457,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
struct d3d12_rasterizer_state *rast = ctx->gfx_pipeline_state.rast;
if (rast->twoface_back) {
enum pipe_prim_type saved_mode = ctx->initial_api_prim;
twoface_emulation(ctx, rast, dinfo);
twoface_emulation(ctx, rast, dinfo, &draws[0]);
ctx->initial_api_prim = saved_mode;
}
@ -504,7 +509,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
assert(dinfo->index_size != 1);
if (dinfo->has_user_indices) {
if (!util_upload_index_buffer(pctx, dinfo, &index_buffer,
if (!util_upload_index_buffer(pctx, dinfo, &draws[0], &index_buffer,
&index_offset, 4)) {
debug_printf("util_upload_index_buffer() failed\n");
return;
@ -559,7 +564,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
ctx->cmdlist->SetPipelineState(ctx->current_pso);
}
set_graphics_root_parameters(ctx, dinfo);
set_graphics_root_parameters(ctx, dinfo, &draws[0]);
bool need_zero_one_depth_range = d3d12_need_zero_one_depth_range(ctx);
if (need_zero_one_depth_range != ctx->need_zero_one_depth_range) {
@ -698,12 +703,12 @@ d3d12_draw_vbo(struct pipe_context *pctx,
d3d12_apply_resource_states(ctx);
if (dinfo->index_size > 0)
ctx->cmdlist->DrawIndexedInstanced(dinfo->count, dinfo->instance_count,
dinfo->start, dinfo->index_bias,
ctx->cmdlist->DrawIndexedInstanced(draws[0].count, dinfo->instance_count,
draws[0].start, dinfo->index_bias,
dinfo->start_instance);
else
ctx->cmdlist->DrawInstanced(dinfo->count, dinfo->instance_count,
dinfo->start, dinfo->start_instance);
ctx->cmdlist->DrawInstanced(draws[0].count, dinfo->instance_count,
draws[0].start, dinfo->start_instance);
ctx->state_dirty = 0;

View File

@ -224,7 +224,9 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct etna_context *ctx = etna_context(pctx);
struct etna_screen *screen = ctx->screen;
@ -234,7 +236,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (!indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
if (ctx->vertex_elements == NULL || ctx->vertex_elements->num_elements == 0)
@ -243,11 +245,11 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (!(ctx->prim_hwsupport & (1 << info->mode))) {
struct primconvert_context *primconvert = ctx->primconvert;
util_primconvert_save_rasterizer_state(primconvert, ctx->rasterizer);
util_primconvert_draw_vbo(primconvert, info);
util_primconvert_draw_vbo(primconvert, info, &draws[0]);
return;
}
int prims = u_decomposed_prims_for_vertices(info->mode, info->count);
int prims = u_decomposed_prims_for_vertices(info->mode, draws[0].count);
if (unlikely(prims <= 0)) {
DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode);
return;
@ -266,12 +268,12 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (info->index_size) {
indexbuf = info->has_user_indices ? NULL : info->index.resource;
if (info->has_user_indices &&
!util_upload_index_buffer(pctx, info, &indexbuf, &index_offset, 4)) {
!util_upload_index_buffer(pctx, info, &draws[0], &indexbuf, &index_offset, 4)) {
BUG("Index buffer upload failed.");
return;
}
/* Add start to index offset, when rendering indexed */
index_offset += info->start * info->index_size;
index_offset += draws[0].start * info->index_size;
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo = etna_resource(indexbuf)->bo;
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.offset = index_offset;
@ -356,7 +358,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
}
}
ctx->stats.prims_generated += u_reduced_prims_for_vertices(info->mode, info->count);
ctx->stats.prims_generated += u_reduced_prims_for_vertices(info->mode, draws[0].count);
ctx->stats.draw_calls++;
/* Update state for this draw operation */
@ -368,12 +370,12 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (screen->specs.halti >= 2) {
/* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */
etna_draw_instanced(ctx->stream, info->index_size, draw_mode, info->instance_count,
info->count, info->index_size ? info->index_bias : info->start);
draws[0].count, info->index_size ? info->index_bias : draws[0].start);
} else {
if (info->index_size)
etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, info->index_bias);
else
etna_draw_primitives(ctx->stream, draw_mode, info->start, prims);
etna_draw_primitives(ctx->stream, draw_mode, draws[0].start, prims);
}
if (DBG_ENABLED(ETNA_DBG_DRAW_STALL)) {

View File

@ -80,11 +80,12 @@ emit_vertexbufs(struct fd_context *ctx)
static void
draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
struct fd_ringbuffer *ring, unsigned index_offset, bool binning)
{
OUT_PKT3(ring, CP_SET_CONSTANT, 2);
OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
OUT_RING(ring, info->index_size ? 0 : info->start);
OUT_RING(ring, info->index_size ? 0 : draw->start);
OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
@ -135,7 +136,7 @@ draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
vismode = IGNORE_VISIBILITY;
fd_draw_emit(ctx->batch, ring, ctx->primtypes[info->mode],
vismode, info, index_offset);
vismode, info, draw, index_offset);
if (is_a20x(ctx->screen)) {
/* not sure why this is required, but it fixes some hangs */
@ -153,6 +154,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,
const struct pipe_draw_start_count *pdraw,
unsigned index_offset)
{
if (!ctx->prog.fs || !ctx->prog.vs)
@ -171,7 +173,7 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *pinfo,
* using a limit of 32k because it fixes an unexplained hang
* 32766 works for all primitives (multiple of 2 and 3)
*/
if (pinfo->count > 32766) {
if (pdraw->count > 32766) {
static const uint16_t step_tbl[PIPE_PRIM_MAX] = {
[0 ... PIPE_PRIM_MAX - 1] = 32766,
[PIPE_PRIM_LINE_STRIP] = 32765,
@ -182,26 +184,26 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *pinfo,
[PIPE_PRIM_LINE_LOOP] = 0,
};
struct pipe_draw_info info = *pinfo;
unsigned count = info.count;
unsigned step = step_tbl[info.mode];
struct pipe_draw_start_count draw = *pdraw;
unsigned count = draw.count;
unsigned step = step_tbl[pinfo->mode];
unsigned num_vertices = ctx->batch->num_vertices;
if (!step)
return false;
for (; count + step > 32766; count -= step) {
info.count = MIN2(count, 32766);
draw_impl(ctx, &info, ctx->batch->draw, index_offset, false);
draw_impl(ctx, &info, ctx->batch->binning, index_offset, true);
info.start += step;
draw.count = MIN2(count, 32766);
draw_impl(ctx, pinfo, &draw, ctx->batch->draw, index_offset, false);
draw_impl(ctx, pinfo, &draw, ctx->batch->binning, index_offset, true);
draw.start += step;
ctx->batch->num_vertices += step;
}
/* changing this value is a hack, restore it */
ctx->batch->num_vertices = num_vertices;
} else {
draw_impl(ctx, pinfo, ctx->batch->draw, index_offset, false);
draw_impl(ctx, pinfo, ctx->batch->binning, index_offset, true);
draw_impl(ctx, pinfo, pdraw, ctx->batch->draw, index_offset, false);
draw_impl(ctx, pinfo, pdraw, ctx->batch->binning, index_offset, true);
}
fd_context_all_clean(ctx);

View File

@ -70,7 +70,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, add_sat(info->min_index, info->index_bias)); /* VFD_INDEX_MIN */
OUT_RING(ring, add_sat(info->max_index, info->index_bias)); /* VFD_INDEX_MAX */
OUT_RING(ring, info->start_instance); /* VFD_INSTANCEID_OFFSET */
OUT_RING(ring, info->index_size ? info->index_bias : info->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->index_size ? info->index_bias : emit->draw->start); /* VFD_INDEX_OFFSET */
OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
@ -84,7 +84,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
fd_draw_emit(ctx->batch, ring, primtype,
emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
info, index_offset);
info, emit->draw, index_offset);
}
/* fixup dirty shader state in case some "unrelated" (from the state-
@ -115,6 +115,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,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
struct fd3_context *fd3_ctx = fd3_context(ctx);
@ -124,6 +125,7 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
.prog = &ctx->prog,
.info = info,
.indirect = indirect,
.draw = draw,
.key = {
.color_two_side = ctx->rasterizer->light_twoside,
.vclamp_color = ctx->rasterizer->clamp_vertex_color,

View File

@ -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, emit->indirect);
ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect, emit->draw);
if (!emit->binning_pass)
ir3_emit_fs_consts(fp, ring, ctx);
}

View File

@ -47,6 +47,7 @@ struct fd3_emit {
const struct fd_program_stateobj *prog;
const struct pipe_draw_info *info;
const struct pipe_draw_indirect_info *indirect;
const struct pipe_draw_start_count *draw;
bool binning_pass;
struct ir3_shader_key key;
enum fd_dirty_3d_state dirty;

View File

@ -53,7 +53,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
fd4_emit_vertex_bufs(ring, emit);
OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
OUT_RING(ring, info->index_size ? info->index_bias : info->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->index_size ? info->index_bias : emit->draw->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->start_instance); /* ??? UNKNOWN_2209 */
OUT_PKT0(ring, REG_A4XX_PC_RESTART_INDEX, 1);
@ -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, emit->indirect, index_offset);
info, emit->indirect, emit->draw, index_offset);
}
/* fixup dirty shader state in case some "unrelated" (from the state-
@ -99,6 +99,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,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
struct fd4_context *fd4_ctx = fd4_context(ctx);
@ -108,6 +109,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
.prog = &ctx->prog,
.info = info,
.indirect = indirect,
.draw = draw,
.key = {
.color_two_side = ctx->rasterizer->light_twoside,
.vclamp_color = ctx->rasterizer->clamp_vertex_color,

View File

@ -91,6 +91,7 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
enum pc_di_vis_cull_mode vismode,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
struct pipe_resource *idx_buffer = NULL;
@ -132,8 +133,8 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
idx_buffer = info->index.resource;
idx_type = fd4_size2indextype(info->index_size);
idx_size = info->index_size * info->count;
idx_offset = index_offset + info->start * info->index_size;
idx_size = info->index_size * draw->count;
idx_offset = index_offset + draw->start * info->index_size;
src_sel = DI_SRC_SEL_DMA;
} else {
idx_buffer = NULL;
@ -144,7 +145,7 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
}
fd4_draw(batch, ring, primtype, vismode, src_sel,
info->count, info->instance_count,
draw->count, info->instance_count,
idx_type, idx_size, idx_offset, idx_buffer);
}

View File

@ -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, emit->indirect);
ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect, emit->draw);
if (!emit->binning_pass)
ir3_emit_fs_consts(fp, ring, ctx);
}

View File

@ -46,6 +46,7 @@ struct fd4_emit {
const struct fd_program_stateobj *prog;
const struct pipe_draw_info *info;
const struct pipe_draw_indirect_info *indirect;
const struct pipe_draw_start_count *draw;
bool binning_pass;
struct ir3_shader_key key;
enum fd_dirty_3d_state dirty;

View File

@ -53,7 +53,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
fd5_emit_vertex_bufs(ring, emit);
OUT_PKT4(ring, REG_A5XX_VFD_INDEX_OFFSET, 2);
OUT_RING(ring, info->index_size ? info->index_bias : info->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->index_size ? info->index_bias : emit->draw->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->start_instance); /* VFD_INSTANCE_START_OFFSET */
OUT_PKT4(ring, REG_A5XX_PC_RESTART_INDEX, 1);
@ -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, emit->indirect, index_offset);
info, emit->indirect, emit->draw, index_offset);
}
/* fixup dirty shader state in case some "unrelated" (from the state-
@ -94,6 +94,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,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
struct fd5_context *fd5_ctx = fd5_context(ctx);
@ -103,6 +104,7 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
.prog = &ctx->prog,
.info = info,
.indirect = indirect,
.draw = draw,
.key = {
.color_two_side = ctx->rasterizer->light_twoside,
.vclamp_color = ctx->rasterizer->clamp_vertex_color,

View File

@ -85,6 +85,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
enum pc_di_vis_cull_mode vismode,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
struct pipe_resource *idx_buffer = NULL;
@ -128,7 +129,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
idx_buffer = info->index.resource;
idx_type = fd4_size2indextype(info->index_size);
max_indices = idx_buffer->width0 / info->index_size;
idx_offset = index_offset + info->start * info->index_size;
idx_offset = index_offset + draw->start * info->index_size;
src_sel = DI_SRC_SEL_DMA;
} else {
idx_buffer = NULL;
@ -139,7 +140,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
}
fd5_draw(batch, ring, primtype, vismode, src_sel,
info->count, info->instance_count,
draw->count, info->instance_count,
idx_type, max_indices, idx_offset, idx_buffer);
}

View File

@ -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, emit->indirect);
ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect, emit->draw);
if (!emit->binning_pass)
ir3_emit_fs_consts(fp, ring, ctx);

View File

@ -46,6 +46,7 @@ struct fd5_emit {
const struct fd_program_stateobj *prog;
const struct pipe_draw_info *info;
const struct pipe_draw_indirect_info *indirect;
const struct pipe_draw_start_count *draw;
bool binning_pass;
struct ir3_shader_key key;
enum fd_dirty_3d_state dirty;

View File

@ -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, emit->indirect);
ir3_emit_vs_driver_params(vs, dpconstobj, ctx, emit->info, emit->indirect, emit->draw);
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) {

View File

@ -77,6 +77,7 @@ static void
draw_emit(struct fd_ringbuffer *ring,
struct CP_DRAW_INDX_OFFSET_0 *draw0,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
if (info->index_size) {
@ -88,8 +89,8 @@ draw_emit(struct fd_ringbuffer *ring,
OUT_PKT(ring, CP_DRAW_INDX_OFFSET,
pack_CP_DRAW_INDX_OFFSET_0(*draw0),
CP_DRAW_INDX_OFFSET_1(.num_instances = info->instance_count),
CP_DRAW_INDX_OFFSET_2(.num_indices = info->count),
CP_DRAW_INDX_OFFSET_3(.first_indx = info->start),
CP_DRAW_INDX_OFFSET_2(.num_indices = draw->count),
CP_DRAW_INDX_OFFSET_3(.first_indx = draw->start),
A5XX_CP_DRAW_INDX_OFFSET_INDX_BASE(
fd_resource(idx_buffer)->bo, index_offset),
A5XX_CP_DRAW_INDX_OFFSET_6(.max_indices = max_indices)
@ -98,7 +99,7 @@ draw_emit(struct fd_ringbuffer *ring,
OUT_PKT(ring, CP_DRAW_INDX_OFFSET,
pack_CP_DRAW_INDX_OFFSET_0(*draw0),
CP_DRAW_INDX_OFFSET_1(.num_instances = info->instance_count),
CP_DRAW_INDX_OFFSET_2(.num_indices = info->count)
CP_DRAW_INDX_OFFSET_2(.num_indices = draw->count)
);
}
}
@ -142,6 +143,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,
const struct pipe_draw_start_count *draw,
unsigned index_offset)
{
struct fd6_context *fd6_ctx = fd6_context(ctx);
@ -151,6 +153,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
.vtx = &ctx->vtx,
.info = info,
.indirect = indirect,
.draw = draw,
.key = {
.vs = ctx->prog.vs,
.gs = ctx->prog.gs,
@ -199,7 +202,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
emit.key.key.has_gs = true;
if (!(emit.key.hs || emit.key.ds || emit.key.gs || (indirect && indirect->buffer)))
fd6_vsc_update_sizes(ctx->batch, info);
fd6_vsc_update_sizes(ctx->batch, info, draw);
fixup_shader_state(ctx, &emit.key.key);
@ -270,9 +273,9 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
ctx->batch->tessellation = true;
ctx->batch->tessparam_size = MAX2(ctx->batch->tessparam_size,
emit.hs->output_size * 4 * info->count);
emit.hs->output_size * 4 * draw->count);
ctx->batch->tessfactor_size = MAX2(ctx->batch->tessfactor_size,
factor_stride * info->count);
factor_stride * draw->count);
if (!ctx->batch->tess_addrs_constobj) {
/* Reserve space for the bo address - we'll write them later in
@ -288,7 +291,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
}
}
uint32_t index_start = info->index_size ? info->index_bias : info->start;
uint32_t index_start = info->index_size ? info->index_bias : draw->start;
if (ctx->last.dirty || (ctx->last.index_start != index_start)) {
OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 1);
OUT_RING(ring, index_start); /* VFD_INDEX_OFFSET */
@ -321,7 +324,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
if (indirect && indirect->buffer) {
draw_emit_indirect(ring, &draw0, info, indirect, index_offset);
} else {
draw_emit(ring, &draw0, info, index_offset);
draw_emit(ring, &draw0, info, draw, index_offset);
}
emit_marker6(ring, 7);

View File

@ -87,6 +87,7 @@ struct fd6_emit {
const struct fd_vertex_state *vtx;
const struct pipe_draw_info *info;
const struct pipe_draw_indirect_info *indirect;
const struct pipe_draw_start_count *draw;
struct ir3_cache_key key;
enum fd_dirty_3d_state dirty;

View File

@ -63,12 +63,13 @@ bitfield_size_bits(unsigned n)
}
static unsigned
prim_count(const struct pipe_draw_info *info)
prim_count(const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
/* PIPE_PRIM_MAX used internally for RECTLIST blits on 3d pipe: */
unsigned vtx_per_prim = (info->mode == PIPE_PRIM_MAX) ? 2 :
u_vertices_per_prim(info->mode);
return (info->count * info->instance_count) / vtx_per_prim;
return (draw->count * info->instance_count) / vtx_per_prim;
}
/**
@ -87,9 +88,10 @@ prim_count(const struct pipe_draw_info *info)
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format#primitive-streams
*/
static unsigned
primitive_stream_size_bits(const struct pipe_draw_info *info, unsigned num_bins)
primitive_stream_size_bits(const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw, unsigned num_bins)
{
unsigned num_prims = prim_count(info);
unsigned num_prims = prim_count(info, draw);
unsigned nbits =
(bitfield_size_bits(num_bins) /* bitfield of bins covered */
+ number_size_bits(1) /* number of primitives with this bitset */
@ -122,7 +124,8 @@ draw_stream_size_bits(const struct pipe_draw_info *info, unsigned num_bins,
}
void
fd6_vsc_update_sizes(struct fd_batch *batch, const struct pipe_draw_info *info)
fd6_vsc_update_sizes(struct fd_batch *batch, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
if (!batch->num_bins_per_pipe) {
batch->num_bins_per_pipe = fd_gmem_estimate_bins_per_pipe(batch);
@ -140,7 +143,7 @@ fd6_vsc_update_sizes(struct fd_batch *batch, const struct pipe_draw_info *info)
}
unsigned prim_strm_bits =
primitive_stream_size_bits(info, batch->num_bins_per_pipe);
primitive_stream_size_bits(info, draw, batch->num_bins_per_pipe);
unsigned draw_strm_bits =
draw_stream_size_bits(info, batch->num_bins_per_pipe, prim_strm_bits);

View File

@ -24,6 +24,7 @@
#ifndef FD6_VSC_H_
#define FD6_VSC_H_
void fd6_vsc_update_sizes(struct fd_batch *batch, const struct pipe_draw_info *info);
void fd6_vsc_update_sizes(struct fd_batch *batch, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw);
#endif /* FD6_VSC_H_ */

View File

@ -234,11 +234,13 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers,
struct pipe_draw_info info = {
.mode = PIPE_PRIM_MAX, /* maps to DI_PT_RECTLIST */
.count = 2,
.max_index = 1,
.instance_count = 1,
};
pctx->draw_vbo(pctx, &info, NULL);
struct pipe_draw_start_count draw = {
.count = 2,
};
pctx->draw_vbo(pctx, &info, NULL, &draw, 1);
/* We expect that this should not have triggered a change in pfb: */
assert(util_framebuffer_state_equal(pfb, &ctx->framebuffer));

View File

@ -391,6 +391,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,
const struct pipe_draw_start_count *draw,
unsigned index_offset);
bool (*clear)(struct fd_context *ctx, unsigned buffers,
const union pipe_color_union *color, double depth, unsigned stencil);

View File

@ -212,7 +212,9 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct fd_context *ctx = fd_context(pctx);
@ -228,7 +230,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (info->mode != PIPE_PRIM_MAX &&
!indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
/* TODO: push down the region versions into the tiles */
@ -240,7 +242,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (ctx->streamout.num_targets > 0)
mesa_loge("stream-out with emulated prims");
util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
util_primconvert_draw_vbo(ctx->primconvert, info);
util_primconvert_draw_vbo(ctx->primconvert, info, &draws[0]);
return;
}
@ -250,7 +252,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
struct pipe_draw_info new_info;
if (info->index_size) {
if (info->has_user_indices) {
if (!util_upload_index_buffer(pctx, info, &indexbuf, &index_offset, 4))
if (!util_upload_index_buffer(pctx, info, &draws[0],
&indexbuf, &index_offset, 4))
return;
new_info = *info;
new_info.index.resource = indexbuf;
@ -292,7 +295,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
unsigned prims;
if ((info->mode != PIPE_PRIM_PATCHES) &&
(info->mode != PIPE_PRIM_MAX))
prims = u_reduced_prims_for_vertices(info->mode, info->count);
prims = u_reduced_prims_for_vertices(info->mode, draws[0].count);
else
prims = 0;
@ -320,13 +323,13 @@ 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, indirect, index_offset))
if (ctx->draw_vbo(ctx, info, indirect, &draws[0], index_offset))
batch->needs_flush = true;
batch->num_vertices += info->count * info->instance_count;
batch->num_vertices += draws[0].count * info->instance_count;
for (unsigned i = 0; i < ctx->streamout.num_targets; i++)
ctx->streamout.offsets[i] += info->count;
ctx->streamout.offsets[i] += draws[0].count;
if (fd_mesa_debug & FD_DBG_DDRAW)
fd_context_all_dirty(ctx);

View File

@ -145,6 +145,7 @@ fd_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_start_count *draw,
unsigned index_offset)
{
struct pipe_resource *idx_buffer = NULL;
@ -157,8 +158,8 @@ fd_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
idx_buffer = info->index.resource;
idx_type = size2indextype(info->index_size);
idx_size = info->index_size * info->count;
idx_offset = index_offset + info->start * info->index_size;
idx_size = info->index_size * draw->count;
idx_offset = index_offset + draw->start * info->index_size;
src_sel = DI_SRC_SEL_DMA;
} else {
idx_buffer = NULL;
@ -169,7 +170,7 @@ fd_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
}
fd_draw(batch, ring, primtype, vismode, src_sel,
info->count, info->instance_count - 1,
draw->count, info->instance_count - 1,
idx_type, idx_size, idx_offset, idx_buffer);
}

View File

@ -515,7 +515,8 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
debug_assert(ir3_needs_vs_driver_params(v));
@ -524,7 +525,7 @@ ir3_emit_vs_driver_params(const struct ir3_shader_variant *v,
uint32_t vertex_params[IR3_DP_VS_COUNT] = {
[IR3_DP_DRAWID] = 0, /* filled by hw (CP_DRAW_INDIRECT_MULTI) */
[IR3_DP_VTXID_BASE] = info->index_size ?
info->index_bias : info->start,
info->index_bias : draw->start,
[IR3_DP_INSTID_BASE] = info->start_instance,
[IR3_DP_VTXCNT_MAX] = max_tf_vtx(ctx, v),
};
@ -597,7 +598,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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
debug_assert(v->type == MESA_SHADER_VERTEX);
@ -606,7 +608,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, indirect);
ir3_emit_vs_driver_params(v, ring, ctx, info, indirect, draw);
}
}

View File

@ -52,14 +52,16 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
const void *mapped_indices = NULL;
unsigned i;
if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
if (!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
/*
@ -110,7 +112,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
/*
* Do the drawing
*/
draw_vbo(i915->draw, info, NULL);
draw_vbo(i915->draw, info, NULL, draws, num_draws);
/*
* unmap vertex/index buffers

View File

@ -823,7 +823,9 @@ 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,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
void iris_launch_grid(struct pipe_context *, const struct pipe_grid_info *);
/* iris_pipe_control.c */

View File

@ -112,7 +112,8 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
bool changed = false;
@ -127,7 +128,7 @@ iris_update_draw_parameters(struct iris_context *ice,
changed = true;
ice->draw.params_valid = false;
} else {
int firstvertex = info->index_size ? info->index_bias : info->start;
int firstvertex = info->index_size ? info->index_bias : draw->start;
if (!ice->draw.params_valid ||
ice->draw.params.firstvertex != firstvertex ||
@ -173,7 +174,8 @@ 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_indirect_info *dindirect)
const struct pipe_draw_indirect_info *dindirect,
const struct pipe_draw_start_count *draw)
{
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
struct pipe_draw_info info = *dinfo;
@ -193,9 +195,9 @@ iris_indirect_draw_vbo(struct iris_context *ice,
iris_batch_maybe_flush(batch, 1500);
iris_update_draw_parameters(ice, &info, &indirect);
iris_update_draw_parameters(ice, &info, &indirect, draw);
batch->screen->vtbl.upload_render_state(ice, batch, &info, &indirect);
batch->screen->vtbl.upload_render_state(ice, batch, &info, &indirect, draw);
ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
@ -217,15 +219,16 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *sc)
{
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
iris_batch_maybe_flush(batch, 1500);
iris_update_draw_parameters(ice, draw, indirect);
iris_update_draw_parameters(ice, draw, indirect, sc);
batch->screen->vtbl.upload_render_state(ice, batch, draw, indirect);
batch->screen->vtbl.upload_render_state(ice, batch, draw, indirect, sc);
}
/**
@ -233,7 +236,9 @@ iris_simple_draw_vbo(struct iris_context *ice,
*/
void
iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct iris_context *ice = (struct iris_context *) ctx;
struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen;
@ -275,9 +280,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, indirect);
iris_indirect_draw_vbo(ice, info, indirect, &draws[0]);
else
iris_simple_draw_vbo(ice, info, indirect);
iris_simple_draw_vbo(ice, info, indirect, &draws[0]);
iris_handle_always_flush_cache(batch);

View File

@ -61,7 +61,8 @@ struct iris_vtable {
void (*upload_render_state)(struct iris_context *ice,
struct iris_batch *batch,
const struct pipe_draw_info *draw,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *sc);
void (*update_surface_base_address)(struct iris_batch *batch,
struct iris_binder *binder);
void (*upload_compute_state)(struct iris_context *ice,

View File

@ -6418,7 +6418,8 @@ static void
iris_upload_render_state(struct iris_context *ice,
struct iris_batch *batch,
const struct pipe_draw_info *draw,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *sc)
{
bool use_predicate = ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT;
@ -6444,7 +6445,7 @@ iris_upload_render_state(struct iris_context *ice,
if (draw->has_user_indices) {
u_upload_data(ice->ctx.stream_uploader, 0,
draw->count * draw->index_size, 4, draw->index.user,
sc->count * draw->index_size, 4, draw->index.user,
&offset, &ice->state.last_res.index_buffer);
} else {
struct iris_resource *res = (void *) draw->index.resource;
@ -6621,9 +6622,9 @@ iris_upload_render_state(struct iris_context *ice,
} else {
prim.StartInstanceLocation = draw->start_instance;
prim.InstanceCount = draw->instance_count;
prim.VertexCountPerInstance = draw->count;
prim.VertexCountPerInstance = sc->count;
prim.StartVertexLocation = draw->start;
prim.StartVertexLocation = sc->start;
if (draw->index_size) {
prim.BaseVertexLocation += draw->index_bias;

View File

@ -265,7 +265,8 @@ lima_pipe_format_to_attrib_type(enum pipe_format format)
}
static void
lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct lima_context_constant_buffer *ccb =
ctx->const_buffer + PIPE_SHADER_VERTEX;
@ -302,7 +303,7 @@ lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_varying_info),
num_outputs);
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : info->count;
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : draw->count;
VS_CMD_DRAW(num, info->index_size);
VS_CMD_UNKNOWN2();
@ -313,7 +314,8 @@ lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
}
static void
lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct lima_vs_shader_state *vs = ctx->vs;
struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
@ -383,17 +385,17 @@ lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
if (vs->point_size_idx != -1)
PLBU_CMD_INDEXED_PT_SIZE(ctx->gp_output->va + ctx->gp_output_point_size_offt);
PLBU_CMD_INDICES(ctx->index_res->bo->va + info->start * info->index_size + ctx->index_offset);
PLBU_CMD_INDICES(ctx->index_res->bo->va + draw->start * info->index_size + ctx->index_offset);
}
else {
/* can this make the attribute info static? */
PLBU_CMD_DRAW_ARRAYS(info->mode, info->start, info->count);
PLBU_CMD_DRAW_ARRAYS(info->mode, draw->start, draw->count);
}
PLBU_CMD_ARRAYS_SEMAPHORE_END();
if (info->index_size)
PLBU_CMD_DRAW_ELEMENTS(info->mode, ctx->min_index, info->count);
PLBU_CMD_DRAW_ELEMENTS(info->mode, ctx->min_index, draw->count);
PLBU_CMD_END();
}
@ -799,7 +801,8 @@ lima_pack_render_state(struct lima_context *ctx, const struct pipe_draw_info *in
}
static void
lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_info *info)
lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct lima_job *job = lima_job_get(ctx);
struct lima_vertex_element_state *ve = ctx->vertex_elements;
@ -821,7 +824,7 @@ lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_i
lima_job_add_bo(job, LIMA_PIPE_GP, res->bo, LIMA_SUBMIT_BO_READ);
unsigned start = info->index_size ? (ctx->min_index + info->index_bias) : info->start;
unsigned start = info->index_size ? (ctx->min_index + info->index_bias) : draw->start;
attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
+ start * pvb->stride;
attribute[n++] = (pvb->stride << 11) |
@ -914,13 +917,14 @@ lima_update_pp_uniform(struct lima_context *ctx)
}
static void
lima_update_varying(struct lima_context *ctx, const struct pipe_draw_info *info)
lima_update_varying(struct lima_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct lima_job *job = lima_job_get(ctx);
struct lima_screen *screen = lima_screen(ctx->base.screen);
struct lima_vs_shader_state *vs = ctx->vs;
uint32_t gp_output_size;
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : info->count;
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : draw->count;
uint32_t *varying =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_varying_info,
@ -998,7 +1002,8 @@ lima_update_varying(struct lima_context *ctx, const struct pipe_draw_info *info)
static void
lima_draw_vbo_update(struct pipe_context *pctx,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct lima_context *ctx = lima_context(pctx);
struct lima_context_framebuffer *fb = &ctx->framebuffer;
@ -1017,7 +1022,7 @@ lima_draw_vbo_update(struct pipe_context *pctx,
lima_update_job_wb(ctx, buffers);
lima_update_gp_attribute_info(ctx, info);
lima_update_gp_attribute_info(ctx, info, draw);
if ((ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
ctx->const_buffer[PIPE_SHADER_VERTEX].dirty) ||
@ -1027,9 +1032,9 @@ lima_draw_vbo_update(struct pipe_context *pctx,
ctx->const_buffer[PIPE_SHADER_VERTEX].dirty = false;
}
lima_update_varying(ctx, info);
lima_update_varying(ctx, info, draw);
lima_pack_vs_cmd(ctx, info);
lima_pack_vs_cmd(ctx, info, draw);
if (ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
ctx->const_buffer[PIPE_SHADER_FRAGMENT].dirty) {
@ -1040,7 +1045,7 @@ lima_draw_vbo_update(struct pipe_context *pctx,
lima_update_textures(ctx);
lima_pack_render_state(ctx, info);
lima_pack_plbu_cmd(ctx, info);
lima_pack_plbu_cmd(ctx, info, draw);
if (ctx->gp_output) {
lima_bo_unreference(ctx->gp_output); /* held by job */
@ -1052,7 +1057,8 @@ lima_draw_vbo_update(struct pipe_context *pctx,
static void
lima_draw_vbo_indexed(struct pipe_context *pctx,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct lima_context *ctx = lima_context(pctx);
struct lima_job *job = lima_job_get(ctx);
@ -1068,26 +1074,26 @@ lima_draw_vbo_indexed(struct pipe_context *pctx,
}
if (info->has_user_indices) {
util_upload_index_buffer(&ctx->base, info, &indexbuf, &ctx->index_offset, 0x40);
util_upload_index_buffer(&ctx->base, info, draw, &indexbuf, &ctx->index_offset, 0x40);
ctx->index_res = lima_resource(indexbuf);
}
else {
ctx->index_res = lima_resource(info->index.resource);
ctx->index_offset = 0;
needs_indices = !panfrost_minmax_cache_get(ctx->index_res->index_cache, info->start,
info->count, &ctx->min_index, &ctx->max_index);
needs_indices = !panfrost_minmax_cache_get(ctx->index_res->index_cache, draw->start,
draw->count, &ctx->min_index, &ctx->max_index);
}
if (needs_indices) {
u_vbuf_get_minmax_index(pctx, info, &ctx->min_index, &ctx->max_index);
u_vbuf_get_minmax_index(pctx, info, draw, &ctx->min_index, &ctx->max_index);
if (!info->has_user_indices)
panfrost_minmax_cache_add(ctx->index_res->index_cache, info->start, info->count,
panfrost_minmax_cache_add(ctx->index_res->index_cache, draw->start, draw->count,
ctx->min_index, ctx->max_index);
}
lima_job_add_bo(job, LIMA_PIPE_GP, ctx->index_res->bo, LIMA_SUBMIT_BO_READ);
lima_job_add_bo(job, LIMA_PIPE_PP, ctx->index_res->bo, LIMA_SUBMIT_BO_READ);
lima_draw_vbo_update(pctx, info);
lima_draw_vbo_update(pctx, info, draw);
if (indexbuf)
pipe_resource_reference(&indexbuf, NULL);
@ -1095,13 +1101,14 @@ lima_draw_vbo_indexed(struct pipe_context *pctx,
static void
lima_draw_vbo_count(struct pipe_context *pctx,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
static const uint32_t max_verts = 65535;
struct pipe_draw_info local_info = *info;
unsigned start = info->start;
unsigned count = info->count;
struct pipe_draw_start_count local_draw = *draw;
unsigned start = draw->start;
unsigned count = draw->count;
while (count) {
unsigned this_count = count;
@ -1109,10 +1116,10 @@ lima_draw_vbo_count(struct pipe_context *pctx,
u_split_draw(info, max_verts, &this_count, &step);
local_info.start = start;
local_info.count = this_count;
local_draw.start = start;
local_draw.count = this_count;
lima_draw_vbo_update(pctx, &local_info);
lima_draw_vbo_update(pctx, info, &local_draw);
count -= step;
start += step;
@ -1122,11 +1129,13 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
/* check if draw mode and vertex/index count match,
* otherwise gp will hang */
if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) {
if (!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count)) {
debug_printf("draw mode and vertex/index count mismatch\n");
return;
}
@ -1159,9 +1168,9 @@ lima_draw_vbo(struct pipe_context *pctx,
lima_job_add_bo(job, LIMA_PIPE_PP, ctx->fs->bo, LIMA_SUBMIT_BO_READ);
if (info->index_size)
lima_draw_vbo_indexed(pctx, info);
lima_draw_vbo_indexed(pctx, info, &draws[0]);
else
lima_draw_vbo_count(pctx, info);
lima_draw_vbo_count(pctx, info, &draws[0]);
}
void

View File

@ -52,7 +52,9 @@
*/
static void
llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct llvmpipe_context *lp = llvmpipe_context(pipe);
struct draw_context *draw = lp->draw;
@ -140,7 +142,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
!lp->queries_disabled);
/* draw! */
draw_vbo(draw, info, indirect);
draw_vbo(draw, info, indirect, draws, num_draws);
/*
* unmap vertex/index buffers

View File

@ -195,13 +195,15 @@ nv30_fragtex_set_sampler_views(struct pipe_context *pipe,
unsigned nr, struct pipe_sampler_view **views);
void
nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info);
nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw);
void
nv30_draw_init(struct pipe_context *pipe);
void
nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info);
nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw);
bool
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl);

View File

@ -376,7 +376,8 @@ nv30_render_validate(struct nv30_context *nv30)
}
void
nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw_one)
{
struct nv30_context *nv30 = nv30_context(pipe);
struct draw_context *draw = nv30->draw;
@ -443,7 +444,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, NULL);
draw_vbo(draw, info, NULL, draw_one, 1);
draw_flush(draw);
if (info->index_size && transferi)

View File

@ -195,7 +195,8 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
}
void
nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct push_context ctx;
unsigned i, index_size;
@ -227,7 +228,7 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
if (info->index_size) {
if (!info->has_user_indices)
ctx.idxbuf = nouveau_resource_map_offset(&nv30->base,
nv04_resource(info->index.resource), info->start * info->index_size,
nv04_resource(info->index.resource), draw->start * info->index_size,
NOUVEAU_BO_RD);
else
ctx.idxbuf = info->index.user;
@ -259,16 +260,16 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
PUSH_DATA (ctx.push, ctx.prim);
switch (index_size) {
case 0:
emit_vertices_seq(&ctx, info->start, info->count);
emit_vertices_seq(&ctx, draw->start, draw->count);
break;
case 1:
emit_vertices_i08(&ctx, info->start, info->count);
emit_vertices_i08(&ctx, draw->start, draw->count);
break;
case 2:
emit_vertices_i16(&ctx, info->start, info->count);
emit_vertices_i16(&ctx, draw->start, draw->count);
break;
case 4:
emit_vertices_i32(&ctx, info->start, info->count);
emit_vertices_i32(&ctx, draw->start, draw->count);
break;
default:
assert(0);

View File

@ -545,14 +545,16 @@ nv30_draw_elements(struct nv30_context *nv30, bool shorten,
static void
nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct nv30_context *nv30 = nv30_context(pipe);
struct nouveau_pushbuf *push = nv30->base.pushbuf;
int i;
if (!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
/* For picking only a few vertices from a large user buffer, push is better,
@ -560,7 +562,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
*/
nv30->vbo_push_hint = /* the 64 is heuristic */
!(info->index_size &&
((info->max_index - info->min_index + 64) < info->count));
((info->max_index - info->min_index + 64) < draws[0].count));
nv30->vbo_min_index = info->min_index;
nv30->vbo_max_index = info->max_index;
@ -574,11 +576,11 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
nv30_state_validate(nv30, ~0, true);
if (nv30->draw_flags) {
nv30_render_vbo(pipe, info);
nv30_render_vbo(pipe, info, &draws[0]);
return;
} else
if (nv30->vbo_fifo) {
nv30_push_vbo(nv30, info);
nv30_push_vbo(nv30, info, &draws[0]);
return;
}
@ -601,7 +603,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
if (!info->index_size) {
nv30_draw_arrays(nv30,
info->mode, info->start, info->count,
info->mode, draws[0].start, draws[0].count,
info->instance_count);
} else {
bool shorten = info->max_index <= 65535;
@ -629,7 +631,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
nv30_draw_elements(nv30, shorten, info,
info->mode, info->start, info->count,
info->mode, draws[0].start, draws[0].count,
info->instance_count, info->index_bias, info->index_size);
}

View File

@ -292,7 +292,9 @@ nv50_cb_push(struct nouveau_context *nv,
/* nv50_vbo.c */
void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
void *
nv50_vertex_state_create(struct pipe_context *pipe,
@ -305,7 +307,8 @@ void nv50_vertex_arrays_validate(struct nv50_context *nv50);
/* nv50_push.c */
void nv50_push_vbo(struct nv50_context *, const struct pipe_draw_info *,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw);
/* nv84_video.c */
struct pipe_video_codec *

View File

@ -239,12 +239,13 @@ nv50_prim_gl(unsigned prim)
void
nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
struct push_context ctx;
unsigned i, index_size;
unsigned inst_count = info->instance_count;
unsigned vert_count = info->count;
unsigned vert_count = draw->count;
bool apply_bias = info->index_size && info->index_bias;
ctx.push = nv50->base.pushbuf;
@ -329,16 +330,16 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
PUSH_DATA (ctx.push, ctx.prim);
switch (index_size) {
case 0:
emit_vertices_seq(&ctx, info->start, vert_count);
emit_vertices_seq(&ctx, draw->start, vert_count);
break;
case 1:
emit_vertices_i08(&ctx, info->start, vert_count);
emit_vertices_i08(&ctx, draw->start, vert_count);
break;
case 2:
emit_vertices_i16(&ctx, info->start, vert_count);
emit_vertices_i16(&ctx, draw->start, vert_count);
break;
case 4:
emit_vertices_i32(&ctx, info->start, vert_count);
emit_vertices_i32(&ctx, draw->start, vert_count);
break;
default:
assert(0);

View File

@ -755,7 +755,9 @@ nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
void
nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_pushbuf *push = nv50->base.pushbuf;
@ -775,7 +777,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
* if index count is larger and we expect repeated vertices, suggest upload.
*/
nv50->vbo_push_hint = /* the 64 is heuristic */
!(info->index_size && ((nv50->vb_elt_limit + 64) < info->count));
!(info->index_size && ((nv50->vb_elt_limit + 64) < draws[0].count));
if (nv50->vbo_user && !(nv50->dirty_3d & (NV50_NEW_3D_ARRAYS | NV50_NEW_3D_VERTEX))) {
if (!!nv50->vbo_fifo != nv50->vbo_push_hint)
@ -828,7 +830,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
if (nv50->vbo_fifo) {
nv50_push_vbo(nv50, info, indirect);
nv50_push_vbo(nv50, info, indirect, &draws[0]);
goto cleanup;
}
@ -873,14 +875,14 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
nv50_draw_elements(nv50, shorten, info,
info->mode, info->start, info->count,
info->mode, draws[0].start, draws[0].count,
info->instance_count, info->index_bias, info->index_size);
} else
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,
info->mode, draws[0].start, draws[0].count,
info->instance_count);
}

View File

@ -414,7 +414,9 @@ nvc0_cb_bo_push(struct nouveau_context *,
/* nvc0_vbo.c */
void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
void *
nvc0_vertex_state_create(struct pipe_context *pipe,
@ -438,9 +440,11 @@ nvc0_video_buffer_create(struct pipe_context *pipe,
/* nvc0_push.c */
void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw);
void nvc0_push_vbo_indirect(struct nvc0_context *, const struct pipe_draw_info *,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw);
/* nve4_compute.c */
void nve4_launch_grid(struct pipe_context *, const struct pipe_grid_info *);

View File

@ -923,7 +923,9 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
@ -942,7 +944,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
*/
nvc0->vbo_push_hint =
(!indirect || indirect->count_from_stream_output) && info->index_size &&
(nvc0->vb_elt_limit >= (info->count * 2));
(nvc0->vb_elt_limit >= (draws[0].count * 2));
/* Check whether we want to switch vertex-submission mode. */
if (nvc0->vbo_user && !(nvc0->dirty_3d & (NVC0_NEW_3D_ARRAYS | NVC0_NEW_3D_VERTEX))) {
@ -1061,9 +1063,9 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
if (nvc0->state.vbo_mode) {
if (indirect && indirect->buffer)
nvc0_push_vbo_indirect(nvc0, info, indirect);
nvc0_push_vbo_indirect(nvc0, info, indirect, &draws[0]);
else
nvc0_push_vbo(nvc0, info, indirect);
nvc0_push_vbo(nvc0, info, indirect, &draws[0]);
goto cleanup;
}
@ -1104,11 +1106,11 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
shorten = false;
nvc0_draw_elements(nvc0, shorten, info,
info->mode, info->start, info->count,
info->mode, draws[0].start, draws[0].count,
info->instance_count, info->index_bias, info->index_size);
} else {
nvc0_draw_arrays(nvc0,
info->mode, info->start, info->count,
info->mode, draws[0].start, draws[0].count,
info->instance_count);
}

View File

@ -36,7 +36,8 @@ struct push_context {
static void nvc0_push_upload_vertex_ids(struct push_context *,
struct nvc0_context *,
const struct pipe_draw_info *);
const struct pipe_draw_info *,
const struct pipe_draw_start_count *draw);
static void
nvc0_push_context_init(struct nvc0_context *nvc0, struct push_context *ctx)
@ -491,7 +492,8 @@ typedef struct {
void
nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
/* 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
@ -514,18 +516,19 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i
uint8_t *buf_data = nouveau_resource_map_offset(
&nvc0->base, buf, indirect->offset, NOUVEAU_BO_RD);
struct pipe_draw_info single = *info;
struct pipe_draw_start_count sdraw = *draw;
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;
single.count = cmd->count;
sdraw.start = draw->start + cmd->firstIndex;
sdraw.count = cmd->count;
single.start_instance = cmd->baseInstance;
single.instance_count = cmd->primCount;
single.index_bias = cmd->baseVertex;
} else {
DrawArraysIndirectCommand *cmd = (void *)buf_data;
single.start = cmd->first;
single.count = cmd->count;
sdraw.start = cmd->first;
sdraw.count = cmd->count;
single.start_instance = cmd->baseInstance;
single.instance_count = cmd->primCount;
}
@ -543,7 +546,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, NULL);
nvc0_push_vbo(nvc0, &single, NULL, &sdraw);
}
nouveau_resource_unmap(buf);
@ -553,12 +556,13 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
struct push_context ctx;
unsigned i, index_size;
unsigned inst_count = info->instance_count;
unsigned vert_count = info->count;
unsigned vert_count = draw->count;
unsigned prim;
nvc0_push_context_init(nvc0, &ctx);
@ -619,7 +623,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
break;
if (unlikely(ctx.need_vertex_id))
nvc0_push_upload_vertex_ids(&ctx, nvc0, info);
nvc0_push_upload_vertex_ids(&ctx, nvc0, info, draw);
if (nvc0->screen->eng3d->oclass < GM107_3D_CLASS)
IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
@ -627,17 +631,17 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
PUSH_DATA (ctx.push, prim);
switch (index_size) {
case 1:
disp_vertices_i08(&ctx, info->start, vert_count);
disp_vertices_i08(&ctx, draw->start, vert_count);
break;
case 2:
disp_vertices_i16(&ctx, info->start, vert_count);
disp_vertices_i16(&ctx, draw->start, vert_count);
break;
case 4:
disp_vertices_i32(&ctx, info->start, vert_count);
disp_vertices_i32(&ctx, draw->start, vert_count);
break;
default:
assert(index_size == 0);
disp_vertices_seq(&ctx, info->start, vert_count);
disp_vertices_seq(&ctx, draw->start, vert_count);
break;
}
PUSH_SPACE(ctx.push, 1);
@ -705,7 +709,8 @@ copy_indices_u32(uint32_t *dst, const uint32_t *elts, uint32_t bias, unsigned n)
static void
nvc0_push_upload_vertex_ids(struct push_context *ctx,
struct nvc0_context *nvc0,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct nouveau_pushbuf *push = ctx->push;
@ -720,7 +725,7 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
if (!index_size || info->index_bias)
index_size = 4;
data = (uint32_t *)nouveau_scratch_get(&nvc0->base,
info->count * index_size, &va, &bo);
draw->count * index_size, &va, &bo);
BCTX_REFN_bo(nvc0->bufctx_3d, 3D_VTX_TMP, NOUVEAU_BO_GART | NOUVEAU_BO_RD,
bo);
@ -728,23 +733,23 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
if (info->index_size) {
if (!info->index_bias) {
memcpy(data, ctx->idxbuf, info->count * index_size);
memcpy(data, ctx->idxbuf, draw->count * index_size);
} else {
switch (info->index_size) {
case 1:
copy_indices_u8(data, ctx->idxbuf, info->index_bias, info->count);
copy_indices_u8(data, ctx->idxbuf, info->index_bias, draw->count);
break;
case 2:
copy_indices_u16(data, ctx->idxbuf, info->index_bias, info->count);
copy_indices_u16(data, ctx->idxbuf, info->index_bias, draw->count);
break;
default:
copy_indices_u32(data, ctx->idxbuf, info->index_bias, info->count);
copy_indices_u32(data, ctx->idxbuf, info->index_bias, draw->count);
break;
}
}
} else {
for (i = 0; i < info->count; ++i)
data[i] = i + (info->start + info->index_bias);
for (i = 0; i < draw->count; ++i)
data[i] = i + (draw->start + info->index_bias);
}
format = (1 << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
@ -781,8 +786,8 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_LIMIT_HIGH(1)), 2);
else
BEGIN_NVC0(push, SUBC_3D(TU102_3D_VERTEX_ARRAY_LIMIT_HIGH(1)), 2);
PUSH_DATAh(push, va + info->count * index_size - 1);
PUSH_DATA (push, va + info->count * index_size - 1);
PUSH_DATAh(push, va + draw->count * index_size - 1);
PUSH_DATA (push, va + draw->count * index_size - 1);
#define NVC0_3D_VERTEX_ID_REPLACE_SOURCE_ATTR_X(a) \
(((0x80 + (a) * 0x10) / 4) << NVC0_3D_VERTEX_ID_REPLACE_SOURCE__SHIFT)

View File

@ -61,11 +61,12 @@ panfrost_bo_access_for_stage(enum pipe_shader_type stage)
mali_ptr
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned *min_index, unsigned *max_index)
{
struct panfrost_resource *rsrc = pan_resource(info->index.resource);
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
off_t offset = info->start * info->index_size;
off_t offset = draw->start * info->index_size;
bool needs_indices = true;
mali_ptr out = 0;
@ -85,8 +86,8 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
/* Check the cache */
needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache,
info->start,
info->count,
draw->start,
draw->count,
min_index,
max_index);
} else {
@ -94,20 +95,20 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
struct panfrost_ptr T =
panfrost_pool_alloc_aligned(&batch->pool,
info->count * info->index_size,
draw->count * info->index_size,
info->index_size);
memcpy(T.cpu, ibuf8 + offset, info->count * info->index_size);
memcpy(T.cpu, ibuf8 + offset, draw->count * info->index_size);
out = T.gpu;
}
if (needs_indices) {
/* Fallback */
u_vbuf_get_minmax_index(&ctx->base, info, min_index, max_index);
u_vbuf_get_minmax_index(&ctx->base, info, draw, min_index, max_index);
if (!info->has_user_indices)
panfrost_minmax_cache_add(rsrc->index_cache,
info->start, info->count,
draw->start, draw->count,
*min_index, *max_index);
}

View File

@ -68,6 +68,7 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
mali_ptr
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned *min_index, unsigned *max_index);
void

View File

@ -228,12 +228,13 @@ panfrost_scissor_culls_everything(struct panfrost_context *ctx)
static void
panfrost_statistics_record(
struct panfrost_context *ctx,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
if (!ctx->active_queries)
return;
uint32_t prims = u_prims_for_vertices(info->mode, info->count);
uint32_t prims = u_prims_for_vertices(info->mode, draw->count);
ctx->prims_generated += prims;
if (!ctx->streamout.num_targets)
@ -331,6 +332,7 @@ static void
panfrost_draw_emit_tiler(struct panfrost_batch *batch,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw,
void *invocation_template,
mali_ptr shared_mem, mali_ptr indices,
mali_ptr fs_vary, mali_ptr varyings,
@ -362,7 +364,7 @@ panfrost_draw_emit_tiler(struct panfrost_batch *batch,
cfg.index_type = panfrost_translate_index_size(info->index_size);
cfg.indices = indices;
cfg.base_vertex_offset = info->index_bias - ctx->offset_start;
cfg.index_count = info->count;
cfg.index_count = draw->count;
} else {
cfg.index_count = indirect && indirect->count_from_stream_output ?
pan_so_target(indirect->count_from_stream_output)->offset :
@ -424,7 +426,9 @@ static void
panfrost_draw_vbo(
struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct panfrost_context *ctx = pan_context(pipe);
struct panfrost_device *device = pan_device(ctx->base.screen);
@ -443,7 +447,7 @@ panfrost_draw_vbo(
if (info->primitive_restart && info->index_size
&& info->restart_index != primitive_index) {
util_draw_vbo_without_prim_restart(pipe, info, indirect);
util_draw_vbo_without_prim_restart(pipe, info, indirect, &draws[0]);
return;
}
@ -452,13 +456,13 @@ panfrost_draw_vbo(
assert(ctx->rasterizer != NULL);
if (!(ctx->draw_modes & (1 << mode))) {
if (info->count < 4) {
if (draws[0].count < 4) {
/* Degenerate case? */
return;
}
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base);
util_primconvert_draw_vbo(ctx->primconvert, info);
util_primconvert_draw_vbo(ctx->primconvert, info, &draws[0]);
return;
}
@ -468,7 +472,7 @@ panfrost_draw_vbo(
panfrost_batch_set_requirements(batch);
/* Take into account a negative bias */
ctx->vertex_count = info->count + abs(info->index_bias);
ctx->vertex_count = draws[0].count + abs(info->index_bias);
ctx->instance_count = info->instance_count;
ctx->active_prim = info->mode;
@ -492,7 +496,7 @@ panfrost_draw_vbo(
mali_ptr indices = 0;
if (info->index_size) {
indices = panfrost_get_index_buffer_bounded(ctx, info,
indices = panfrost_get_index_buffer_bounded(ctx, info, &draws[0],
&min_index,
&max_index);
@ -500,7 +504,7 @@ panfrost_draw_vbo(
vertex_count = max_index - min_index + 1;
ctx->offset_start = min_index + info->index_bias;
} else {
ctx->offset_start = info->start;
ctx->offset_start = draws[0].start;
}
/* Encode the padded vertex count */
@ -510,7 +514,7 @@ panfrost_draw_vbo(
else
ctx->padded_count = vertex_count;
panfrost_statistics_record(ctx, info);
panfrost_statistics_record(ctx, info, &draws[0]);
struct mali_invocation_packed invocation;
panfrost_pack_work_groups_compute(&invocation,
@ -529,7 +533,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, indirect, &invocation, shared_mem, indices,
panfrost_draw_emit_tiler(batch, info, indirect, &draws[0], &invocation, shared_mem, indices,
fs_vary, varyings, pos, psiz, tiler.cpu);
panfrost_emit_vertex_tiler_jobs(batch, &vertex, &tiler);

View File

@ -333,7 +333,8 @@ static boolean immd_is_good_idea(struct r300_context *r300,
****************************************************************************/
static void r300_draw_arrays_immediate(struct r300_context *r300,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
@ -344,7 +345,7 @@ static void r300_draw_arrays_immediate(struct r300_context *r300,
unsigned vertex_size = r300->velems->vertex_size_dwords;
/* The number of dwords for this draw operation. */
unsigned dwords = 4 + info->count * vertex_size;
unsigned dwords = 4 + draw->count * vertex_size;
/* Size of the vertex element, in dwords. */
unsigned size[PIPE_MAX_ATTRIBS];
@ -375,21 +376,21 @@ static void r300_draw_arrays_immediate(struct r300_context *r300,
map[vbi] = (uint32_t*)r300->rws->buffer_map(
r300_resource(vbuf->buffer.resource)->buf,
r300->cs, PIPE_MAP_READ | PIPE_MAP_UNSYNCHRONIZED);
map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * info->start;
map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * draw->start;
}
mapelem[i] = map[vbi] + (velem->src_offset / 4);
}
r300_emit_draw_init(r300, info->mode, info->count-1);
r300_emit_draw_init(r300, info->mode, draw->count-1);
BEGIN_CS(dwords);
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, info->count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (info->count << 16) |
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, draw->count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (draw->count << 16) |
r300_translate_primitive(info->mode));
/* Emit vertices. */
for (v = 0; v < info->count; v++) {
for (v = 0; v < draw->count; v++) {
for (i = 0; i < vertex_element_count; i++) {
OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]);
}
@ -496,14 +497,15 @@ static void r300_emit_draw_elements(struct r300_context *r300,
}
static void r300_draw_elements_immediate(struct r300_context *r300,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
const uint8_t *ptr1;
const uint16_t *ptr2;
const uint32_t *ptr4;
unsigned index_size = info->index_size;
unsigned i, count_dwords = index_size == 4 ? info->count :
(info->count + 1) / 2;
unsigned i, count_dwords = index_size == 4 ? draw->count :
(draw->count + 1) / 2;
CS_LOCALS(r300);
/* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
@ -520,41 +522,41 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
switch (index_size) {
case 1:
ptr1 = (uint8_t*)info->index.user;
ptr1 += info->start;
ptr1 += draw->start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
r300_translate_primitive(info->mode));
if (info->index_bias && !r300->screen->caps.is_r500) {
for (i = 0; i < info->count-1; i += 2)
for (i = 0; i < draw->count-1; i += 2)
OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
(ptr1[i] + info->index_bias));
if (info->count & 1)
if (draw->count & 1)
OUT_CS(ptr1[i] + info->index_bias);
} else {
for (i = 0; i < info->count-1; i += 2)
for (i = 0; i < draw->count-1; i += 2)
OUT_CS(((ptr1[i+1]) << 16) |
(ptr1[i] ));
if (info->count & 1)
if (draw->count & 1)
OUT_CS(ptr1[i]);
}
break;
case 2:
ptr2 = (uint16_t*)info->index.user;
ptr2 += info->start;
ptr2 += draw->start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
r300_translate_primitive(info->mode));
if (info->index_bias && !r300->screen->caps.is_r500) {
for (i = 0; i < info->count-1; i += 2)
for (i = 0; i < draw->count-1; i += 2)
OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
(ptr2[i] + info->index_bias));
if (info->count & 1)
if (draw->count & 1)
OUT_CS(ptr2[i] + info->index_bias);
} else {
OUT_CS_TABLE(ptr2, count_dwords);
@ -563,14 +565,14 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
case 4:
ptr4 = (uint32_t*)info->index.user;
ptr4 += info->start;
ptr4 += draw->start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
r300_translate_primitive(info->mode));
if (info->index_bias && !r300->screen->caps.is_r500) {
for (i = 0; i < info->count; i++)
for (i = 0; i < draw->count; i++)
OUT_CS(ptr4[i] + info->index_bias);
} else {
OUT_CS_TABLE(ptr4, count_dwords);
@ -582,14 +584,15 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
static void r300_draw_elements(struct r300_context *r300,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
int instance_id)
{
struct pipe_resource *indexBuffer =
info->has_user_indices ? NULL : info->index.resource;
unsigned indexSize = info->index_size;
struct pipe_resource* orgIndexBuffer = indexBuffer;
unsigned start = info->start;
unsigned count = info->count;
unsigned start = draw->start;
unsigned count = draw->count;
boolean alt_num_verts = r300->screen->caps.is_r500 &&
count > 65536;
unsigned short_count;
@ -673,12 +676,13 @@ done:
static void r300_draw_arrays(struct r300_context *r300,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
int instance_id)
{
boolean alt_num_verts = r300->screen->caps.is_r500 &&
info->count > 65536;
unsigned start = info->start;
unsigned count = info->count;
draw->count > 65536;
unsigned start = draw->start;
unsigned count = draw->count;
unsigned short_count;
/* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
@ -713,21 +717,23 @@ static void r300_draw_arrays(struct r300_context *r300,
}
static void r300_draw_arrays_instanced(struct r300_context *r300,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
int i;
for (i = 0; i < info->instance_count; i++)
r300_draw_arrays(r300, info, i);
r300_draw_arrays(r300, info, draw, i);
}
static void r300_draw_elements_instanced(struct r300_context *r300,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
int i;
for (i = 0; i < info->instance_count; i++)
r300_draw_elements(r300, info, i);
r300_draw_elements(r300, info, draw, i);
}
static unsigned r300_max_vertex_count(struct r300_context *r300)
@ -781,13 +787,16 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct r300_context* r300 = r300_context(pipe);
struct pipe_draw_info info = *dinfo;
struct pipe_draw_start_count draw = draws[0];
if (r300->skip_rendering ||
!u_trim_pipe_prim(info.mode, &info.count)) {
!u_trim_pipe_prim(info.mode, &draw.count)) {
return;
}
@ -811,23 +820,23 @@ static void r300_draw_vbo(struct pipe_context* pipe,
info.max_index = max_count - 1;
if (info.instance_count <= 1) {
if (info.count <= 8 && info.has_user_indices) {
r300_draw_elements_immediate(r300, &info);
if (draw.count <= 8 && info.has_user_indices) {
r300_draw_elements_immediate(r300, &info, &draw);
} else {
r300_draw_elements(r300, &info, -1);
r300_draw_elements(r300, &info, &draw, -1);
}
} else {
r300_draw_elements_instanced(r300, &info);
r300_draw_elements_instanced(r300, &info, &draw);
}
} else {
if (info.instance_count <= 1) {
if (immd_is_good_idea(r300, info.count)) {
r300_draw_arrays_immediate(r300, &info);
if (immd_is_good_idea(r300, draw.count)) {
r300_draw_arrays_immediate(r300, &info, &draw);
} else {
r300_draw_arrays(r300, &info, -1);
r300_draw_arrays(r300, &info, &draw, -1);
}
} else {
r300_draw_arrays_instanced(r300, &info);
r300_draw_arrays_instanced(r300, &info, &draw);
}
}
}
@ -840,15 +849,18 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct r300_context* r300 = r300_context(pipe);
struct pipe_draw_start_count draw = draws[0];
if (r300->skip_rendering) {
return;
}
if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
if (!u_trim_pipe_prim(info->mode, &draw.count))
return;
if (info->index_size) {
@ -861,7 +873,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
r300_update_derived_state(r300);
draw_vbo(r300->draw, info, NULL);
draw_vbo(r300->draw, info, NULL, &draw, 1);
draw_flush(r300->draw);
}

View File

@ -36,7 +36,9 @@
struct r300_stencilref_context {
void (*draw_vbo)(struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
uint32_t rs_cull_mode;
uint32_t zb_stencilrefmask;
@ -103,18 +105,20 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
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, NULL);
sr->draw_vbo(pipe, info, NULL, draws, num_draws);
} else {
r300_stencilref_begin(r300);
sr->draw_vbo(pipe, info, NULL);
sr->draw_vbo(pipe, info, NULL, draws, num_draws);
r300_stencilref_switch_side(r300);
sr->draw_vbo(pipe, info, NULL);
sr->draw_vbo(pipe, info, NULL, draws, num_draws);
r300_stencilref_end(r300);
}
}

View File

@ -2053,7 +2053,9 @@ static inline void r600_emit_rasterizer_prim_state(struct r600_context *rctx)
}
static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct pipe_resource *indexbuf = info->has_user_indices ? NULL : info->index.resource;
@ -2073,7 +2075,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
indirect = NULL;
}
if (!indirect && !info->count && (index_size || !count_from_so)) {
if (!indirect && !draws[0].count && (index_size || !count_from_so)) {
return;
}
@ -2135,7 +2137,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
}
if (index_size) {
index_offset += info->start * index_size;
index_offset += draws[0].start * index_size;
/* Translate 8-bit indices to 16-bit. */
if (unlikely(index_size == 1)) {
@ -2146,7 +2148,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
if (likely(!indirect)) {
start = 0;
count = info->count;
count = draws[0].count;
}
else {
/* Have to get start/count from indirect buffer, slow path ahead... */
@ -2185,16 +2187,16 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
* Note: Instanced rendering in combination with immediate indices hangs. */
if (has_user_indices && (R600_BIG_ENDIAN || indirect ||
info->instance_count > 1 ||
info->count*index_size > 20)) {
draws[0].count*index_size > 20)) {
indexbuf = NULL;
u_upload_data(ctx->stream_uploader, 0,
info->count * index_size, 256,
draws[0].count * index_size, 256,
info->index.user, &index_offset, &indexbuf);
has_user_indices = false;
}
index_bias = info->index_bias;
} else {
index_bias = info->start;
index_bias = draws[0].start;
}
/* Set the index offset and primitive restart. */
@ -2326,10 +2328,10 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
(VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0)));
if (has_user_indices) {
unsigned size_bytes = info->count*index_size;
unsigned size_bytes = draws[0].count*index_size;
unsigned size_dw = align(size_bytes, 4) / 4;
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_IMMD, 1 + size_dw, render_cond_bit));
radeon_emit(cs, info->count);
radeon_emit(cs, draws[0].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_IMMEDIATE);
radeon_emit_array(cs, info->index.user, size_dw);
} else {
@ -2339,7 +2341,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX, 3, render_cond_bit));
radeon_emit(cs, va);
radeon_emit(cs, (va >> 32UL) & 0xFF);
radeon_emit(cs, info->count);
radeon_emit(cs, draws[0].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA);
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx,
@ -2390,7 +2392,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
if (likely(!indirect)) {
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_AUTO, 1, render_cond_bit));
radeon_emit(cs, info->count);
radeon_emit(cs, draws[0].count);
}
else {
radeon_emit(cs, PKT3(EG_PKT3_DRAW_INDIRECT, 1, render_cond_bit));

View File

@ -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, NULL, draws + first_draw, num_draws_split);
sctx->b.draw_vbo(&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, NULL, draws + i, 1);
sctx->b.draw_vbo(&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, NULL, &split_draw_range, 1);
sctx->b.draw_vbo(&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, NULL, &split_draw_range, 1);
sctx->b.draw_vbo(&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)

View File

@ -1768,11 +1768,11 @@ static ALWAYS_INLINE bool pd_msg(const char *s)
return false;
}
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)
static void si_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;
@ -2247,15 +2247,6 @@ return_cleanup:
pipe_resource_reference(&indexbuf, NULL);
}
static void si_draw_vbo(struct pipe_context *ctx,
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, indirect, &draw, 1);
}
static void si_draw_rectangle(struct blitter_context *blitter, void *vertex_elements_cso,
blitter_get_vs_func get_vs, int x1, int y1, int x2, int y2,
float depth, unsigned num_instances, enum blitter_attrib_type type,
@ -2283,16 +2274,20 @@ static void si_draw_rectangle(struct blitter_context *blitter, void *vertex_elem
pipe->bind_vs_state(pipe, si_get_blitter_vs(sctx, type, num_instances));
struct pipe_draw_info info = {};
struct pipe_draw_start_count draw;
info.mode = SI_PRIM_RECTANGLE_LIST;
info.count = 3;
info.instance_count = num_instances;
draw.start = 0;
draw.count = 3;
/* Don't set per-stage shader pointers for VS. */
sctx->shader_pointers_dirty &= ~SI_DESCS_SHADER_MASK(VERTEX);
sctx->vertex_buffer_pointer_dirty = false;
sctx->vertex_buffer_user_sgprs_dirty = false;
si_draw_vbo(pipe, &info, NULL);
si_draw_vbo(pipe, &info, NULL, &draw, 1);
}
void si_trace_emit(struct si_context *sctx)
@ -2312,8 +2307,6 @@ void si_trace_emit(struct si_context *sctx)
void si_init_draw_functions(struct si_context *sctx)
{
sctx->b.draw_vbo = si_draw_vbo;
sctx->b.multi_draw = si_multi_draw_vbo;
sctx->blitter->draw_rectangle = si_draw_rectangle;
si_init_ia_multi_vgt_param_table(sctx);

View File

@ -60,7 +60,9 @@
void
softpipe_draw_vbo(struct pipe_context *pipe,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct softpipe_context *sp = softpipe_context(pipe);
struct draw_context *draw = sp->draw;
@ -130,7 +132,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
sp->active_statistics_queries > 0);
/* draw! */
draw_vbo(draw, info, indirect);
draw_vbo(draw, info, indirect, draws, num_draws);
/* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) {

View File

@ -181,7 +181,9 @@ 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_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
void
softpipe_map_texture_surfaces(struct softpipe_context *sp);

View File

@ -66,6 +66,7 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl,
enum pipe_error
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned count);
boolean

View File

@ -61,6 +61,7 @@
static enum pipe_error
translate_indices(struct svga_hwtnl *hwtnl,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
enum pipe_prim_type gen_prim,
unsigned orig_nr, unsigned gen_nr,
unsigned gen_size,
@ -74,7 +75,7 @@ translate_indices(struct svga_hwtnl *hwtnl,
struct pipe_transfer *src_transfer = NULL;
struct pipe_transfer *dst_transfer = NULL;
const unsigned size = gen_size * gen_nr;
const unsigned offset = info->start * info->index_size;
const unsigned offset = draw->start * info->index_size;
const void *src_map = NULL;
struct pipe_resource *dst = NULL;
void *dst_map = NULL;
@ -215,6 +216,7 @@ svga_hwtnl_simple_draw_range_elements(struct svga_hwtnl *hwtnl,
enum pipe_error
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned count)
{
struct pipe_context *pipe = &hwtnl->svga->pipe;
@ -257,7 +259,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
if ((gen_type == U_TRANSLATE_MEMCPY) && (info->index_size == gen_size)) {
/* No need for translation, just pass through to hardware:
*/
unsigned start_offset = info->start * info->index_size;
unsigned start_offset = draw->start * info->index_size;
struct pipe_resource *index_buffer = NULL;
unsigned index_offset;
@ -269,7 +271,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
index_offset /= info->index_size;
} else {
pipe_resource_reference(&index_buffer, info->index.resource);
index_offset = info->start;
index_offset = draw->start;
}
assert(index_buffer != NULL);
@ -296,7 +298,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
* GL though, as index buffers are typically used only once
* there.
*/
ret = translate_indices(hwtnl, info, gen_prim,
ret = translate_indices(hwtnl, info, draw, gen_prim,
count, gen_nr, gen_size,
gen_func, &gen_buf, &gen_offset);
if (ret == PIPE_OK) {

View File

@ -45,11 +45,12 @@
static enum pipe_error
retry_draw_range_elements(struct svga_context *svga,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw,
unsigned count)
{
SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DRAWELEMENTS);
SVGA_RETRY(svga, svga_hwtnl_draw_range_elements(svga->hwtnl, info, count));
SVGA_RETRY(svga, svga_hwtnl_draw_range_elements(svga->hwtnl, info, draw, count));
SVGA_STATS_TIME_POP(svga_sws(svga));
return PIPE_OK;
@ -217,11 +218,13 @@ get_vcount_from_stream_output(struct svga_context *svga,
static void
svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct svga_context *svga = svga_context(pipe);
enum pipe_prim_type reduced_prim = u_reduced_prim(info->mode);
unsigned count = info->count;
unsigned count = draws[0].count;
enum pipe_error ret = 0;
boolean needed_swtnl;
@ -251,8 +254,8 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
* always start from 0 for DrawArrays and does not include baseVertex for
* DrawIndexed.
*/
if (svga->curr.vertex_id_bias != (info->start + info->index_bias)) {
svga->curr.vertex_id_bias = info->start + info->index_bias;
if (svga->curr.vertex_id_bias != (draws[0].start + info->index_bias)) {
svga->curr.vertex_id_bias = draws[0].start + info->index_bias;
svga->dirty |= SVGA_NEW_VS_CONSTS;
}
@ -270,7 +273,7 @@ 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, indirect);
r = util_draw_vbo_without_prim_restart(pipe, info, indirect, &draws[0]);
assert(r == PIPE_OK);
(void) r;
goto done;
@ -299,7 +302,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, indirect);
ret = svga_swtnl_draw_vbo(svga, info, indirect, &draws[0]);
}
else {
if (!svga_update_state_retry(svga, SVGA_STATE_HW_DRAW)) {
@ -351,10 +354,10 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
ret = retry_draw_indirect(svga, info, indirect);
}
else if (info->index_size) {
ret = retry_draw_range_elements(svga, info, count);
ret = retry_draw_range_elements(svga, info, &draws[0], count);
}
else {
ret = retry_draw_arrays(svga, info->mode, info->start, count,
ret = retry_draw_arrays(svga, info->mode, draws[0].start, count,
info->start_instance, info->instance_count,
info->vertices_per_patch);
}

View File

@ -40,7 +40,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_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw);
#endif

View File

@ -332,8 +332,10 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
.index_bias = bias,
.min_index = svga_render->min_index,
.max_index = svga_render->max_index,
};
const struct pipe_draw_start_count draw = {
.start = 0,
.count = nr_indices
.count = nr_indices,
};
assert((svga_render->vbuf_offset - svga_render->vdecl_offset)
@ -350,6 +352,7 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
*/
svga_update_state_retry(svga, SVGA_STATE_HW_DRAW);
SVGA_RETRY_CHECK(svga, svga_hwtnl_draw_range_elements(svga->hwtnl, &info,
&draw,
nr_indices), retried);
if (retried) {
svga->swtnl.new_vbuf = TRUE;

View File

@ -39,7 +39,8 @@
enum pipe_error
svga_swtnl_draw_vbo(struct svga_context *svga,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw_one)
{
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = { 0 };
struct pipe_transfer *ib_transfer = NULL;
@ -113,7 +114,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer->width0);
}
draw_vbo(draw, info, indirect);
draw_vbo(draw, info, indirect, draw_one, 1);
draw_flush(svga->swtnl.draw);

View File

@ -38,13 +38,15 @@
*/
static void
swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct swr_context *ctx = swr_context(pipe);
if (!indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
if (!swr_check_render_cond(pipe))
@ -66,14 +68,17 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
swr_update_draw_context(ctx);
struct pipe_draw_info resolved_info;
struct pipe_draw_start_count resolved_draw;
/* DrawTransformFeedback */
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_draw.start = draws[0].start;
resolved_draw.count = ctx->so_primCounter * resolved_info.vertices_per_patch;
resolved_info.max_index = resolved_draw.count - 1;
info = &resolved_info;
indirect = NULL;
draws = &resolved_draw;
}
if (ctx->vs->pipe.stream_output.num_outputs) {
@ -232,17 +237,17 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
if (info->index_size)
ctx->api.pfnSwrDrawIndexedInstanced(ctx->swrContext,
swr_convert_prim_topology(info->mode, info->vertices_per_patch),
info->count,
draws[0].count,
info->instance_count,
info->start,
draws[0].start,
info->index_bias,
info->start_instance);
else
ctx->api.pfnSwrDrawInstanced(ctx->swrContext,
swr_convert_prim_topology(info->mode, info->vertices_per_patch),
info->count,
draws[0].count,
info->instance_count,
info->start,
draws[0].start,
info->start_instance);
/* On client-buffer draw, we used client buffer directly, without

View File

@ -1158,7 +1158,8 @@ swr_get_last_fe(const struct swr_context *ctx)
void
swr_update_derived(struct pipe_context *pipe,
const struct pipe_draw_info *p_draw_info)
const struct pipe_draw_info *p_draw_info,
const struct pipe_draw_start_count *draw)
{
struct swr_context *ctx = swr_context(pipe);
struct swr_screen *screen = swr_screen(pipe->screen);
@ -1496,7 +1497,7 @@ swr_update_derived(struct pipe_context *pipe,
* revalidate on each draw */
post_update_dirty_flags |= SWR_NEW_VERTEX;
size = info.count * pitch;
size = draw->count * pitch;
size = AlignUp(size, 4);
/* If size of client memory copy is too large, don't copy. The

View File

@ -130,7 +130,8 @@ struct swr_derived_state {
};
void swr_update_derived(struct pipe_context *,
const struct pipe_draw_info * = nullptr);
const struct pipe_draw_info * = nullptr,
const struct pipe_draw_start_count *draw = nullptr);
/*
* Conversion functions: Convert mesa state defines to SWR.

View File

@ -47,7 +47,9 @@ 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_indirect_info *pindirect)
const struct pipe_draw_indirect_info *pindirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct tegra_context *context = to_tegra_context(pcontext);
struct pipe_draw_indirect_info indirect;
@ -68,7 +70,7 @@ tegra_draw_vbo(struct pipe_context *pcontext,
pindirect = &indirect;
}
context->gpu->draw_vbo(context->gpu, pinfo, pindirect);
context->gpu->draw_vbo(context->gpu, pinfo, pindirect, draws, num_draws);
}
static void

View File

@ -977,14 +977,15 @@ v3d_emit_gl_shader_state(struct v3d_context *v3d,
*/
static void
v3d_update_primitives_generated_counter(struct v3d_context *v3d,
const struct pipe_draw_info *info)
const struct pipe_draw_info *info,
const struct pipe_draw_start_count *draw)
{
assert(!v3d->prog.gs);
if (!v3d->active_queries)
return;
uint32_t prims = u_prims_for_vertices(info->mode, info->count);
uint32_t prims = u_prims_for_vertices(info->mode, draw->count);
v3d->prims_generated += prims;
}
@ -1085,13 +1086,15 @@ v3d_check_compiled_shaders(struct v3d_context *v3d)
static void
v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct v3d_context *v3d = v3d_context(pctx);
if (!indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
/* Fall back for weird desktop GL primitive restart values. */
@ -1109,16 +1112,16 @@ 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, indirect);
util_draw_vbo_without_prim_restart(pctx, info, indirect, &draws[0]);
return;
}
}
if (info->mode >= PIPE_PRIM_QUADS && info->mode <= PIPE_PRIM_POLYGON) {
util_primconvert_save_rasterizer_state(v3d->primconvert, &v3d->rasterizer->base);
util_primconvert_draw_vbo(v3d->primconvert, info);
util_primconvert_draw_vbo(v3d->primconvert, info, &draws[0]);
perf_debug("Fallback conversion for %d %s vertices\n",
info->count, u_prim_name(info->mode));
draws[0].count, u_prim_name(info->mode));
return;
}
@ -1260,17 +1263,17 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
#endif
if (!v3d->prog.gs)
v3d_update_primitives_generated_counter(v3d, info);
v3d_update_primitives_generated_counter(v3d, info, &draws[0]);
uint32_t hw_prim_type = v3d_hw_prim_type(info->mode);
if (info->index_size) {
uint32_t index_size = info->index_size;
uint32_t offset = info->start * index_size;
uint32_t offset = draws[0].start * index_size;
struct pipe_resource *prsc;
if (info->has_user_indices) {
prsc = NULL;
u_upload_data(v3d->uploader, 0,
info->count * info->index_size, 4,
draws[0].count * info->index_size, 4,
info->index.user,
&offset, &prsc);
} else {
@ -1315,12 +1318,12 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
prim.enable_primitive_restarts = info->primitive_restart;
prim.number_of_instances = info->instance_count;
prim.instance_length = info->count;
prim.instance_length = draws[0].count;
}
} else {
cl_emit(&job->bcl, INDEXED_PRIM_LIST, prim) {
prim.index_type = ffs(info->index_size) - 1;
prim.length = info->count;
prim.length = draws[0].count;
#if V3D_VERSION >= 40
prim.index_offset = offset;
#else /* V3D_VERSION < 40 */
@ -1351,10 +1354,10 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
indirect->count_from_stream_output : NULL;
uint32_t vert_count = so ?
v3d_stream_output_target_get_vertex_count(so) :
info->count;
draws[0].count;
cl_emit(&job->bcl, VERTEX_ARRAY_INSTANCED_PRIMS, prim) {
prim.mode = hw_prim_type | prim_tf_enable;
prim.index_of_first_vertex = info->start;
prim.index_of_first_vertex = draws[0].start;
prim.number_of_instances = info->instance_count;
prim.instance_length = vert_count;
}
@ -1364,11 +1367,11 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
indirect->count_from_stream_output : NULL;
uint32_t vert_count = so ?
v3d_stream_output_target_get_vertex_count(so) :
info->count;
draws[0].count;
cl_emit(&job->bcl, VERTEX_ARRAY_PRIMS, prim) {
prim.mode = hw_prim_type | prim_tf_enable;
prim.length = vert_count;
prim.index_of_first_vertex = info->start;
prim.index_of_first_vertex = draws[0].start;
}
}
}
@ -1387,7 +1390,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
* needs some clamping to the buffer size.
*/
for (int i = 0; i < v3d->streamout.num_targets; i++)
v3d->streamout.offsets[i] += info->count;
v3d->streamout.offsets[i] += draws[0].count;
if (v3d->zsa && job->zsbuf && v3d->zsa->base.depth.enabled) {
struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);

View File

@ -287,28 +287,30 @@ 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,
const struct pipe_draw_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct vc4_context *vc4 = vc4_context(pctx);
struct pipe_draw_info local_info;
if (!indirect &&
!info->primitive_restart &&
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
return;
if (info->mode >= PIPE_PRIM_QUADS) {
if (info->mode == PIPE_PRIM_QUADS &&
info->count == 4 &&
draws[0].count == 4 &&
!vc4->rasterizer->base.flatshade) {
local_info = *info;
local_info.mode = PIPE_PRIM_TRIANGLE_FAN;
info = &local_info;
} else {
util_primconvert_save_rasterizer_state(vc4->primconvert, &vc4->rasterizer->base);
util_primconvert_draw_vbo(vc4->primconvert, info);
util_primconvert_draw_vbo(vc4->primconvert, info, &draws[0]);
perf_debug("Fallback conversion for %d %s vertices\n",
info->count, u_prim_name(info->mode));
draws[0].count, u_prim_name(info->mode));
return;
}
}
@ -317,7 +319,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
vc4_predraw_check_textures(pctx, &vc4->verttex);
vc4_predraw_check_textures(pctx, &vc4->fragtex);
vc4_hw_2116_workaround(pctx, info->count);
vc4_hw_2116_workaround(pctx, draws[0].count);
struct vc4_job *job = vc4_get_job_for_fbo(vc4);
@ -329,7 +331,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
job = vc4_get_job_for_fbo(vc4);
}
vc4_get_draw_cl_space(job, info->count);
vc4_get_draw_cl_space(job, draws[0].count);
if (vc4->prim_mode != info->mode) {
vc4->prim_mode = info->mode;
@ -370,18 +372,18 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
*/
if (info->index_size) {
uint32_t index_size = info->index_size;
uint32_t offset = info->start * index_size;
uint32_t offset = draws[0].start * index_size;
struct pipe_resource *prsc;
if (info->index_size == 4) {
prsc = vc4_get_shadow_index_buffer(pctx, info,
offset,
info->count, &offset);
draws[0].count, &offset);
index_size = 2;
} else {
if (info->has_user_indices) {
prsc = NULL;
u_upload_data(vc4->uploader, 0,
info->count * index_size, 4,
draws[0].count * index_size, 4,
info->index.user,
&offset, &prsc);
} else {
@ -416,7 +418,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
(index_size == 2 ?
VC4_INDEX_BUFFER_U16:
VC4_INDEX_BUFFER_U8));
cl_u32(&bcl, info->count);
cl_u32(&bcl, draws[0].count);
cl_u32(&bcl, offset);
cl_u32(&bcl, vc4->max_index);
@ -426,8 +428,8 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (info->index_size == 4 || info->has_user_indices)
pipe_resource_reference(&prsc, NULL);
} else {
uint32_t count = info->count;
uint32_t start = info->start;
uint32_t count = draws[0].count;
uint32_t start = draws[0].start;
uint32_t extra_index_bias = 0;
static const uint32_t max_verts = 65535;

View File

@ -849,7 +849,9 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct virgl_context *vctx = virgl_context(ctx);
struct virgl_screen *rs = virgl_screen(ctx->screen);
@ -858,22 +860,22 @@ static void virgl_draw_vbo(struct pipe_context *ctx,
if (!indirect &&
!dinfo->primitive_restart &&
!u_trim_pipe_prim(dinfo->mode, (unsigned*)&dinfo->count))
!u_trim_pipe_prim(dinfo->mode, (unsigned*)&draws[0].count))
return;
if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
util_primconvert_save_rasterizer_state(vctx->primconvert, &vctx->rs_state.rs);
util_primconvert_draw_vbo(vctx->primconvert, dinfo);
util_primconvert_draw_vbo(vctx->primconvert, dinfo, &draws[0]);
return;
}
if (info.index_size) {
pipe_resource_reference(&ib.buffer, info.has_user_indices ? NULL : info.index.resource);
ib.user_buffer = info.has_user_indices ? info.index.user : NULL;
ib.index_size = dinfo->index_size;
ib.offset = info.start * ib.index_size;
ib.offset = draws[0].start * ib.index_size;
if (ib.user_buffer) {
u_upload_data(vctx->uploader, 0, info.count * ib.index_size, 4,
u_upload_data(vctx->uploader, 0, draws[0].count * ib.index_size, 4,
ib.user_buffer, &ib.offset, &ib.buffer);
ib.user_buffer = NULL;
}
@ -887,7 +889,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, indirect);
virgl_encoder_draw_vbo(vctx, &info, indirect, &draws[0]);
pipe_resource_reference(&ib.buffer, NULL);

View File

@ -708,7 +708,8 @@ 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_indirect_info *indirect)
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw)
{
uint32_t length = VIRGL_DRAW_VBO_SIZE;
if (info->mode == PIPE_PRIM_PATCHES)
@ -716,8 +717,8 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx,
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);
virgl_encoder_write_dword(ctx->cbuf, info->count);
virgl_encoder_write_dword(ctx->cbuf, draw->start);
virgl_encoder_write_dword(ctx->cbuf, draw->count);
virgl_encoder_write_dword(ctx->cbuf, info->mode);
virgl_encoder_write_dword(ctx->cbuf, !!info->index_size);
virgl_encoder_write_dword(ctx->cbuf, info->instance_count);

View File

@ -136,7 +136,8 @@ int virgl_encoder_set_viewport_states(struct virgl_context *ctx,
int virgl_encoder_draw_vbo(struct virgl_context *ctx,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draw);
int virgl_encoder_create_surface(struct virgl_context *ctx,

View File

@ -188,6 +188,8 @@ zink_blit(struct pipe_context *pctx,
void
zink_draw_vbo(struct pipe_context *pctx,
const struct pipe_draw_info *dinfo,
const struct pipe_draw_indirect_info *indirect);
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws);
#endif

View File

@ -209,7 +209,9 @@ 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_indirect_info *dindirect)
const struct pipe_draw_indirect_info *dindirect,
const struct pipe_draw_start_count *draws,
unsigned num_draws)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_screen *screen = zink_screen(pctx->screen);
@ -224,7 +226,7 @@ zink_draw_vbo(struct pipe_context *pctx,
if (dinfo->primitive_restart && !restart_supported(dinfo->mode)) {
util_draw_vbo_without_prim_restart(pctx, dinfo, dindirect);
util_draw_vbo_without_prim_restart(pctx, dinfo, dindirect, &draws[0]);
return;
}
if (dinfo->mode == PIPE_PRIM_QUADS ||
@ -232,11 +234,11 @@ zink_draw_vbo(struct pipe_context *pctx,
dinfo->mode == PIPE_PRIM_POLYGON ||
(dinfo->mode == PIPE_PRIM_TRIANGLE_FAN && !screen->have_triangle_fans) ||
dinfo->mode == PIPE_PRIM_LINE_LOOP) {
if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&draws[0].count))
return;
util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base);
util_primconvert_draw_vbo(ctx->primconvert, dinfo);
util_primconvert_draw_vbo(ctx->primconvert, dinfo, &draws[0]);
return;
}
@ -278,11 +280,11 @@ 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, dindirect, &index_buffer);
util_translate_prim_restart_ib(pctx, dinfo, dindirect, &draws[0], &index_buffer);
need_index_buffer_unref = true;
} else {
if (dinfo->has_user_indices) {
if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset, 4)) {
if (!util_upload_index_buffer(pctx, dinfo, &draws[0], &index_buffer, &index_offset, 4)) {
debug_printf("util_upload_index_buffer() failed\n");
return;
}
@ -523,8 +525,8 @@ zink_draw_vbo(struct pipe_context *pctx,
vkCmdDrawIndexedIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
} else
vkCmdDrawIndexed(batch->cmdbuf,
dinfo->count, dinfo->instance_count,
need_index_buffer_unref ? 0 : dinfo->start, dinfo->index_bias, dinfo->start_instance);
draws[0].count, dinfo->instance_count,
need_index_buffer_unref ? 0 : draws[0].start, dinfo->index_bias, dinfo->start_instance);
} else {
if (so_target && screen->info.tf_props.transformFeedbackDraw) {
zink_batch_reference_resource_rw(batch, zink_resource(so_target->counter_buffer), true);
@ -536,7 +538,7 @@ zink_draw_vbo(struct pipe_context *pctx,
zink_batch_reference_resource_rw(batch, indirect, false);
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);
vkCmdDraw(batch->cmdbuf, draws[0].count, dinfo->instance_count, draws[0].start, dinfo->start_instance);
}
if (dinfo->index_size > 0 && (dinfo->has_user_indices || need_index_buffer_unref))

View File

@ -60,6 +60,7 @@ struct rendering_state {
bool min_samples_dirty;
struct pipe_draw_indirect_info indirect_info;
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
struct pipe_grid_info dispatch_info;
struct pipe_framebuffer_state framebuffer;
@ -1302,11 +1303,11 @@ static void handle_draw(struct lvp_cmd_buffer_entry *cmd,
{
state->info.index_size = 0;
state->info.index.resource = NULL;
state->info.start = cmd->u.draw.first_vertex;
state->info.count = cmd->u.draw.vertex_count;
state->draw.start = cmd->u.draw.first_vertex;
state->draw.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, NULL);
state->pctx->draw_vbo(state->pctx, &state->info, NULL, &state->draw, 1);
}
static void handle_set_viewport(struct lvp_cmd_buffer_entry *cmd,
@ -1845,8 +1846,8 @@ static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,
state->info.max_index = ~0;
state->info.index_size = state->index_size;
state->info.index.resource = state->index_buffer;
state->info.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
state->info.count = cmd->u.draw_indexed.index_count;
state->draw.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
state->draw.count = cmd->u.draw_indexed.index_count;
state->info.start_instance = cmd->u.draw_indexed.first_instance;
state->info.instance_count = cmd->u.draw_indexed.instance_count;
state->info.index_bias = cmd->u.draw_indexed.vertex_offset;
@ -1858,7 +1859,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, NULL);
state->pctx->draw_vbo(state->pctx, &state->info, NULL, &state->draw, 1);
}
static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd,
@ -1875,7 +1876,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->pctx->draw_vbo(state->pctx, &state->info, &state->indirect_info);
state->pctx->draw_vbo(state->pctx, &state->info, &state->indirect_info, &state->draw, 1);
}
static void handle_index_buffer(struct lvp_cmd_buffer_entry *cmd,

View File

@ -3090,6 +3090,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
struct pipe_stream_output_info so;
struct pipe_stream_output_target *target;
struct pipe_draw_info draw;
struct pipe_draw_start_count sc;
struct pipe_box box;
bool programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t);
unsigned offsets[1] = {0};
@ -3170,13 +3171,13 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
}
draw.mode = PIPE_PRIM_POINTS;
draw.count = VertexCount;
sc.count = VertexCount;
draw.start_instance = 0;
draw.primitive_restart = FALSE;
draw.restart_index = 0;
draw.instance_count = 1;
draw.index_size = 0;
draw.start = 0;
sc.start = 0;
draw.index_bias = 0;
draw.min_index = 0;
draw.max_index = VertexCount - 1;
@ -3184,7 +3185,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
pipe_sw->set_stream_output_targets(pipe_sw, 1, &target, offsets);
pipe_sw->draw_vbo(pipe_sw, &draw, NULL);
pipe_sw->draw_vbo(pipe_sw, &draw, NULL, &sc, 1);
pipe_sw->set_stream_output_targets(pipe_sw, 0, NULL, 0);
pipe_sw->stream_output_target_destroy(pipe_sw, target);

View File

@ -2307,10 +2307,11 @@ CSMT_ITEM_NO_WAIT(nine_context_clear_fb,
static inline void
init_draw_info(struct pipe_draw_info *info,
struct pipe_draw_start_count *draw,
struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count)
{
info->mode = d3dprimitivetype_to_pipe_prim(type);
info->count = prim_count_to_vertex_count(type, count);
draw->count = prim_count_to_vertex_count(type, count);
info->start_instance = 0;
info->instance_count = 1;
if (dev->context.stream_instancedata_mask & dev->context.stream_usage_mask)
@ -2327,18 +2328,19 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive,
{
struct nine_context *context = &device->context;
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = 0;
info.start = StartVertex;
draw.start = StartVertex;
info.index_bias = 0;
info.min_index = info.start;
info.max_index = info.count - 1;
info.min_index = draw.start;
info.max_index = draw.count - 1;
info.index.resource = NULL;
context->pipe->draw_vbo(context->pipe, &info, NULL);
context->pipe->draw_vbo(context->pipe, &info, NULL, &draw, 1);
}
CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive,
@ -2351,12 +2353,13 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive,
{
struct nine_context *context = &device->context;
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = context->index_size;
info.start = context->index_offset / context->index_size + StartIndex;
draw.start = context->index_offset / context->index_size + StartIndex;
info.index_bias = BaseVertexIndex;
info.index_bounds_valid = true;
/* These don't include index bias: */
@ -2364,7 +2367,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, NULL);
context->pipe->draw_vbo(context->pipe, &info, NULL, &draw, 1);
}
CSMT_ITEM_NO_WAIT(nine_context_draw_primitive_from_vtxbuf,
@ -2374,20 +2377,21 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive_from_vtxbuf,
{
struct nine_context *context = &device->context;
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = 0;
info.start = 0;
draw.start = 0;
info.index_bias = 0;
info.min_index = 0;
info.max_index = info.count - 1;
info.max_index = draw.count - 1;
info.index.resource = NULL;
context->pipe->set_vertex_buffers(context->pipe, 0, 1, vtxbuf);
context->pipe->draw_vbo(context->pipe, &info, NULL);
context->pipe->draw_vbo(context->pipe, &info, NULL, &draw, 1);
}
CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf,
@ -2403,12 +2407,13 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf,
{
struct nine_context *context = &device->context;
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = index_size;
info.start = index_offset / info.index_size;
draw.start = index_offset / info.index_size;
info.index_bias = 0;
info.index_bounds_valid = true;
info.min_index = MinVertexIndex;
@ -2421,7 +2426,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, NULL);
context->pipe->draw_vbo(context->pipe, &info, NULL, &draw, 1);
}
CSMT_ITEM_NO_WAIT(nine_context_resource_copy_region,

View File

@ -108,45 +108,38 @@ struct pipe_context {
* VBO drawing
*/
/*@{*/
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.
* Multi draw.
*
* For indirect multi draws, use draw_vbo, which supports them through
* "info->indirect".
* For indirect multi draws, num_draws is 1 and indirect->draw_count
* is used instead.
*
* Differences against draw_vbo:
* - "start" and "count" are taken from "draws", not "info"
* - "info->has_user_indices" is always false
* - "info->indirect" and "info->count_from_stream_output" are always NULL
* Caps:
* - PIPE_CAP_MULTI_DRAW: Direct multi draws
* - PIPE_CAP_MULTI_DRAW_INDIRECT: Indirect multi draws
* - PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: Indirect draw count
*
* Differences against glMultiDraw:
* - "info->draw_id" is 0 and should be 0 for every draw
* (we could make this configurable)
* - "info->index_bias" is always constant due to hardware performance
* concerns (this is very important) and the lack of apps using
* glMultiDrawElementsBaseVertex.
* Differences against glMultiDraw and glMultiMode:
* - "info->mode" and "info->index_bias" are always constant due to the lack
* of hardware support and CPU performance concerns. Only start and count
* vary.
* - if "info->increment_draw_id" is false, draw_id doesn't change between
* draws
*
* The main use case is to optimize applications that submit many
* back-to-back draws or when mesa/main or st/mesa eliminates redundant
* state changes, resulting in back-to-back draws in the driver. It requires
* DrawID = 0 for every draw. u_threaded_context is the module that converts
* back-to-back draws into a multi draw. It's done trivially by looking
* ahead within a gallium command buffer and collapsing draws.
* Direct multi draws are also generated by u_threaded_context, which looks
* ahead in gallium command buffers and merges single draws.
*
* \param pipe context
* \param info draw info
* \param draws array of (start, count) pairs
* \param num_draws number of draws
* \param indirect indirect multi draws
* \param draws array of (start, count) pairs for direct draws
* \param num_draws number of direct draws; 1 for indirect multi draws
*/
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);
void (*draw_vbo)(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);
/*@}*/
/**

View File

@ -749,14 +749,6 @@ struct pipe_draw_start_count {
*/
struct pipe_draw_info
{
/**
* Direct draws: start is the index of the first vertex
* Non-indexed indirect draws: not used
* Indexed indirect draws: start is added to the indirect start.
*/
unsigned start;
unsigned count; /**< number of vertices */
enum pipe_prim_type mode:8; /**< the mode of the primitive */
ubyte vertices_per_patch; /**< the number of vertices per patch */
ubyte index_size; /**< if 0, the draw is not indexed. */

View File

@ -187,6 +187,7 @@ static void draw( void )
{
union pipe_color_union clear_color = { {1,0,1,1} };
struct pipe_draw_info info;
struct pipe_draw_start_count draw;
ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
@ -194,8 +195,8 @@ static void draw( void )
util_draw_init_info(&info);
info.index_size = draw_elements ? 2 : 0;
info.mode = PIPE_PRIM_TRIANGLES;
info.start = 0;
info.count = 3;
draw.start = 0;
draw.count = 3;
/* draw NUM_INST triangles */
info.instance_count = NUM_INST;
@ -209,7 +210,7 @@ static void draw( void )
indices);
}
ctx->draw_vbo(ctx, &info, NULL);
ctx->draw_vbo(ctx, &info, NULL, &draw, 1);
pipe_resource_reference(&info.index.resource, NULL);

View File

@ -223,31 +223,34 @@ st_draw_vbo(struct gl_context *ctx,
/* do actual drawing */
for (i = 0; i < nr_prims; i++) {
info.count = prims[i].count;
struct pipe_draw_start_count draw;
draw.count = prims[i].count;
/* Skip no-op draw calls. */
if (!info.count)
if (!draw.count)
continue;
draw.start = start + prims[i].start;
info.mode = translate_prim(ctx, prims[i].mode);
info.start = start + prims[i].start;
info.index_bias = prims[i].basevertex;
info.drawid = prims[i].draw_id;
if (!ib) {
info.min_index = info.start;
info.max_index = info.start + info.count - 1;
info.min_index = draw.start;
info.max_index = draw.start + draw.count - 1;
}
if (ST_DEBUG & DEBUG_DRAW) {
debug_printf("st/draw: mode %s start %u count %u index_size %d\n",
u_prim_name(info.mode),
info.start,
info.count,
draw.start,
draw.count,
info.index_size);
}
/* Don't call u_trim_pipe_prim. Drivers should do it if they need it. */
cso_draw_vbo(st->cso_context, &info, NULL);
cso_draw_vbo(st->cso_context, &info, NULL, draw);
}
}
@ -265,13 +268,13 @@ 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;
struct pipe_draw_start_count draw = {0};
assert(stride);
prepare_draw(st, ctx);
memset(&indirect, 0, sizeof(indirect));
util_draw_init_info(&info);
info.start = 0; /* index offset / index size */
info.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */
if (ib) {
@ -282,7 +285,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
info.index_size = 1 << ib->index_size_shift;
info.index.resource = st_buffer_object(bufobj)->buffer;
info.start = pointer_to_offset(ib->ptr) >> ib->index_size_shift;
draw.start = pointer_to_offset(ib->ptr) >> ib->index_size_shift;
/* Primitive restart is not handled by the VBO module in this case. */
setup_primitive_restart(ctx, &info);
@ -307,7 +310,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, &indirect);
cso_draw_vbo(st->cso_context, &info, &indirect, draw);
indirect.offset += stride;
}
} else {
@ -318,7 +321,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, &indirect);
cso_draw_vbo(st->cso_context, &info, &indirect, draw);
}
}
@ -330,12 +333,12 @@ st_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
struct st_context *st = st_context(ctx);
struct pipe_draw_info info;
struct pipe_draw_indirect_info indirect;
struct pipe_draw_start_count draw = {0};
prepare_draw(st, ctx);
memset(&indirect, 0, sizeof(indirect));
util_draw_init_info(&info);
info.start = 0; /* index offset / index size */
info.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */
info.mode = translate_prim(ctx, mode);
info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
@ -351,7 +354,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, &indirect);
cso_draw_vbo(st->cso_context, &info, &indirect, draw);
}
void

Some files were not shown because too many files have changed in this diff Show More