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:
parent
80b391077f
commit
1cd455b17b
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue