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
|
void
|
||||||
cso_draw_vbo(struct cso_context *cso,
|
cso_draw_vbo(struct cso_context *cso,
|
||||||
const struct pipe_draw_info *info,
|
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;
|
struct u_vbuf *vbuf = cso->vbuf_current;
|
||||||
|
|
||||||
|
@ -1738,10 +1739,10 @@ cso_draw_vbo(struct cso_context *cso,
|
||||||
indirect->count_from_stream_output == NULL);
|
indirect->count_from_stream_output == NULL);
|
||||||
|
|
||||||
if (vbuf) {
|
if (vbuf) {
|
||||||
u_vbuf_draw_vbo(vbuf, info, indirect);
|
u_vbuf_draw_vbo(vbuf, info, indirect, draw);
|
||||||
} else {
|
} else {
|
||||||
struct pipe_context *pipe = cso->pipe;
|
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)
|
cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
|
||||||
{
|
{
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
|
|
||||||
info.mode = mode;
|
info.mode = mode;
|
||||||
info.start = start;
|
|
||||||
info.count = count;
|
|
||||||
info.min_index = start;
|
info.min_index = start;
|
||||||
info.max_index = start + count - 1;
|
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
|
void
|
||||||
|
@ -1767,16 +1770,18 @@ cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
|
||||||
uint start_instance, uint instance_count)
|
uint start_instance, uint instance_count)
|
||||||
{
|
{
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
|
|
||||||
info.mode = mode;
|
info.mode = mode;
|
||||||
info.start = start;
|
|
||||||
info.count = count;
|
|
||||||
info.min_index = start;
|
info.min_index = start;
|
||||||
info.max_index = start + count - 1;
|
info.max_index = start + count - 1;
|
||||||
info.start_instance = start_instance;
|
info.start_instance = start_instance;
|
||||||
info.instance_count = instance_count;
|
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
|
void
|
||||||
cso_draw_vbo(struct cso_context *cso,
|
cso_draw_vbo(struct cso_context *cso,
|
||||||
const struct pipe_draw_info *info,
|
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
|
void
|
||||||
cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
|
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,
|
void draw_vbo(struct draw_context *draw,
|
||||||
const struct pipe_draw_info *info,
|
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
|
static void
|
||||||
draw_pt_arrays_restart(struct draw_context *draw,
|
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 prim = info->mode;
|
||||||
const unsigned start = info->start;
|
const unsigned start = draw_info->start;
|
||||||
const unsigned count = info->count;
|
const unsigned count = draw_info->count;
|
||||||
const unsigned elt_max = draw->pt.user.eltMax;
|
const unsigned elt_max = draw->pt.user.eltMax;
|
||||||
unsigned i, j, cur_start, cur_count;
|
unsigned i, j, cur_start, cur_count;
|
||||||
/* The largest index within a loop using the i variable as the index.
|
/* 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
|
static void
|
||||||
resolve_draw_info(const struct pipe_draw_info *raw_info,
|
resolve_draw_info(const struct pipe_draw_info *raw_info,
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count *raw_draw,
|
||||||
struct pipe_draw_info *info,
|
struct pipe_draw_info *info,
|
||||||
|
struct pipe_draw_start_count *draw,
|
||||||
struct pipe_vertex_buffer *vertex_buffer)
|
struct pipe_vertex_buffer *vertex_buffer)
|
||||||
{
|
{
|
||||||
memcpy(info, raw_info, sizeof(struct pipe_draw_info));
|
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) {
|
if (indirect && indirect->count_from_stream_output) {
|
||||||
struct draw_so_target *target =
|
struct draw_so_target *target =
|
||||||
(struct draw_so_target *)indirect->count_from_stream_output;
|
(struct draw_so_target *)indirect->count_from_stream_output;
|
||||||
assert(vertex_buffer != NULL);
|
assert(vertex_buffer != NULL);
|
||||||
info->count = vertex_buffer->stride == 0 ? 0 :
|
draw->count = vertex_buffer->stride == 0 ? 0 :
|
||||||
target->internal_offset / vertex_buffer->stride;
|
target->internal_offset / vertex_buffer->stride;
|
||||||
|
|
||||||
/* Stream output draw can not be indexed */
|
/* Stream output draw can not be indexed */
|
||||||
debug_assert(!info->index_size);
|
debug_assert(!info->index_size);
|
||||||
info->max_index = info->count - 1;
|
info->max_index = draw->count - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,13 +472,16 @@ resolve_draw_info(const struct pipe_draw_info *raw_info,
|
||||||
void
|
void
|
||||||
draw_vbo(struct draw_context *draw,
|
draw_vbo(struct draw_context *draw,
|
||||||
const struct pipe_draw_info *info,
|
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 instance;
|
||||||
unsigned index_limit;
|
unsigned index_limit;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
unsigned fpstate = util_fpstate_get();
|
unsigned fpstate = util_fpstate_get();
|
||||||
struct pipe_draw_info resolved_info;
|
struct pipe_draw_info resolved_info;
|
||||||
|
struct pipe_draw_start_count resolved_draw;
|
||||||
|
|
||||||
if (info->instance_count == 0)
|
if (info->instance_count == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -484,13 +491,16 @@ draw_vbo(struct draw_context *draw,
|
||||||
*/
|
*/
|
||||||
util_fpstate_set_denorms_to_zero(fpstate);
|
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;
|
info = &resolved_info;
|
||||||
|
draws = &resolved_draw;
|
||||||
|
num_draws = 1;
|
||||||
|
|
||||||
if (info->index_size)
|
if (info->index_size)
|
||||||
assert(draw->pt.user.elts);
|
assert(draw->pt.user.elts);
|
||||||
|
|
||||||
count = info->count;
|
count = draws[0].count;
|
||||||
|
|
||||||
draw->pt.user.eltBias = info->index_bias;
|
draw->pt.user.eltBias = info->index_bias;
|
||||||
draw->pt.user.min_index = info->min_index;
|
draw->pt.user.min_index = info->min_index;
|
||||||
|
@ -502,7 +512,7 @@ draw_vbo(struct draw_context *draw,
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
debug_printf("draw_vbo(mode=%u start=%u count=%u):\n",
|
debug_printf("draw_vbo(mode=%u start=%u count=%u):\n",
|
||||||
info->mode, info->start, count);
|
info->mode, draws[0].start, count);
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
|
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
|
||||||
|
@ -530,7 +540,7 @@ draw_vbo(struct draw_context *draw,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0)
|
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,
|
index_limit = util_draw_max_index(draw->pt.vertex_buffer,
|
||||||
draw->pt.vertex_element,
|
draw->pt.vertex_element,
|
||||||
|
@ -554,7 +564,7 @@ draw_vbo(struct draw_context *draw,
|
||||||
}
|
}
|
||||||
|
|
||||||
draw->pt.max_index = index_limit - 1;
|
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
|
* 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);
|
draw_new_instance(draw);
|
||||||
|
|
||||||
if (info->primitive_restart) {
|
if (info->primitive_restart) {
|
||||||
draw_pt_arrays_restart(draw, info);
|
draw_pt_arrays_restart(draw, info, &draws[0]);
|
||||||
}
|
}
|
||||||
else {
|
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
|
static void
|
||||||
dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info,
|
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;
|
int sh, i;
|
||||||
|
|
||||||
DUMP(draw_info, info);
|
DUMP(draw_info, info);
|
||||||
|
DUMP(draw_start_count, draw);
|
||||||
if (indirect) {
|
if (indirect) {
|
||||||
if (indirect->buffer)
|
if (indirect->buffer)
|
||||||
DUMP_M(resource, 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);
|
dd_dump_flush(state, &call->info.flush, f);
|
||||||
break;
|
break;
|
||||||
case CALL_DRAW_VBO:
|
case CALL_DRAW_VBO:
|
||||||
dd_dump_draw_vbo(state, &call->info.draw_vbo.draw,
|
dd_dump_draw_vbo(state, &call->info.draw_vbo.info,
|
||||||
&call->info.draw_vbo.indirect, f);
|
&call->info.draw_vbo.indirect,
|
||||||
|
&call->info.draw_vbo.draw, f);
|
||||||
break;
|
break;
|
||||||
case CALL_LAUNCH_GRID:
|
case CALL_LAUNCH_GRID:
|
||||||
dd_dump_launch_grid(state, &call->info.launch_grid, f);
|
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_so_target_reference(&dst->info.draw_vbo.indirect.count_from_stream_output, NULL);
|
||||||
pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL);
|
pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL);
|
||||||
pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL);
|
pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL);
|
||||||
if (dst->info.draw_vbo.draw.index_size &&
|
if (dst->info.draw_vbo.info.index_size &&
|
||||||
!dst->info.draw_vbo.draw.has_user_indices)
|
!dst->info.draw_vbo.info.has_user_indices)
|
||||||
pipe_resource_reference(&dst->info.draw_vbo.draw.index.resource, NULL);
|
pipe_resource_reference(&dst->info.draw_vbo.info.index.resource, NULL);
|
||||||
else
|
else
|
||||||
dst->info.draw_vbo.draw.index.user = NULL;
|
dst->info.draw_vbo.info.index.user = NULL;
|
||||||
break;
|
break;
|
||||||
case CALL_LAUNCH_GRID:
|
case CALL_LAUNCH_GRID:
|
||||||
pipe_resource_reference(&dst->info.launch_grid.indirect, NULL);
|
pipe_resource_reference(&dst->info.launch_grid.indirect, NULL);
|
||||||
|
@ -1300,17 +1303,20 @@ dd_context_flush(struct pipe_context *_pipe,
|
||||||
static void
|
static void
|
||||||
dd_context_draw_vbo(struct pipe_context *_pipe,
|
dd_context_draw_vbo(struct pipe_context *_pipe,
|
||||||
const struct pipe_draw_info *info,
|
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 dd_context *dctx = dd_context(_pipe);
|
||||||
struct pipe_context *pipe = dctx->pipe;
|
struct pipe_context *pipe = dctx->pipe;
|
||||||
struct dd_draw_record *record = dd_create_record(dctx);
|
struct dd_draw_record *record = dd_create_record(dctx);
|
||||||
|
|
||||||
record->call.type = CALL_DRAW_VBO;
|
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) {
|
if (info->index_size && !info->has_user_indices) {
|
||||||
record->call.info.draw_vbo.draw.index.resource = NULL;
|
record->call.info.draw_vbo.info.index.resource = NULL;
|
||||||
pipe_resource_reference(&record->call.info.draw_vbo.draw.index.resource,
|
pipe_resource_reference(&record->call.info.draw_vbo.info.index.resource,
|
||||||
info->index.resource);
|
info->index.resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1330,7 +1336,7 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
|
||||||
}
|
}
|
||||||
|
|
||||||
dd_before_draw(dctx, record);
|
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);
|
dd_after_draw(dctx, record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,8 +122,9 @@ struct call_flush {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct call_draw_info {
|
struct call_draw_info {
|
||||||
struct pipe_draw_info draw;
|
struct pipe_draw_info info;
|
||||||
struct pipe_draw_indirect_info indirect;
|
struct pipe_draw_indirect_info indirect;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct call_get_query_result_resource {
|
struct call_get_query_result_resource {
|
||||||
|
|
|
@ -31,7 +31,9 @@
|
||||||
#include "util/u_transfer.h"
|
#include "util/u_transfer.h"
|
||||||
|
|
||||||
static void noop_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
|
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
|
static void
|
||||||
rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *_info,
|
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 rbug_context *rb_pipe = rbug_context(_pipe);
|
||||||
struct pipe_context *pipe = rb_pipe->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) &&
|
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_GEOMETRY] && rb_pipe->curr.shader[PIPE_SHADER_GEOMETRY]->disabled) &&
|
||||||
!(rb_pipe->curr.shader[PIPE_SHADER_VERTEX] && rb_pipe->curr.shader[PIPE_SHADER_VERTEX]->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);
|
mtx_unlock(&rb_pipe->call_mutex);
|
||||||
|
|
||||||
rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);
|
rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);
|
||||||
|
|
|
@ -90,7 +90,9 @@ trace_surface_unwrap(struct trace_context *tr_ctx,
|
||||||
static void
|
static void
|
||||||
trace_context_draw_vbo(struct pipe_context *_pipe,
|
trace_context_draw_vbo(struct pipe_context *_pipe,
|
||||||
const struct pipe_draw_info *info,
|
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 trace_context *tr_ctx = trace_context(_pipe);
|
||||||
struct pipe_context *pipe = tr_ctx->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(ptr, pipe);
|
||||||
trace_dump_arg(draw_info, info);
|
trace_dump_arg(draw_info, info);
|
||||||
trace_dump_arg(draw_indirect_info, indirect);
|
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();
|
trace_dump_trace_flush();
|
||||||
|
|
||||||
pipe->draw_vbo(pipe, info, indirect);
|
pipe->draw_vbo(pipe, info, indirect, draws, num_draws);
|
||||||
|
|
||||||
trace_dump_call_end();
|
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, index_size);
|
||||||
trace_dump_member(uint, state, has_user_indices);
|
trace_dump_member(uint, state, has_user_indices);
|
||||||
|
|
||||||
trace_dump_member(uint, state, mode);
|
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, start_instance);
|
||||||
trace_dump_member(uint, state, instance_count);
|
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();
|
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)
|
void trace_dump_draw_indirect_info(const struct pipe_draw_indirect_info *state)
|
||||||
{
|
{
|
||||||
if (!trace_dumping_enabled_locked())
|
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_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_draw_indirect_info(const struct pipe_draw_indirect_info *state);
|
||||||
|
|
||||||
void trace_dump_blit_info(const struct pipe_blit_info *);
|
void trace_dump_blit_info(const struct pipe_blit_info *);
|
||||||
|
|
|
@ -97,9 +97,11 @@ util_primconvert_save_rasterizer_state(struct primconvert_context *pc,
|
||||||
|
|
||||||
void
|
void
|
||||||
util_primconvert_draw_vbo(struct primconvert_context *pc,
|
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_info new_info;
|
||||||
|
struct pipe_draw_start_count new_draw;
|
||||||
struct pipe_transfer *src_transfer = NULL;
|
struct pipe_transfer *src_transfer = NULL;
|
||||||
u_translate_func trans_func;
|
u_translate_func trans_func;
|
||||||
u_generate_func gen_func;
|
u_generate_func gen_func;
|
||||||
|
@ -121,10 +123,10 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
|
||||||
unsigned index_size;
|
unsigned index_size;
|
||||||
|
|
||||||
u_index_translator(pc->cfg.primtypes_mask,
|
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,
|
pc->api_pv, pc->api_pv,
|
||||||
info->primitive_restart ? PR_ENABLE : PR_DISABLE,
|
info->primitive_restart ? PR_ENABLE : PR_DISABLE,
|
||||||
&mode, &index_size, &new_info.count,
|
&mode, &index_size, &new_draw.count,
|
||||||
&trans_func);
|
&trans_func);
|
||||||
new_info.mode = mode;
|
new_info.mode = mode;
|
||||||
new_info.index_size = index_size;
|
new_info.index_size = index_size;
|
||||||
|
@ -140,31 +142,31 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
|
||||||
unsigned index_size;
|
unsigned index_size;
|
||||||
|
|
||||||
u_index_generator(pc->cfg.primtypes_mask,
|
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,
|
pc->api_pv, pc->api_pv,
|
||||||
&mode, &index_size, &new_info.count,
|
&mode, &index_size, &new_draw.count,
|
||||||
&gen_func);
|
&gen_func);
|
||||||
new_info.mode = mode;
|
new_info.mode = mode;
|
||||||
new_info.index_size = index_size;
|
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);
|
&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) {
|
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) {
|
if (pc->cfg.fixed_prim_restart && info->primitive_restart) {
|
||||||
new_info.restart_index = (1ull << (new_info.index_size * 8)) - 1;
|
new_info.restart_index = (1ull << (new_info.index_size * 8)) - 1;
|
||||||
if (info->restart_index != new_info.restart_index)
|
if (info->restart_index != new_info.restart_index)
|
||||||
util_translate_prim_restart_data(new_info.index_size, dst, dst,
|
util_translate_prim_restart_data(new_info.index_size, dst, dst,
|
||||||
new_info.count,
|
new_draw.count,
|
||||||
info->restart_index);
|
info->restart_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gen_func(info->start, new_info.count, dst);
|
gen_func(draw->start, new_draw.count, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_transfer)
|
if (src_transfer)
|
||||||
|
@ -173,7 +175,7 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
|
||||||
u_upload_unmap(pc->pipe->stream_uploader);
|
u_upload_unmap(pc->pipe->stream_uploader);
|
||||||
|
|
||||||
/* to the translated draw: */
|
/* 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);
|
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
|
const struct pipe_rasterizer_state
|
||||||
*rast);
|
*rast);
|
||||||
void util_primconvert_draw_vbo(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);
|
||||||
|
|
||||||
#endif /* U_PRIMCONVERT_H_ */
|
#endif /* U_PRIMCONVERT_H_ */
|
||||||
|
|
|
@ -176,14 +176,16 @@ util_draw_indirect(struct pipe_context *pipe,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < draw_count; i++) {
|
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.instance_count = params[1];
|
||||||
info.start = params[2];
|
draw.start = params[2];
|
||||||
info.index_bias = info_in->index_size ? params[3] : 0;
|
info.index_bias = info_in->index_size ? params[3] : 0;
|
||||||
info.start_instance = info_in->index_size ? params[4] : params[3];
|
info.start_instance = info_in->index_size ? params[4] : params[3];
|
||||||
info.drawid = i;
|
info.drawid = i;
|
||||||
|
|
||||||
pipe->draw_vbo(pipe, &info, NULL);
|
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
|
||||||
|
|
||||||
params += indirect->stride / 4;
|
params += indirect->stride / 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,15 +55,17 @@ util_draw_arrays(struct pipe_context *pipe,
|
||||||
uint count)
|
uint count)
|
||||||
{
|
{
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
info.mode = mode;
|
info.mode = mode;
|
||||||
info.start = start;
|
|
||||||
info.count = count;
|
|
||||||
info.min_index = start;
|
info.min_index = start;
|
||||||
info.max_index = start + count - 1;
|
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
|
static inline void
|
||||||
|
@ -75,17 +77,19 @@ util_draw_elements(struct pipe_context *pipe,
|
||||||
uint count)
|
uint count)
|
||||||
{
|
{
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
info.index.user = indices;
|
info.index.user = indices;
|
||||||
info.has_user_indices = true;
|
info.has_user_indices = true;
|
||||||
info.index_size = index_size;
|
info.index_size = index_size;
|
||||||
info.mode = mode;
|
info.mode = mode;
|
||||||
info.start = start;
|
|
||||||
info.count = count;
|
|
||||||
info.index_bias = index_bias;
|
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
|
static inline void
|
||||||
|
@ -97,18 +101,20 @@ util_draw_arrays_instanced(struct pipe_context *pipe,
|
||||||
uint instance_count)
|
uint instance_count)
|
||||||
{
|
{
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
info.mode = mode;
|
info.mode = mode;
|
||||||
info.start = start;
|
|
||||||
info.count = count;
|
|
||||||
info.start_instance = start_instance;
|
info.start_instance = start_instance;
|
||||||
info.instance_count = instance_count;
|
info.instance_count = instance_count;
|
||||||
info.index_bounds_valid = true;
|
info.index_bounds_valid = true;
|
||||||
info.min_index = start;
|
info.min_index = start;
|
||||||
info.max_index = start + count - 1;
|
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
|
static inline void
|
||||||
|
@ -123,19 +129,21 @@ util_draw_elements_instanced(struct pipe_context *pipe,
|
||||||
uint instance_count)
|
uint instance_count)
|
||||||
{
|
{
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
info.index.user = indices;
|
info.index.user = indices;
|
||||||
info.has_user_indices = true;
|
info.has_user_indices = true;
|
||||||
info.index_size = index_size;
|
info.index_size = index_size;
|
||||||
info.mode = mode;
|
info.mode = mode;
|
||||||
info.start = start;
|
|
||||||
info.count = count;
|
|
||||||
info.index_bias = index_bias;
|
info.index_bias = index_bias;
|
||||||
info.start_instance = start_instance;
|
info.start_instance = start_instance;
|
||||||
info.instance_count = instance_count;
|
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
|
void
|
||||||
util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state);
|
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
|
void
|
||||||
util_dump_draw_indirect_info(FILE *stream,
|
util_dump_draw_indirect_info(FILE *stream,
|
||||||
const struct pipe_draw_indirect_info *indirect);
|
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, uint, state, has_user_indices);
|
||||||
|
|
||||||
util_dump_member(stream, enum_prim_mode, state, mode);
|
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, start_instance);
|
||||||
util_dump_member(stream, uint, state, instance_count);
|
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);
|
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
|
void
|
||||||
util_dump_draw_indirect_info(FILE *stream,
|
util_dump_draw_indirect_info(FILE *stream,
|
||||||
const struct pipe_draw_indirect_info *state)
|
const struct pipe_draw_indirect_info *state)
|
||||||
|
|
|
@ -143,13 +143,14 @@ void util_set_shader_buffers_mask(struct pipe_shader_buffer *dst,
|
||||||
bool
|
bool
|
||||||
util_upload_index_buffer(struct pipe_context *pipe,
|
util_upload_index_buffer(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
struct pipe_resource **out_buffer,
|
struct pipe_resource **out_buffer,
|
||||||
unsigned *out_offset, unsigned alignment)
|
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,
|
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,
|
(char*)info->index.user + start_offset,
|
||||||
out_offset, out_buffer);
|
out_offset, out_buffer);
|
||||||
u_upload_unmap(pipe->stream_uploader);
|
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,
|
bool util_upload_index_buffer(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
struct pipe_resource **out_buffer,
|
struct pipe_resource **out_buffer,
|
||||||
unsigned *out_offset, unsigned alignment);
|
unsigned *out_offset, unsigned alignment);
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ enum pipe_error
|
||||||
util_translate_prim_restart_ib(struct pipe_context *context,
|
util_translate_prim_restart_ib(struct pipe_context *context,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
||||||
struct pipe_resource **dst_buffer)
|
struct pipe_resource **dst_buffer)
|
||||||
{
|
{
|
||||||
struct pipe_screen *screen = context->screen;
|
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;
|
const unsigned src_index_size = info->index_size;
|
||||||
unsigned dst_index_size;
|
unsigned dst_index_size;
|
||||||
DrawElementsIndirectCommand indirect;
|
DrawElementsIndirectCommand indirect;
|
||||||
unsigned count = info->count;
|
unsigned count = draw->count;
|
||||||
unsigned start = info->start;
|
unsigned start = draw->start;
|
||||||
|
|
||||||
/* 1-byte indexes are converted to 2-byte indexes, 4-byte stays 4-byte */
|
/* 1-byte indexes are converted to 2-byte indexes, 4-byte stays 4-byte */
|
||||||
dst_index_size = MAX2(2, info->index_size);
|
dst_index_size = MAX2(2, info->index_size);
|
||||||
|
@ -147,7 +148,7 @@ util_translate_prim_restart_ib(struct pipe_context *context,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
util_translate_prim_restart_data(src_index_size, src_map, dst_map,
|
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)
|
if (src_transfer)
|
||||||
pipe_buffer_unmap(context, 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
|
enum pipe_error
|
||||||
util_draw_vbo_without_prim_restart(struct pipe_context *context,
|
util_draw_vbo_without_prim_restart(struct pipe_context *context,
|
||||||
const struct pipe_draw_info *info,
|
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;
|
const void *src_map;
|
||||||
struct range_info ranges = {0};
|
struct range_info ranges = {0};
|
||||||
struct pipe_draw_info new_info;
|
struct pipe_draw_info new_info;
|
||||||
|
struct pipe_draw_start_count new_draw;
|
||||||
struct pipe_transfer *src_transfer = NULL;
|
struct pipe_transfer *src_transfer = NULL;
|
||||||
unsigned i, start, count;
|
unsigned i, start, count;
|
||||||
DrawElementsIndirectCommand indirect;
|
DrawElementsIndirectCommand indirect;
|
||||||
unsigned info_start = info->start;
|
unsigned info_start = draw->start;
|
||||||
unsigned info_count = info->count;
|
unsigned info_count = draw->count;
|
||||||
unsigned info_instance_count = info->instance_count;
|
unsigned info_instance_count = info->instance_count;
|
||||||
|
|
||||||
assert(info->index_size);
|
assert(info->index_size);
|
||||||
|
@ -308,13 +311,14 @@ util_draw_vbo_without_prim_restart(struct pipe_context *context,
|
||||||
|
|
||||||
/* draw ranges between the restart indexes */
|
/* draw ranges between the restart indexes */
|
||||||
new_info = *info;
|
new_info = *info;
|
||||||
|
new_draw = *draw;
|
||||||
/* we've effectively remapped this to a direct draw */
|
/* we've effectively remapped this to a direct draw */
|
||||||
new_info.instance_count = info_instance_count;
|
new_info.instance_count = info_instance_count;
|
||||||
new_info.primitive_restart = FALSE;
|
new_info.primitive_restart = FALSE;
|
||||||
for (i = 0; i < ranges.count; i++) {
|
for (i = 0; i < ranges.count; i++) {
|
||||||
new_info.start = ranges.ranges[i].start;
|
new_draw.start = ranges.ranges[i].start;
|
||||||
new_info.count = ranges.ranges[i].count;
|
new_draw.count = ranges.ranges[i].count;
|
||||||
context->draw_vbo(context, &new_info, NULL);
|
context->draw_vbo(context, &new_info, NULL, &new_draw, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FREE(ranges.ranges);
|
FREE(ranges.ranges);
|
||||||
|
|
|
@ -50,12 +50,14 @@ enum pipe_error
|
||||||
util_translate_prim_restart_ib(struct pipe_context *context,
|
util_translate_prim_restart_ib(struct pipe_context *context,
|
||||||
const struct pipe_draw_info *info,
|
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_resource **dst_buffer);
|
struct pipe_resource **dst_buffer);
|
||||||
|
|
||||||
enum pipe_error
|
enum pipe_error
|
||||||
util_draw_vbo_without_prim_restart(struct pipe_context *context,
|
util_draw_vbo_without_prim_restart(struct pipe_context *context,
|
||||||
const struct pipe_draw_info *info,
|
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
|
static inline unsigned
|
||||||
util_prim_restart_index_from_size(unsigned index_size)
|
util_prim_restart_index_from_size(unsigned index_size)
|
||||||
|
|
|
@ -64,6 +64,7 @@ enum tc_call_id {
|
||||||
* not needed. */
|
* not needed. */
|
||||||
struct tc_draw_single {
|
struct tc_draw_single {
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*tc_execute)(struct pipe_context *pipe, union tc_payload *payload);
|
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);
|
simplify_draw_info(&(*next_info)->info);
|
||||||
|
|
||||||
/* All fields must be the same except start and count. */
|
/* All fields must be the same except start and count. */
|
||||||
return memcmp((uint32_t*)&first_info->info + 2,
|
return memcmp((uint32_t*)&first_info->info,
|
||||||
(uint32_t*)&(*next_info)->info + 2,
|
(uint32_t*)&(*next_info)->info,
|
||||||
sizeof(struct pipe_draw_info) - 8) == 0;
|
sizeof(struct pipe_draw_info)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -161,10 +162,10 @@ tc_batch_execute(void *job, UNUSED int thread_index)
|
||||||
struct pipe_draw_start_count multi[256];
|
struct pipe_draw_start_count multi[256];
|
||||||
unsigned num_draws = 2;
|
unsigned num_draws = 2;
|
||||||
|
|
||||||
multi[0].start = first_info->info.start;
|
multi[0].start = first_info->draw.start;
|
||||||
multi[0].count = first_info->info.count;
|
multi[0].count = first_info->draw.count;
|
||||||
multi[1].start = next_info->info.start;
|
multi[1].start = next_info->draw.start;
|
||||||
multi[1].count = next_info->info.count;
|
multi[1].count = next_info->draw.count;
|
||||||
|
|
||||||
if (next_info->info.index_size)
|
if (next_info->info.index_size)
|
||||||
pipe_resource_reference(&next_info->info.index.resource, NULL);
|
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) &&
|
for (; next != last && num_draws < ARRAY_SIZE(multi) &&
|
||||||
is_next_call_a_mergeable_draw(first_info, next, &next_info);
|
is_next_call_a_mergeable_draw(first_info, next, &next_info);
|
||||||
next += next->num_call_slots, num_draws++) {
|
next += next->num_call_slots, num_draws++) {
|
||||||
multi[num_draws].start = next_info->info.start;
|
multi[num_draws].start = next_info->draw.start;
|
||||||
multi[num_draws].count = next_info->info.count;
|
multi[num_draws].count = next_info->draw.count;
|
||||||
|
|
||||||
if (next_info->info.index_size)
|
if (next_info->info.index_size)
|
||||||
pipe_resource_reference(&next_info->info.index.resource, NULL);
|
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)
|
if (first_info->info.index_size)
|
||||||
pipe_resource_reference(&first_info->info.index.resource, NULL);
|
pipe_resource_reference(&first_info->info.index.resource, NULL);
|
||||||
iter = next;
|
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;
|
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)
|
if (info->info.index_size)
|
||||||
pipe_resource_reference(&info->info.index.resource, NULL);
|
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 tc_draw_indirect {
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
struct pipe_draw_indirect_info indirect;
|
struct pipe_draw_indirect_info indirect;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
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;
|
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)
|
if (info->info.index_size)
|
||||||
pipe_resource_reference(&info->info.index.resource, NULL);
|
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
|
static void
|
||||||
tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
|
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);
|
struct threaded_context *tc = threaded_context(_pipe);
|
||||||
unsigned index_size = info->index_size;
|
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)) {
|
if (unlikely(indirect)) {
|
||||||
assert(!has_user_indices);
|
assert(!has_user_indices);
|
||||||
|
assert(num_draws == 1);
|
||||||
|
|
||||||
struct tc_draw_indirect *p =
|
struct tc_draw_indirect *p =
|
||||||
tc_add_struct_typed_call(tc, TC_CALL_draw_indirect, tc_draw_indirect);
|
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,
|
pipe_so_target_reference(&p->indirect.count_from_stream_output,
|
||||||
indirect->count_from_stream_output);
|
indirect->count_from_stream_output);
|
||||||
memcpy(&p->indirect, indirect, sizeof(*indirect));
|
memcpy(&p->indirect, indirect, sizeof(*indirect));
|
||||||
} else if (index_size && has_user_indices) {
|
p->draw.start = draws[0].start;
|
||||||
unsigned size = info->count * index_size;
|
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;
|
struct pipe_resource *buffer = NULL;
|
||||||
unsigned offset;
|
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.
|
* to the driver if it was done afterwards.
|
||||||
*/
|
*/
|
||||||
u_upload_data(tc->base.stream_uploader, 0, size, 4,
|
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);
|
&offset, &buffer);
|
||||||
if (unlikely(!buffer))
|
if (unlikely(!buffer))
|
||||||
return;
|
return;
|
||||||
|
@ -2300,7 +2311,8 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
|
||||||
memcpy(&p->info, info, sizeof(*info));
|
memcpy(&p->info, info, sizeof(*info));
|
||||||
p->info.has_user_indices = false;
|
p->info.has_user_indices = false;
|
||||||
p->info.index.resource = buffer;
|
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 {
|
} else {
|
||||||
/* Non-indexed call or indexed with a real index buffer. */
|
/* Non-indexed call or indexed with a real index buffer. */
|
||||||
struct tc_draw_single *p =
|
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);
|
info->index.resource);
|
||||||
}
|
}
|
||||||
memcpy(&p->info, info, sizeof(*info));
|
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
|
static enum pipe_error
|
||||||
u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
|
u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned vb_mask, unsigned out_vb,
|
unsigned vb_mask, unsigned out_vb,
|
||||||
int start_vertex, unsigned num_vertices,
|
int start_vertex, unsigned num_vertices,
|
||||||
int min_index, boolean unroll_indices)
|
int min_index, boolean unroll_indices)
|
||||||
|
@ -475,12 +476,12 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
|
||||||
/* Translate. */
|
/* Translate. */
|
||||||
if (unroll_indices) {
|
if (unroll_indices) {
|
||||||
struct pipe_transfer *transfer = NULL;
|
struct pipe_transfer *transfer = NULL;
|
||||||
const unsigned offset = info->start * info->index_size;
|
const unsigned offset = draw->start * info->index_size;
|
||||||
uint8_t *map;
|
uint8_t *map;
|
||||||
|
|
||||||
/* Create and map the output buffer. */
|
/* Create and map the output buffer. */
|
||||||
u_upload_alloc(mgr->pipe->stream_uploader, 0,
|
u_upload_alloc(mgr->pipe->stream_uploader, 0,
|
||||||
key->output_stride * info->count, 4,
|
key->output_stride * draw->count, 4,
|
||||||
&out_offset, &out_buffer,
|
&out_offset, &out_buffer,
|
||||||
(void**)&out_map);
|
(void**)&out_map);
|
||||||
if (!out_buffer)
|
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;
|
map = (uint8_t*)info->index.user + offset;
|
||||||
} else {
|
} else {
|
||||||
map = pipe_buffer_map_range(mgr->pipe, info->index.resource, offset,
|
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);
|
PIPE_MAP_READ, &transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (info->index_size) {
|
switch (info->index_size) {
|
||||||
case 4:
|
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;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
case 1:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,6 +612,7 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
|
||||||
static boolean
|
static boolean
|
||||||
u_vbuf_translate_begin(struct u_vbuf *mgr,
|
u_vbuf_translate_begin(struct u_vbuf *mgr,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
int start_vertex, unsigned num_vertices,
|
int start_vertex, unsigned num_vertices,
|
||||||
int min_index, boolean unroll_indices)
|
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++) {
|
for (type = 0; type < VB_NUM; type++) {
|
||||||
if (key[type].nr_elements) {
|
if (key[type].nr_elements) {
|
||||||
enum pipe_error err;
|
enum pipe_error err;
|
||||||
err = u_vbuf_translate_buffers(mgr, &key[type], info, mask[type],
|
err = u_vbuf_translate_buffers(mgr, &key[type], info, draw,
|
||||||
mgr->fallback_vbs[type],
|
mask[type], mgr->fallback_vbs[type],
|
||||||
start[type], num[type], min_index,
|
start[type], num[type], min_index,
|
||||||
unroll_indices && type == VB_VERTEX);
|
unroll_indices && type == VB_VERTEX);
|
||||||
if (err != PIPE_OK)
|
if (err != PIPE_OK)
|
||||||
|
@ -1133,10 +1135,11 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(const struct u_vbuf *mgr)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
|
u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
|
||||||
|
unsigned count,
|
||||||
const void *indices, unsigned *out_min_index,
|
const void *indices, unsigned *out_min_index,
|
||||||
unsigned *out_max_index)
|
unsigned *out_max_index)
|
||||||
{
|
{
|
||||||
if (!info->count) {
|
if (!count) {
|
||||||
*out_min_index = 0;
|
*out_min_index = 0;
|
||||||
*out_max_index = 0;
|
*out_max_index = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -1148,7 +1151,7 @@ u_vbuf_get_minmax_index_mapped(const struct pipe_draw_info *info,
|
||||||
unsigned max = 0;
|
unsigned max = 0;
|
||||||
unsigned min = ~0u;
|
unsigned min = ~0u;
|
||||||
if (info->primitive_restart) {
|
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] != info->restart_index) {
|
||||||
if (ui_indices[i] > max) max = ui_indices[i];
|
if (ui_indices[i] > max) max = ui_indices[i];
|
||||||
if (ui_indices[i] < min) min = 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 {
|
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] > max) max = ui_indices[i];
|
||||||
if (ui_indices[i] < min) min = 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 max = 0;
|
||||||
unsigned short min = ~((unsigned short)0);
|
unsigned short min = ~((unsigned short)0);
|
||||||
if (info->primitive_restart) {
|
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] != info->restart_index) {
|
||||||
if (us_indices[i] > max) max = us_indices[i];
|
if (us_indices[i] > max) max = us_indices[i];
|
||||||
if (us_indices[i] < min) min = 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 {
|
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] > max) max = us_indices[i];
|
||||||
if (us_indices[i] < min) min = 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 max = 0;
|
||||||
unsigned char min = ~((unsigned char)0);
|
unsigned char min = ~((unsigned char)0);
|
||||||
if (info->primitive_restart) {
|
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] != info->restart_index) {
|
||||||
if (ub_indices[i] > max) max = ub_indices[i];
|
if (ub_indices[i] > max) max = ub_indices[i];
|
||||||
if (ub_indices[i] < min) min = 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 {
|
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] > max) max = ub_indices[i];
|
||||||
if (ub_indices[i] < min) min = 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,
|
void u_vbuf_get_minmax_index(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned *out_min_index, unsigned *out_max_index)
|
unsigned *out_min_index, unsigned *out_max_index)
|
||||||
{
|
{
|
||||||
struct pipe_transfer *transfer = NULL;
|
struct pipe_transfer *transfer = NULL;
|
||||||
|
@ -1223,15 +1227,16 @@ void u_vbuf_get_minmax_index(struct pipe_context *pipe,
|
||||||
|
|
||||||
if (info->has_user_indices) {
|
if (info->has_user_indices) {
|
||||||
indices = (uint8_t*)info->index.user +
|
indices = (uint8_t*)info->index.user +
|
||||||
info->start * info->index_size;
|
draw->start * info->index_size;
|
||||||
} else {
|
} else {
|
||||||
indices = pipe_buffer_map_range(pipe, info->index.resource,
|
indices = pipe_buffer_map_range(pipe, info->index.resource,
|
||||||
info->start * info->index_size,
|
draw->start * info->index_size,
|
||||||
info->count * info->index_size,
|
draw->count * info->index_size,
|
||||||
PIPE_MAP_READ, &transfer);
|
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) {
|
if (transfer) {
|
||||||
pipe_buffer_unmap(pipe, 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);
|
assert(info->index_size);
|
||||||
|
|
||||||
for (unsigned i = 0; i < draw_count; i++) {
|
for (unsigned i = 0; i < draw_count; i++) {
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
unsigned offset = i * stride / 4;
|
unsigned offset = i * stride / 4;
|
||||||
|
|
||||||
info->count = indirect_data[offset + 0];
|
draw.count = indirect_data[offset + 0];
|
||||||
info->instance_count = indirect_data[offset + 1];
|
info->instance_count = indirect_data[offset + 1];
|
||||||
|
|
||||||
if (!info->count || !info->instance_count)
|
if (!draw.count || !info->instance_count)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
info->start = indirect_data[offset + 2];
|
draw.start = indirect_data[offset + 2];
|
||||||
info->index_bias = indirect_data[offset + 3];
|
info->index_bias = indirect_data[offset + 3];
|
||||||
info->start_instance = indirect_data[offset + 4];
|
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,
|
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;
|
struct pipe_context *pipe = mgr->pipe;
|
||||||
int start_vertex;
|
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 =
|
const uint32_t incompatible_vb_mask =
|
||||||
mgr->incompatible_vb_mask & used_vb_mask;
|
mgr->incompatible_vb_mask & used_vb_mask;
|
||||||
struct pipe_draw_info new_info;
|
struct pipe_draw_info new_info;
|
||||||
|
struct pipe_draw_start_count new_draw;
|
||||||
|
|
||||||
/* Normal draw. No fallback and no user buffers. */
|
/* Normal draw. No fallback and no user buffers. */
|
||||||
if (!incompatible_vb_mask &&
|
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);
|
u_vbuf_set_driver_vertex_buffers(mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe->draw_vbo(pipe, info, indirect);
|
pipe->draw_vbo(pipe, info, indirect, &draw, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_info = *info;
|
new_info = *info;
|
||||||
|
new_draw = draw;
|
||||||
|
|
||||||
/* Handle indirect (multi)draws. */
|
/* Handle indirect (multi)draws. */
|
||||||
if (indirect && indirect->buffer) {
|
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. */
|
/* Update the index range. */
|
||||||
unsigned min, max;
|
unsigned min, max;
|
||||||
new_info.count = count; /* only used by get_minmax_index */
|
u_vbuf_get_minmax_index_mapped(&new_info, count,
|
||||||
u_vbuf_get_minmax_index_mapped(&new_info,
|
|
||||||
indices +
|
indices +
|
||||||
new_info.index_size * start,
|
new_info.index_size * start,
|
||||||
&min, &max);
|
&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
|
* This efficiently processes the multidraw with the time complexity
|
||||||
* equal to 1 draw call.
|
* equal to 1 draw call.
|
||||||
*/
|
*/
|
||||||
new_info.start = ~0u;
|
new_draw.start = ~0u;
|
||||||
new_info.start_instance = ~0u;
|
new_info.start_instance = ~0u;
|
||||||
unsigned end_vertex = 0;
|
unsigned end_vertex = 0;
|
||||||
unsigned end_instance = 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 start_instance = data[offset + 3];
|
||||||
unsigned instance_count = data[offset + 1];
|
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,
|
new_info.start_instance = MIN2(new_info.start_instance,
|
||||||
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);
|
free(data);
|
||||||
|
|
||||||
/* Set the final counts. */
|
/* 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;
|
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;
|
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;
|
min_index = new_info.min_index;
|
||||||
max_index = new_info.max_index;
|
max_index = new_info.max_index;
|
||||||
} else {
|
} 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);
|
&min_index, &max_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1489,7 +1497,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
||||||
* performance. */
|
* performance. */
|
||||||
if (!indirect &&
|
if (!indirect &&
|
||||||
!new_info.primitive_restart &&
|
!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)) {
|
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
|
||||||
unroll_indices = TRUE;
|
unroll_indices = TRUE;
|
||||||
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
|
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;
|
min_index = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
start_vertex = new_info.start;
|
start_vertex = new_draw.start;
|
||||||
num_vertices = new_info.count;
|
num_vertices = new_draw.count;
|
||||||
min_index = 0;
|
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 ||
|
if (unroll_indices ||
|
||||||
incompatible_vb_mask ||
|
incompatible_vb_mask ||
|
||||||
mgr->ve->incompatible_elem_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)) {
|
min_index, unroll_indices)) {
|
||||||
debug_warn_once("u_vbuf_translate_begin() failed");
|
debug_warn_once("u_vbuf_translate_begin() failed");
|
||||||
return;
|
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_size = 0;
|
||||||
new_info.index_bias = 0;
|
new_info.index_bias = 0;
|
||||||
new_info.min_index = 0;
|
new_info.min_index = 0;
|
||||||
new_info.max_index = new_info.count - 1;
|
new_info.max_index = new_draw.count - 1;
|
||||||
new_info.start = 0;
|
new_draw.start = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
user_vb_mask &= ~(incompatible_vb_mask |
|
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_upload_unmap(pipe->stream_uploader);
|
||||||
u_vbuf_set_driver_vertex_buffers(mgr);
|
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) {
|
if (mgr->using_translate) {
|
||||||
u_vbuf_translate_end(mgr);
|
u_vbuf_translate_end(mgr);
|
||||||
|
|
|
@ -78,9 +78,11 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr,
|
||||||
unsigned start_slot, unsigned count,
|
unsigned start_slot, unsigned count,
|
||||||
const struct pipe_vertex_buffer *bufs);
|
const struct pipe_vertex_buffer *bufs);
|
||||||
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
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,
|
void u_vbuf_get_minmax_index(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned *out_min_index, unsigned *out_max_index);
|
unsigned *out_min_index, unsigned *out_max_index);
|
||||||
|
|
||||||
/* Save/restore functionality. */
|
/* Save/restore functionality. */
|
||||||
|
|
|
@ -320,7 +320,9 @@ d3d12_apply_resource_states(struct d3d12_context* ctx);
|
||||||
void
|
void
|
||||||
d3d12_draw_vbo(struct pipe_context *pctx,
|
d3d12_draw_vbo(struct pipe_context *pctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
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
|
void
|
||||||
d3d12_blit(struct pipe_context *pctx,
|
d3d12_blit(struct pipe_context *pctx,
|
||||||
|
|
|
@ -166,6 +166,7 @@ fill_sampler_descriptors(struct d3d12_context *ctx,
|
||||||
static unsigned
|
static unsigned
|
||||||
fill_state_vars(struct d3d12_context *ctx,
|
fill_state_vars(struct d3d12_context *ctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
const struct pipe_draw_info *dinfo,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
struct d3d12_shader *shader,
|
struct d3d12_shader *shader,
|
||||||
uint32_t *values)
|
uint32_t *values)
|
||||||
{
|
{
|
||||||
|
@ -187,7 +188,7 @@ fill_state_vars(struct d3d12_context *ctx,
|
||||||
size += 4;
|
size += 4;
|
||||||
break;
|
break;
|
||||||
case D3D12_STATE_VAR_FIRST_VERTEX:
|
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;
|
size += 4;
|
||||||
break;
|
break;
|
||||||
case D3D12_STATE_VAR_DEPTH_TRANSFORM:
|
case D3D12_STATE_VAR_DEPTH_TRANSFORM:
|
||||||
|
@ -240,7 +241,8 @@ check_descriptors_left(struct d3d12_context *ctx)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_graphics_root_parameters(struct d3d12_context *ctx,
|
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;
|
unsigned num_params = 0;
|
||||||
|
|
||||||
|
@ -269,7 +271,7 @@ set_graphics_root_parameters(struct d3d12_context *ctx,
|
||||||
/* TODO Don't always update state vars */
|
/* TODO Don't always update state vars */
|
||||||
if (shader->num_state_vars > 0) {
|
if (shader->num_state_vars > 0) {
|
||||||
uint32_t constants[D3D12_MAX_STATE_VARS * 4];
|
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);
|
ctx->cmdlist->SetGraphicsRoot32BitConstants(num_params, size, constants, 0);
|
||||||
num_params++;
|
num_params++;
|
||||||
}
|
}
|
||||||
|
@ -353,11 +355,12 @@ ib_format(unsigned index_size)
|
||||||
static void
|
static void
|
||||||
twoface_emulation(struct d3d12_context *ctx,
|
twoface_emulation(struct d3d12_context *ctx,
|
||||||
struct d3d12_rasterizer_state *rast,
|
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 */
|
/* draw backfaces */
|
||||||
ctx->base.bind_rasterizer_state(&ctx->base, rast->twoface_back);
|
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 */
|
/* restore real state */
|
||||||
ctx->base.bind_rasterizer_state(&ctx->base, rast);
|
ctx->base.bind_rasterizer_state(&ctx->base, rast);
|
||||||
|
@ -417,7 +420,9 @@ d3d12_last_vertex_stage(struct d3d12_context *ctx)
|
||||||
void
|
void
|
||||||
d3d12_draw_vbo(struct pipe_context *pctx,
|
d3d12_draw_vbo(struct pipe_context *pctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
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_context *ctx = d3d12_context(pctx);
|
||||||
struct d3d12_batch *batch;
|
struct d3d12_batch *batch;
|
||||||
|
@ -431,12 +436,12 @@ d3d12_draw_vbo(struct pipe_context *pctx,
|
||||||
dinfo->restart_index != 0xffffffff)) {
|
dinfo->restart_index != 0xffffffff)) {
|
||||||
|
|
||||||
if (!dinfo->primitive_restart &&
|
if (!dinfo->primitive_restart &&
|
||||||
!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count))
|
!u_trim_pipe_prim(dinfo->mode, (unsigned *)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx->initial_api_prim = dinfo->mode;
|
ctx->initial_api_prim = dinfo->mode;
|
||||||
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->gfx_pipeline_state.rast->base);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +457,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
|
||||||
struct d3d12_rasterizer_state *rast = ctx->gfx_pipeline_state.rast;
|
struct d3d12_rasterizer_state *rast = ctx->gfx_pipeline_state.rast;
|
||||||
if (rast->twoface_back) {
|
if (rast->twoface_back) {
|
||||||
enum pipe_prim_type saved_mode = ctx->initial_api_prim;
|
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;
|
ctx->initial_api_prim = saved_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +509,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
|
||||||
assert(dinfo->index_size != 1);
|
assert(dinfo->index_size != 1);
|
||||||
|
|
||||||
if (dinfo->has_user_indices) {
|
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)) {
|
&index_offset, 4)) {
|
||||||
debug_printf("util_upload_index_buffer() failed\n");
|
debug_printf("util_upload_index_buffer() failed\n");
|
||||||
return;
|
return;
|
||||||
|
@ -559,7 +564,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
|
||||||
ctx->cmdlist->SetPipelineState(ctx->current_pso);
|
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);
|
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) {
|
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);
|
d3d12_apply_resource_states(ctx);
|
||||||
|
|
||||||
if (dinfo->index_size > 0)
|
if (dinfo->index_size > 0)
|
||||||
ctx->cmdlist->DrawIndexedInstanced(dinfo->count, dinfo->instance_count,
|
ctx->cmdlist->DrawIndexedInstanced(draws[0].count, dinfo->instance_count,
|
||||||
dinfo->start, dinfo->index_bias,
|
draws[0].start, dinfo->index_bias,
|
||||||
dinfo->start_instance);
|
dinfo->start_instance);
|
||||||
else
|
else
|
||||||
ctx->cmdlist->DrawInstanced(dinfo->count, dinfo->instance_count,
|
ctx->cmdlist->DrawInstanced(draws[0].count, dinfo->instance_count,
|
||||||
dinfo->start, dinfo->start_instance);
|
draws[0].start, dinfo->start_instance);
|
||||||
|
|
||||||
ctx->state_dirty = 0;
|
ctx->state_dirty = 0;
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,9 @@ etna_get_fs(struct etna_context *ctx, struct etna_shader_key key)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
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_context *ctx = etna_context(pctx);
|
||||||
struct etna_screen *screen = ctx->screen;
|
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 &&
|
if (!indirect &&
|
||||||
!info->primitive_restart &&
|
!info->primitive_restart &&
|
||||||
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctx->vertex_elements == NULL || ctx->vertex_elements->num_elements == 0)
|
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))) {
|
if (!(ctx->prim_hwsupport & (1 << info->mode))) {
|
||||||
struct primconvert_context *primconvert = ctx->primconvert;
|
struct primconvert_context *primconvert = ctx->primconvert;
|
||||||
util_primconvert_save_rasterizer_state(primconvert, ctx->rasterizer);
|
util_primconvert_save_rasterizer_state(primconvert, ctx->rasterizer);
|
||||||
util_primconvert_draw_vbo(primconvert, info);
|
util_primconvert_draw_vbo(primconvert, info, &draws[0]);
|
||||||
return;
|
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)) {
|
if (unlikely(prims <= 0)) {
|
||||||
DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode);
|
DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode);
|
||||||
return;
|
return;
|
||||||
|
@ -266,12 +268,12 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
indexbuf = info->has_user_indices ? NULL : info->index.resource;
|
indexbuf = info->has_user_indices ? NULL : info->index.resource;
|
||||||
if (info->has_user_indices &&
|
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.");
|
BUG("Index buffer upload failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Add start to index offset, when rendering indexed */
|
/* 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.bo = etna_resource(indexbuf)->bo;
|
||||||
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.offset = index_offset;
|
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++;
|
ctx->stats.draw_calls++;
|
||||||
|
|
||||||
/* Update state for this draw operation */
|
/* 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) {
|
if (screen->specs.halti >= 2) {
|
||||||
/* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */
|
/* 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,
|
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 {
|
} else {
|
||||||
if (info->index_size)
|
if (info->index_size)
|
||||||
etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, info->index_bias);
|
etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, info->index_bias);
|
||||||
else
|
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)) {
|
if (DBG_ENABLED(ETNA_DBG_DRAW_STALL)) {
|
||||||
|
|
|
@ -80,11 +80,12 @@ emit_vertexbufs(struct fd_context *ctx)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
|
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)
|
struct fd_ringbuffer *ring, unsigned index_offset, bool binning)
|
||||||
{
|
{
|
||||||
OUT_PKT3(ring, CP_SET_CONSTANT, 2);
|
OUT_PKT3(ring, CP_SET_CONSTANT, 2);
|
||||||
OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET));
|
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_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
|
||||||
OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
|
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;
|
vismode = IGNORE_VISIBILITY;
|
||||||
|
|
||||||
fd_draw_emit(ctx->batch, ring, ctx->primtypes[info->mode],
|
fd_draw_emit(ctx->batch, ring, ctx->primtypes[info->mode],
|
||||||
vismode, info, index_offset);
|
vismode, info, draw, index_offset);
|
||||||
|
|
||||||
if (is_a20x(ctx->screen)) {
|
if (is_a20x(ctx->screen)) {
|
||||||
/* not sure why this is required, but it fixes some hangs */
|
/* 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
|
static bool
|
||||||
fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *pinfo,
|
fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *pinfo,
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count *pdraw,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
if (!ctx->prog.fs || !ctx->prog.vs)
|
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
|
* using a limit of 32k because it fixes an unexplained hang
|
||||||
* 32766 works for all primitives (multiple of 2 and 3)
|
* 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] = {
|
static const uint16_t step_tbl[PIPE_PRIM_MAX] = {
|
||||||
[0 ... PIPE_PRIM_MAX - 1] = 32766,
|
[0 ... PIPE_PRIM_MAX - 1] = 32766,
|
||||||
[PIPE_PRIM_LINE_STRIP] = 32765,
|
[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,
|
[PIPE_PRIM_LINE_LOOP] = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pipe_draw_info info = *pinfo;
|
struct pipe_draw_start_count draw = *pdraw;
|
||||||
unsigned count = info.count;
|
unsigned count = draw.count;
|
||||||
unsigned step = step_tbl[info.mode];
|
unsigned step = step_tbl[pinfo->mode];
|
||||||
unsigned num_vertices = ctx->batch->num_vertices;
|
unsigned num_vertices = ctx->batch->num_vertices;
|
||||||
|
|
||||||
if (!step)
|
if (!step)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (; count + step > 32766; count -= step) {
|
for (; count + step > 32766; count -= step) {
|
||||||
info.count = MIN2(count, 32766);
|
draw.count = MIN2(count, 32766);
|
||||||
draw_impl(ctx, &info, ctx->batch->draw, index_offset, false);
|
draw_impl(ctx, pinfo, &draw, ctx->batch->draw, index_offset, false);
|
||||||
draw_impl(ctx, &info, ctx->batch->binning, index_offset, true);
|
draw_impl(ctx, pinfo, &draw, ctx->batch->binning, index_offset, true);
|
||||||
info.start += step;
|
draw.start += step;
|
||||||
ctx->batch->num_vertices += step;
|
ctx->batch->num_vertices += step;
|
||||||
}
|
}
|
||||||
/* changing this value is a hack, restore it */
|
/* changing this value is a hack, restore it */
|
||||||
ctx->batch->num_vertices = num_vertices;
|
ctx->batch->num_vertices = num_vertices;
|
||||||
} else {
|
} else {
|
||||||
draw_impl(ctx, pinfo, ctx->batch->draw, index_offset, false);
|
draw_impl(ctx, pinfo, pdraw, ctx->batch->draw, index_offset, false);
|
||||||
draw_impl(ctx, pinfo, ctx->batch->binning, index_offset, true);
|
draw_impl(ctx, pinfo, pdraw, ctx->batch->binning, index_offset, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_context_all_clean(ctx);
|
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->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, add_sat(info->max_index, info->index_bias)); /* VFD_INDEX_MAX */
|
||||||
OUT_RING(ring, info->start_instance); /* VFD_INSTANCEID_OFFSET */
|
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_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
|
||||||
OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
|
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,
|
fd_draw_emit(ctx->batch, ring, primtype,
|
||||||
emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
|
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-
|
/* 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
|
static bool
|
||||||
fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
|
fd3_draw_vbo(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,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
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,
|
.prog = &ctx->prog,
|
||||||
.info = info,
|
.info = info,
|
||||||
.indirect = indirect,
|
.indirect = indirect,
|
||||||
|
.draw = draw,
|
||||||
.key = {
|
.key = {
|
||||||
.color_two_side = ctx->rasterizer->light_twoside,
|
.color_two_side = ctx->rasterizer->light_twoside,
|
||||||
.vclamp_color = ctx->rasterizer->clamp_vertex_color,
|
.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);
|
OUT_RING(ring, HLSQ_FLUSH);
|
||||||
|
|
||||||
if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */
|
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)
|
if (!emit->binning_pass)
|
||||||
ir3_emit_fs_consts(fp, ring, ctx);
|
ir3_emit_fs_consts(fp, ring, ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct fd3_emit {
|
||||||
const struct fd_program_stateobj *prog;
|
const struct fd_program_stateobj *prog;
|
||||||
const struct pipe_draw_info *info;
|
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 binning_pass;
|
bool binning_pass;
|
||||||
struct ir3_shader_key key;
|
struct ir3_shader_key key;
|
||||||
enum fd_dirty_3d_state dirty;
|
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);
|
fd4_emit_vertex_bufs(ring, emit);
|
||||||
|
|
||||||
OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
|
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_RING(ring, info->start_instance); /* ??? UNKNOWN_2209 */
|
||||||
|
|
||||||
OUT_PKT0(ring, REG_A4XX_PC_RESTART_INDEX, 1);
|
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,
|
fd4_draw_emit(ctx->batch, ring, primtype,
|
||||||
emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
|
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-
|
/* 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
|
static bool
|
||||||
fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
|
fd4_draw_vbo(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,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct fd4_context *fd4_ctx = fd4_context(ctx);
|
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,
|
.prog = &ctx->prog,
|
||||||
.info = info,
|
.info = info,
|
||||||
.indirect = indirect,
|
.indirect = indirect,
|
||||||
|
.draw = draw,
|
||||||
.key = {
|
.key = {
|
||||||
.color_two_side = ctx->rasterizer->light_twoside,
|
.color_two_side = ctx->rasterizer->light_twoside,
|
||||||
.vclamp_color = ctx->rasterizer->clamp_vertex_color,
|
.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,
|
enum pc_di_vis_cull_mode vismode,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct pipe_resource *idx_buffer = NULL;
|
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_buffer = info->index.resource;
|
||||||
idx_type = fd4_size2indextype(info->index_size);
|
idx_type = fd4_size2indextype(info->index_size);
|
||||||
idx_size = info->index_size * info->count;
|
idx_size = info->index_size * draw->count;
|
||||||
idx_offset = index_offset + info->start * info->index_size;
|
idx_offset = index_offset + draw->start * info->index_size;
|
||||||
src_sel = DI_SRC_SEL_DMA;
|
src_sel = DI_SRC_SEL_DMA;
|
||||||
} else {
|
} else {
|
||||||
idx_buffer = NULL;
|
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,
|
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);
|
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 */
|
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)
|
if (!emit->binning_pass)
|
||||||
ir3_emit_fs_consts(fp, ring, ctx);
|
ir3_emit_fs_consts(fp, ring, ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct fd4_emit {
|
||||||
const struct fd_program_stateobj *prog;
|
const struct fd_program_stateobj *prog;
|
||||||
const struct pipe_draw_info *info;
|
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 binning_pass;
|
bool binning_pass;
|
||||||
struct ir3_shader_key key;
|
struct ir3_shader_key key;
|
||||||
enum fd_dirty_3d_state dirty;
|
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);
|
fd5_emit_vertex_bufs(ring, emit);
|
||||||
|
|
||||||
OUT_PKT4(ring, REG_A5XX_VFD_INDEX_OFFSET, 2);
|
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_RING(ring, info->start_instance); /* VFD_INSTANCE_START_OFFSET */
|
||||||
|
|
||||||
OUT_PKT4(ring, REG_A5XX_PC_RESTART_INDEX, 1);
|
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_emit_render_cntl(ctx, false, emit->binning_pass);
|
||||||
fd5_draw_emit(ctx->batch, ring, primtype,
|
fd5_draw_emit(ctx->batch, ring, primtype,
|
||||||
emit->binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
|
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-
|
/* 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
|
static bool
|
||||||
fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
|
fd5_draw_vbo(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,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct fd5_context *fd5_ctx = fd5_context(ctx);
|
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,
|
.prog = &ctx->prog,
|
||||||
.info = info,
|
.info = info,
|
||||||
.indirect = indirect,
|
.indirect = indirect,
|
||||||
|
.draw = draw,
|
||||||
.key = {
|
.key = {
|
||||||
.color_two_side = ctx->rasterizer->light_twoside,
|
.color_two_side = ctx->rasterizer->light_twoside,
|
||||||
.vclamp_color = ctx->rasterizer->clamp_vertex_color,
|
.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,
|
enum pc_di_vis_cull_mode vismode,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct pipe_resource *idx_buffer = NULL;
|
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_buffer = info->index.resource;
|
||||||
idx_type = fd4_size2indextype(info->index_size);
|
idx_type = fd4_size2indextype(info->index_size);
|
||||||
max_indices = idx_buffer->width0 / 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;
|
src_sel = DI_SRC_SEL_DMA;
|
||||||
} else {
|
} else {
|
||||||
idx_buffer = NULL;
|
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,
|
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);
|
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)));
|
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)
|
if (!emit->binning_pass)
|
||||||
ir3_emit_fs_consts(fp, ring, ctx);
|
ir3_emit_fs_consts(fp, ring, ctx);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct fd5_emit {
|
||||||
const struct fd_program_stateobj *prog;
|
const struct fd_program_stateobj *prog;
|
||||||
const struct pipe_draw_info *info;
|
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 binning_pass;
|
bool binning_pass;
|
||||||
struct ir3_shader_key key;
|
struct ir3_shader_key key;
|
||||||
enum fd_dirty_3d_state dirty;
|
enum fd_dirty_3d_state dirty;
|
||||||
|
|
|
@ -359,7 +359,7 @@ fd6_emit_consts(struct fd6_emit *emit)
|
||||||
if (ir3_needs_vs_driver_params(vs)) {
|
if (ir3_needs_vs_driver_params(vs)) {
|
||||||
struct fd_ringbuffer *dpconstobj = fd_submit_new_ringbuffer(
|
struct fd_ringbuffer *dpconstobj = fd_submit_new_ringbuffer(
|
||||||
ctx->batch->submit, IR3_DP_VS_COUNT * 4, FD_RINGBUFFER_STREAMING);
|
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_emit_take_group(emit, dpconstobj, FD6_GROUP_VS_DRIVER_PARAMS, ENABLE_ALL);
|
||||||
fd6_ctx->has_dp_state = true;
|
fd6_ctx->has_dp_state = true;
|
||||||
} else if (fd6_ctx->has_dp_state) {
|
} else if (fd6_ctx->has_dp_state) {
|
||||||
|
|
|
@ -77,6 +77,7 @@ static void
|
||||||
draw_emit(struct fd_ringbuffer *ring,
|
draw_emit(struct fd_ringbuffer *ring,
|
||||||
struct CP_DRAW_INDX_OFFSET_0 *draw0,
|
struct CP_DRAW_INDX_OFFSET_0 *draw0,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
|
@ -88,8 +89,8 @@ draw_emit(struct fd_ringbuffer *ring,
|
||||||
OUT_PKT(ring, CP_DRAW_INDX_OFFSET,
|
OUT_PKT(ring, CP_DRAW_INDX_OFFSET,
|
||||||
pack_CP_DRAW_INDX_OFFSET_0(*draw0),
|
pack_CP_DRAW_INDX_OFFSET_0(*draw0),
|
||||||
CP_DRAW_INDX_OFFSET_1(.num_instances = info->instance_count),
|
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),
|
||||||
CP_DRAW_INDX_OFFSET_3(.first_indx = info->start),
|
CP_DRAW_INDX_OFFSET_3(.first_indx = draw->start),
|
||||||
A5XX_CP_DRAW_INDX_OFFSET_INDX_BASE(
|
A5XX_CP_DRAW_INDX_OFFSET_INDX_BASE(
|
||||||
fd_resource(idx_buffer)->bo, index_offset),
|
fd_resource(idx_buffer)->bo, index_offset),
|
||||||
A5XX_CP_DRAW_INDX_OFFSET_6(.max_indices = max_indices)
|
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,
|
OUT_PKT(ring, CP_DRAW_INDX_OFFSET,
|
||||||
pack_CP_DRAW_INDX_OFFSET_0(*draw0),
|
pack_CP_DRAW_INDX_OFFSET_0(*draw0),
|
||||||
CP_DRAW_INDX_OFFSET_1(.num_instances = info->instance_count),
|
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
|
static bool
|
||||||
fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
|
fd6_draw_vbo(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,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct fd6_context *fd6_ctx = fd6_context(ctx);
|
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,
|
.vtx = &ctx->vtx,
|
||||||
.info = info,
|
.info = info,
|
||||||
.indirect = indirect,
|
.indirect = indirect,
|
||||||
|
.draw = draw,
|
||||||
.key = {
|
.key = {
|
||||||
.vs = ctx->prog.vs,
|
.vs = ctx->prog.vs,
|
||||||
.gs = ctx->prog.gs,
|
.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;
|
emit.key.key.has_gs = true;
|
||||||
|
|
||||||
if (!(emit.key.hs || emit.key.ds || emit.key.gs || (indirect && indirect->buffer)))
|
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);
|
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->tessellation = true;
|
||||||
ctx->batch->tessparam_size = MAX2(ctx->batch->tessparam_size,
|
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,
|
ctx->batch->tessfactor_size = MAX2(ctx->batch->tessfactor_size,
|
||||||
factor_stride * info->count);
|
factor_stride * draw->count);
|
||||||
|
|
||||||
if (!ctx->batch->tess_addrs_constobj) {
|
if (!ctx->batch->tess_addrs_constobj) {
|
||||||
/* Reserve space for the bo address - we'll write them later in
|
/* 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)) {
|
if (ctx->last.dirty || (ctx->last.index_start != index_start)) {
|
||||||
OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 1);
|
OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 1);
|
||||||
OUT_RING(ring, index_start); /* VFD_INDEX_OFFSET */
|
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) {
|
if (indirect && indirect->buffer) {
|
||||||
draw_emit_indirect(ring, &draw0, info, indirect, index_offset);
|
draw_emit_indirect(ring, &draw0, info, indirect, index_offset);
|
||||||
} else {
|
} else {
|
||||||
draw_emit(ring, &draw0, info, index_offset);
|
draw_emit(ring, &draw0, info, draw, index_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_marker6(ring, 7);
|
emit_marker6(ring, 7);
|
||||||
|
|
|
@ -87,6 +87,7 @@ struct fd6_emit {
|
||||||
const struct fd_vertex_state *vtx;
|
const struct fd_vertex_state *vtx;
|
||||||
const struct pipe_draw_info *info;
|
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 ir3_cache_key key;
|
struct ir3_cache_key key;
|
||||||
enum fd_dirty_3d_state dirty;
|
enum fd_dirty_3d_state dirty;
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,13 @@ bitfield_size_bits(unsigned n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
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: */
|
/* PIPE_PRIM_MAX used internally for RECTLIST blits on 3d pipe: */
|
||||||
unsigned vtx_per_prim = (info->mode == PIPE_PRIM_MAX) ? 2 :
|
unsigned vtx_per_prim = (info->mode == PIPE_PRIM_MAX) ? 2 :
|
||||||
u_vertices_per_prim(info->mode);
|
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
|
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format#primitive-streams
|
||||||
*/
|
*/
|
||||||
static unsigned
|
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 =
|
unsigned nbits =
|
||||||
(bitfield_size_bits(num_bins) /* bitfield of bins covered */
|
(bitfield_size_bits(num_bins) /* bitfield of bins covered */
|
||||||
+ number_size_bits(1) /* number of primitives with this bitset */
|
+ 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
|
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) {
|
if (!batch->num_bins_per_pipe) {
|
||||||
batch->num_bins_per_pipe = fd_gmem_estimate_bins_per_pipe(batch);
|
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 =
|
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 =
|
unsigned draw_strm_bits =
|
||||||
draw_stream_size_bits(info, batch->num_bins_per_pipe, prim_strm_bits);
|
draw_stream_size_bits(info, batch->num_bins_per_pipe, prim_strm_bits);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#ifndef FD6_VSC_H_
|
#ifndef FD6_VSC_H_
|
||||||
#define 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_ */
|
#endif /* FD6_VSC_H_ */
|
||||||
|
|
|
@ -234,11 +234,13 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers,
|
||||||
|
|
||||||
struct pipe_draw_info info = {
|
struct pipe_draw_info info = {
|
||||||
.mode = PIPE_PRIM_MAX, /* maps to DI_PT_RECTLIST */
|
.mode = PIPE_PRIM_MAX, /* maps to DI_PT_RECTLIST */
|
||||||
.count = 2,
|
|
||||||
.max_index = 1,
|
.max_index = 1,
|
||||||
.instance_count = 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: */
|
/* We expect that this should not have triggered a change in pfb: */
|
||||||
assert(util_framebuffer_state_equal(pfb, &ctx->framebuffer));
|
assert(util_framebuffer_state_equal(pfb, &ctx->framebuffer));
|
||||||
|
|
|
@ -391,6 +391,7 @@ struct fd_context {
|
||||||
/* draw: */
|
/* draw: */
|
||||||
bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info,
|
bool (*draw_vbo)(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,
|
||||||
unsigned index_offset);
|
unsigned index_offset);
|
||||||
bool (*clear)(struct fd_context *ctx, unsigned buffers,
|
bool (*clear)(struct fd_context *ctx, unsigned buffers,
|
||||||
const union pipe_color_union *color, double depth, unsigned stencil);
|
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
|
static void
|
||||||
fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
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);
|
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 &&
|
if (info->mode != PIPE_PRIM_MAX &&
|
||||||
!indirect &&
|
!indirect &&
|
||||||
!info->primitive_restart &&
|
!info->primitive_restart &&
|
||||||
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* TODO: push down the region versions into the tiles */
|
/* 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)
|
if (ctx->streamout.num_targets > 0)
|
||||||
mesa_loge("stream-out with emulated prims");
|
mesa_loge("stream-out with emulated prims");
|
||||||
util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +252,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
||||||
struct pipe_draw_info new_info;
|
struct pipe_draw_info new_info;
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
if (info->has_user_indices) {
|
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;
|
return;
|
||||||
new_info = *info;
|
new_info = *info;
|
||||||
new_info.index.resource = indexbuf;
|
new_info.index.resource = indexbuf;
|
||||||
|
@ -292,7 +295,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
||||||
unsigned prims;
|
unsigned prims;
|
||||||
if ((info->mode != PIPE_PRIM_PATCHES) &&
|
if ((info->mode != PIPE_PRIM_PATCHES) &&
|
||||||
(info->mode != PIPE_PRIM_MAX))
|
(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
|
else
|
||||||
prims = 0;
|
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->cbufs[0])),
|
||||||
util_format_short_name(pipe_surface_format(pfb->zsbuf)));
|
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->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++)
|
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)
|
if (fd_mesa_debug & FD_DBG_DDRAW)
|
||||||
fd_context_all_dirty(ctx);
|
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_primtype primtype,
|
||||||
enum pc_di_vis_cull_mode vismode,
|
enum pc_di_vis_cull_mode vismode,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned index_offset)
|
unsigned index_offset)
|
||||||
{
|
{
|
||||||
struct pipe_resource *idx_buffer = NULL;
|
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_buffer = info->index.resource;
|
||||||
idx_type = size2indextype(info->index_size);
|
idx_type = size2indextype(info->index_size);
|
||||||
idx_size = info->index_size * info->count;
|
idx_size = info->index_size * draw->count;
|
||||||
idx_offset = index_offset + info->start * info->index_size;
|
idx_offset = index_offset + draw->start * info->index_size;
|
||||||
src_sel = DI_SRC_SEL_DMA;
|
src_sel = DI_SRC_SEL_DMA;
|
||||||
} else {
|
} else {
|
||||||
idx_buffer = NULL;
|
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,
|
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);
|
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,
|
ir3_emit_vs_driver_params(const struct ir3_shader_variant *v,
|
||||||
struct fd_ringbuffer *ring, struct fd_context *ctx,
|
struct fd_ringbuffer *ring, struct fd_context *ctx,
|
||||||
const struct pipe_draw_info *info,
|
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));
|
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] = {
|
uint32_t vertex_params[IR3_DP_VS_COUNT] = {
|
||||||
[IR3_DP_DRAWID] = 0, /* filled by hw (CP_DRAW_INDIRECT_MULTI) */
|
[IR3_DP_DRAWID] = 0, /* filled by hw (CP_DRAW_INDIRECT_MULTI) */
|
||||||
[IR3_DP_VTXID_BASE] = info->index_size ?
|
[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_INSTID_BASE] = info->start_instance,
|
||||||
[IR3_DP_VTXCNT_MAX] = max_tf_vtx(ctx, v),
|
[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
|
static inline void
|
||||||
ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
|
ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
|
||||||
struct fd_context *ctx, const struct pipe_draw_info *info,
|
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);
|
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: */
|
/* emit driver params every time: */
|
||||||
if (info && ir3_needs_vs_driver_params(v)) {
|
if (info && ir3_needs_vs_driver_params(v)) {
|
||||||
ring_wfi(ctx->batch, ring);
|
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
|
static void
|
||||||
i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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 i915_context *i915 = i915_context(pipe);
|
||||||
struct draw_context *draw = i915->draw;
|
struct draw_context *draw = i915->draw;
|
||||||
const void *mapped_indices = NULL;
|
const void *mapped_indices = NULL;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
if (!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -110,7 +112,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
||||||
/*
|
/*
|
||||||
* Do the drawing
|
* Do the drawing
|
||||||
*/
|
*/
|
||||||
draw_vbo(i915->draw, info, NULL);
|
draw_vbo(i915->draw, info, NULL, draws, num_draws);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* unmap vertex/index buffers
|
* unmap vertex/index buffers
|
||||||
|
|
|
@ -823,7 +823,9 @@ void iris_copy_region(struct blorp_context *blorp,
|
||||||
/* iris_draw.c */
|
/* iris_draw.c */
|
||||||
|
|
||||||
void iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
|
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 *);
|
void iris_launch_grid(struct pipe_context *, const struct pipe_grid_info *);
|
||||||
|
|
||||||
/* iris_pipe_control.c */
|
/* iris_pipe_control.c */
|
||||||
|
|
|
@ -112,7 +112,8 @@ iris_update_draw_info(struct iris_context *ice,
|
||||||
static void
|
static void
|
||||||
iris_update_draw_parameters(struct iris_context *ice,
|
iris_update_draw_parameters(struct iris_context *ice,
|
||||||
const struct pipe_draw_info *info,
|
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;
|
bool changed = false;
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ iris_update_draw_parameters(struct iris_context *ice,
|
||||||
changed = true;
|
changed = true;
|
||||||
ice->draw.params_valid = false;
|
ice->draw.params_valid = false;
|
||||||
} else {
|
} 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 ||
|
if (!ice->draw.params_valid ||
|
||||||
ice->draw.params.firstvertex != firstvertex ||
|
ice->draw.params.firstvertex != firstvertex ||
|
||||||
|
@ -173,7 +174,8 @@ iris_update_draw_parameters(struct iris_context *ice,
|
||||||
static void
|
static void
|
||||||
iris_indirect_draw_vbo(struct iris_context *ice,
|
iris_indirect_draw_vbo(struct iris_context *ice,
|
||||||
const struct pipe_draw_info *dinfo,
|
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 iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
|
||||||
struct pipe_draw_info info = *dinfo;
|
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_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.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
|
||||||
ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
|
ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
|
||||||
|
@ -217,15 +219,16 @@ iris_indirect_draw_vbo(struct iris_context *ice,
|
||||||
static void
|
static void
|
||||||
iris_simple_draw_vbo(struct iris_context *ice,
|
iris_simple_draw_vbo(struct iris_context *ice,
|
||||||
const struct pipe_draw_info *draw,
|
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];
|
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
|
||||||
|
|
||||||
iris_batch_maybe_flush(batch, 1500);
|
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
|
void
|
||||||
iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info,
|
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_context *ice = (struct iris_context *) ctx;
|
||||||
struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen;
|
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);
|
iris_handle_always_flush_cache(batch);
|
||||||
|
|
||||||
if (indirect && indirect->buffer)
|
if (indirect && indirect->buffer)
|
||||||
iris_indirect_draw_vbo(ice, info, indirect);
|
iris_indirect_draw_vbo(ice, info, indirect, &draws[0]);
|
||||||
else
|
else
|
||||||
iris_simple_draw_vbo(ice, info, indirect);
|
iris_simple_draw_vbo(ice, info, indirect, &draws[0]);
|
||||||
|
|
||||||
iris_handle_always_flush_cache(batch);
|
iris_handle_always_flush_cache(batch);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ struct iris_vtable {
|
||||||
void (*upload_render_state)(struct iris_context *ice,
|
void (*upload_render_state)(struct iris_context *ice,
|
||||||
struct iris_batch *batch,
|
struct iris_batch *batch,
|
||||||
const struct pipe_draw_info *draw,
|
const struct pipe_draw_info *draw,
|
||||||
const struct pipe_draw_indirect_info *indirect);
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count *sc);
|
||||||
void (*update_surface_base_address)(struct iris_batch *batch,
|
void (*update_surface_base_address)(struct iris_batch *batch,
|
||||||
struct iris_binder *binder);
|
struct iris_binder *binder);
|
||||||
void (*upload_compute_state)(struct iris_context *ice,
|
void (*upload_compute_state)(struct iris_context *ice,
|
||||||
|
|
|
@ -6418,7 +6418,8 @@ static void
|
||||||
iris_upload_render_state(struct iris_context *ice,
|
iris_upload_render_state(struct iris_context *ice,
|
||||||
struct iris_batch *batch,
|
struct iris_batch *batch,
|
||||||
const struct pipe_draw_info *draw,
|
const struct pipe_draw_info *draw,
|
||||||
const struct pipe_draw_indirect_info *indirect)
|
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;
|
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) {
|
if (draw->has_user_indices) {
|
||||||
u_upload_data(ice->ctx.stream_uploader, 0,
|
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);
|
&offset, &ice->state.last_res.index_buffer);
|
||||||
} else {
|
} else {
|
||||||
struct iris_resource *res = (void *) draw->index.resource;
|
struct iris_resource *res = (void *) draw->index.resource;
|
||||||
|
@ -6621,9 +6622,9 @@ iris_upload_render_state(struct iris_context *ice,
|
||||||
} else {
|
} else {
|
||||||
prim.StartInstanceLocation = draw->start_instance;
|
prim.StartInstanceLocation = draw->start_instance;
|
||||||
prim.InstanceCount = draw->instance_count;
|
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) {
|
if (draw->index_size) {
|
||||||
prim.BaseVertexLocation += draw->index_bias;
|
prim.BaseVertexLocation += draw->index_bias;
|
||||||
|
|
|
@ -265,7 +265,8 @@ lima_pipe_format_to_attrib_type(enum pipe_format format)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 =
|
struct lima_context_constant_buffer *ccb =
|
||||||
ctx->const_buffer + PIPE_SHADER_VERTEX;
|
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),
|
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_varying_info),
|
||||||
num_outputs);
|
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_DRAW(num, info->index_size);
|
||||||
|
|
||||||
VS_CMD_UNKNOWN2();
|
VS_CMD_UNKNOWN2();
|
||||||
|
@ -313,7 +314,8 @@ lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 lima_vs_shader_state *vs = ctx->vs;
|
||||||
struct pipe_scissor_state *cscissor = &ctx->clipped_scissor;
|
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)
|
if (vs->point_size_idx != -1)
|
||||||
PLBU_CMD_INDEXED_PT_SIZE(ctx->gp_output->va + ctx->gp_output_point_size_offt);
|
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 {
|
else {
|
||||||
/* can this make the attribute info static? */
|
/* 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();
|
PLBU_CMD_ARRAYS_SEMAPHORE_END();
|
||||||
|
|
||||||
if (info->index_size)
|
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();
|
PLBU_CMD_END();
|
||||||
}
|
}
|
||||||
|
@ -799,7 +801,8 @@ lima_pack_render_state(struct lima_context *ctx, const struct pipe_draw_info *in
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_job *job = lima_job_get(ctx);
|
||||||
struct lima_vertex_element_state *ve = ctx->vertex_elements;
|
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);
|
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
|
attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
|
||||||
+ start * pvb->stride;
|
+ start * pvb->stride;
|
||||||
attribute[n++] = (pvb->stride << 11) |
|
attribute[n++] = (pvb->stride << 11) |
|
||||||
|
@ -914,13 +917,14 @@ lima_update_pp_uniform(struct lima_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_job *job = lima_job_get(ctx);
|
||||||
struct lima_screen *screen = lima_screen(ctx->base.screen);
|
struct lima_screen *screen = lima_screen(ctx->base.screen);
|
||||||
struct lima_vs_shader_state *vs = ctx->vs;
|
struct lima_vs_shader_state *vs = ctx->vs;
|
||||||
uint32_t gp_output_size;
|
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 =
|
uint32_t *varying =
|
||||||
lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_varying_info,
|
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
|
static void
|
||||||
lima_draw_vbo_update(struct pipe_context *pctx,
|
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 *ctx = lima_context(pctx);
|
||||||
struct lima_context_framebuffer *fb = &ctx->framebuffer;
|
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_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 &&
|
if ((ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
|
||||||
ctx->const_buffer[PIPE_SHADER_VERTEX].dirty) ||
|
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;
|
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 &&
|
if (ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF &&
|
||||||
ctx->const_buffer[PIPE_SHADER_FRAGMENT].dirty) {
|
ctx->const_buffer[PIPE_SHADER_FRAGMENT].dirty) {
|
||||||
|
@ -1040,7 +1045,7 @@ lima_draw_vbo_update(struct pipe_context *pctx,
|
||||||
lima_update_textures(ctx);
|
lima_update_textures(ctx);
|
||||||
|
|
||||||
lima_pack_render_state(ctx, info);
|
lima_pack_render_state(ctx, info);
|
||||||
lima_pack_plbu_cmd(ctx, info);
|
lima_pack_plbu_cmd(ctx, info, draw);
|
||||||
|
|
||||||
if (ctx->gp_output) {
|
if (ctx->gp_output) {
|
||||||
lima_bo_unreference(ctx->gp_output); /* held by job */
|
lima_bo_unreference(ctx->gp_output); /* held by job */
|
||||||
|
@ -1052,7 +1057,8 @@ lima_draw_vbo_update(struct pipe_context *pctx,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lima_draw_vbo_indexed(struct pipe_context *pctx,
|
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_context *ctx = lima_context(pctx);
|
||||||
struct lima_job *job = lima_job_get(ctx);
|
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) {
|
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);
|
ctx->index_res = lima_resource(indexbuf);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ctx->index_res = lima_resource(info->index.resource);
|
ctx->index_res = lima_resource(info->index.resource);
|
||||||
ctx->index_offset = 0;
|
ctx->index_offset = 0;
|
||||||
needs_indices = !panfrost_minmax_cache_get(ctx->index_res->index_cache, info->start,
|
needs_indices = !panfrost_minmax_cache_get(ctx->index_res->index_cache, draw->start,
|
||||||
info->count, &ctx->min_index, &ctx->max_index);
|
draw->count, &ctx->min_index, &ctx->max_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needs_indices) {
|
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)
|
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);
|
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_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_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)
|
if (indexbuf)
|
||||||
pipe_resource_reference(&indexbuf, NULL);
|
pipe_resource_reference(&indexbuf, NULL);
|
||||||
|
@ -1095,13 +1101,14 @@ lima_draw_vbo_indexed(struct pipe_context *pctx,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lima_draw_vbo_count(struct pipe_context *pctx,
|
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;
|
static const uint32_t max_verts = 65535;
|
||||||
|
|
||||||
struct pipe_draw_info local_info = *info;
|
struct pipe_draw_start_count local_draw = *draw;
|
||||||
unsigned start = info->start;
|
unsigned start = draw->start;
|
||||||
unsigned count = info->count;
|
unsigned count = draw->count;
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
unsigned this_count = 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);
|
u_split_draw(info, max_verts, &this_count, &step);
|
||||||
|
|
||||||
local_info.start = start;
|
local_draw.start = start;
|
||||||
local_info.count = this_count;
|
local_draw.count = this_count;
|
||||||
|
|
||||||
lima_draw_vbo_update(pctx, &local_info);
|
lima_draw_vbo_update(pctx, info, &local_draw);
|
||||||
|
|
||||||
count -= step;
|
count -= step;
|
||||||
start += step;
|
start += step;
|
||||||
|
@ -1122,11 +1129,13 @@ lima_draw_vbo_count(struct pipe_context *pctx,
|
||||||
static void
|
static void
|
||||||
lima_draw_vbo(struct pipe_context *pctx,
|
lima_draw_vbo(struct pipe_context *pctx,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
/* check if draw mode and vertex/index count match,
|
||||||
* otherwise gp will hang */
|
* 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");
|
debug_printf("draw mode and vertex/index count mismatch\n");
|
||||||
return;
|
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);
|
lima_job_add_bo(job, LIMA_PIPE_PP, ctx->fs->bo, LIMA_SUBMIT_BO_READ);
|
||||||
|
|
||||||
if (info->index_size)
|
if (info->index_size)
|
||||||
lima_draw_vbo_indexed(pctx, info);
|
lima_draw_vbo_indexed(pctx, info, &draws[0]);
|
||||||
else
|
else
|
||||||
lima_draw_vbo_count(pctx, info);
|
lima_draw_vbo_count(pctx, info, &draws[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -52,7 +52,9 @@
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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 llvmpipe_context *lp = llvmpipe_context(pipe);
|
||||||
struct draw_context *draw = lp->draw;
|
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);
|
!lp->queries_disabled);
|
||||||
|
|
||||||
/* draw! */
|
/* draw! */
|
||||||
draw_vbo(draw, info, indirect);
|
draw_vbo(draw, info, indirect, draws, num_draws);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* unmap vertex/index buffers
|
* unmap vertex/index buffers
|
||||||
|
|
|
@ -195,13 +195,15 @@ nv30_fragtex_set_sampler_views(struct pipe_context *pipe,
|
||||||
unsigned nr, struct pipe_sampler_view **views);
|
unsigned nr, struct pipe_sampler_view **views);
|
||||||
|
|
||||||
void
|
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
|
void
|
||||||
nv30_draw_init(struct pipe_context *pipe);
|
nv30_draw_init(struct pipe_context *pipe);
|
||||||
|
|
||||||
void
|
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
|
bool
|
||||||
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl);
|
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl);
|
||||||
|
|
|
@ -376,7 +376,8 @@ nv30_render_validate(struct nv30_context *nv30)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 nv30_context *nv30 = nv30_context(pipe);
|
||||||
struct draw_context *draw = nv30->draw;
|
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_set_indexes(draw, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_vbo(draw, info, NULL);
|
draw_vbo(draw, info, NULL, draw_one, 1);
|
||||||
draw_flush(draw);
|
draw_flush(draw);
|
||||||
|
|
||||||
if (info->index_size && transferi)
|
if (info->index_size && transferi)
|
||||||
|
|
|
@ -195,7 +195,8 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
struct push_context ctx;
|
||||||
unsigned i, index_size;
|
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->index_size) {
|
||||||
if (!info->has_user_indices)
|
if (!info->has_user_indices)
|
||||||
ctx.idxbuf = nouveau_resource_map_offset(&nv30->base,
|
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);
|
NOUVEAU_BO_RD);
|
||||||
else
|
else
|
||||||
ctx.idxbuf = info->index.user;
|
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);
|
PUSH_DATA (ctx.push, ctx.prim);
|
||||||
switch (index_size) {
|
switch (index_size) {
|
||||||
case 0:
|
case 0:
|
||||||
emit_vertices_seq(&ctx, info->start, info->count);
|
emit_vertices_seq(&ctx, draw->start, draw->count);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
emit_vertices_i08(&ctx, info->start, info->count);
|
emit_vertices_i08(&ctx, draw->start, draw->count);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
emit_vertices_i16(&ctx, info->start, info->count);
|
emit_vertices_i16(&ctx, draw->start, draw->count);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
emit_vertices_i32(&ctx, info->start, info->count);
|
emit_vertices_i32(&ctx, draw->start, draw->count);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
@ -545,14 +545,16 @@ nv30_draw_elements(struct nv30_context *nv30, bool shorten,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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 nv30_context *nv30 = nv30_context(pipe);
|
||||||
struct nouveau_pushbuf *push = nv30->base.pushbuf;
|
struct nouveau_pushbuf *push = nv30->base.pushbuf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!info->primitive_restart &&
|
if (!info->primitive_restart &&
|
||||||
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* For picking only a few vertices from a large user buffer, push is better,
|
/* 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 */
|
nv30->vbo_push_hint = /* the 64 is heuristic */
|
||||||
!(info->index_size &&
|
!(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_min_index = info->min_index;
|
||||||
nv30->vbo_max_index = info->max_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);
|
nv30_state_validate(nv30, ~0, true);
|
||||||
if (nv30->draw_flags) {
|
if (nv30->draw_flags) {
|
||||||
nv30_render_vbo(pipe, info);
|
nv30_render_vbo(pipe, info, &draws[0]);
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
if (nv30->vbo_fifo) {
|
if (nv30->vbo_fifo) {
|
||||||
nv30_push_vbo(nv30, info);
|
nv30_push_vbo(nv30, info, &draws[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +603,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
||||||
|
|
||||||
if (!info->index_size) {
|
if (!info->index_size) {
|
||||||
nv30_draw_arrays(nv30,
|
nv30_draw_arrays(nv30,
|
||||||
info->mode, info->start, info->count,
|
info->mode, draws[0].start, draws[0].count,
|
||||||
info->instance_count);
|
info->instance_count);
|
||||||
} else {
|
} else {
|
||||||
bool shorten = info->max_index <= 65535;
|
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,
|
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);
|
info->instance_count, info->index_bias, info->index_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,9 @@ nv50_cb_push(struct nouveau_context *nv,
|
||||||
|
|
||||||
/* nv50_vbo.c */
|
/* nv50_vbo.c */
|
||||||
void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *,
|
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 *
|
void *
|
||||||
nv50_vertex_state_create(struct pipe_context *pipe,
|
nv50_vertex_state_create(struct pipe_context *pipe,
|
||||||
|
@ -305,7 +307,8 @@ void nv50_vertex_arrays_validate(struct nv50_context *nv50);
|
||||||
|
|
||||||
/* nv50_push.c */
|
/* nv50_push.c */
|
||||||
void nv50_push_vbo(struct nv50_context *, const struct pipe_draw_info *,
|
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 */
|
/* nv84_video.c */
|
||||||
struct pipe_video_codec *
|
struct pipe_video_codec *
|
||||||
|
|
|
@ -239,12 +239,13 @@ nv50_prim_gl(unsigned prim)
|
||||||
|
|
||||||
void
|
void
|
||||||
nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
|
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;
|
struct push_context ctx;
|
||||||
unsigned i, index_size;
|
unsigned i, index_size;
|
||||||
unsigned inst_count = info->instance_count;
|
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;
|
bool apply_bias = info->index_size && info->index_bias;
|
||||||
|
|
||||||
ctx.push = nv50->base.pushbuf;
|
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);
|
PUSH_DATA (ctx.push, ctx.prim);
|
||||||
switch (index_size) {
|
switch (index_size) {
|
||||||
case 0:
|
case 0:
|
||||||
emit_vertices_seq(&ctx, info->start, vert_count);
|
emit_vertices_seq(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
emit_vertices_i08(&ctx, info->start, vert_count);
|
emit_vertices_i08(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
emit_vertices_i16(&ctx, info->start, vert_count);
|
emit_vertices_i16(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
emit_vertices_i32(&ctx, info->start, vert_count);
|
emit_vertices_i32(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
@ -755,7 +755,9 @@ nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
|
||||||
|
|
||||||
void
|
void
|
||||||
nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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 nv50_context *nv50 = nv50_context(pipe);
|
||||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
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.
|
* if index count is larger and we expect repeated vertices, suggest upload.
|
||||||
*/
|
*/
|
||||||
nv50->vbo_push_hint = /* the 64 is heuristic */
|
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_user && !(nv50->dirty_3d & (NV50_NEW_3D_ARRAYS | NV50_NEW_3D_VERTEX))) {
|
||||||
if (!!nv50->vbo_fifo != nv50->vbo_push_hint)
|
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) {
|
if (nv50->vbo_fifo) {
|
||||||
nv50_push_vbo(nv50, info, indirect);
|
nv50_push_vbo(nv50, info, indirect, &draws[0]);
|
||||||
goto cleanup;
|
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,
|
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);
|
info->instance_count, info->index_bias, info->index_size);
|
||||||
} else
|
} else
|
||||||
if (unlikely(indirect && indirect->count_from_stream_output)) {
|
if (unlikely(indirect && indirect->count_from_stream_output)) {
|
||||||
nva0_draw_stream_output(nv50, info, indirect);
|
nva0_draw_stream_output(nv50, info, indirect);
|
||||||
} else {
|
} else {
|
||||||
nv50_draw_arrays(nv50,
|
nv50_draw_arrays(nv50,
|
||||||
info->mode, info->start, info->count,
|
info->mode, draws[0].start, draws[0].count,
|
||||||
info->instance_count);
|
info->instance_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,7 +414,9 @@ nvc0_cb_bo_push(struct nouveau_context *,
|
||||||
|
|
||||||
/* nvc0_vbo.c */
|
/* nvc0_vbo.c */
|
||||||
void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *,
|
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 *
|
void *
|
||||||
nvc0_vertex_state_create(struct pipe_context *pipe,
|
nvc0_vertex_state_create(struct pipe_context *pipe,
|
||||||
|
@ -438,9 +440,11 @@ nvc0_video_buffer_create(struct pipe_context *pipe,
|
||||||
|
|
||||||
/* nvc0_push.c */
|
/* nvc0_push.c */
|
||||||
void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *,
|
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 *,
|
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 */
|
/* nve4_compute.c */
|
||||||
void nve4_launch_grid(struct pipe_context *, const struct pipe_grid_info *);
|
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
|
void
|
||||||
nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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 nvc0_context *nvc0 = nvc0_context(pipe);
|
||||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
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 =
|
nvc0->vbo_push_hint =
|
||||||
(!indirect || indirect->count_from_stream_output) && info->index_size &&
|
(!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. */
|
/* Check whether we want to switch vertex-submission mode. */
|
||||||
if (nvc0->vbo_user && !(nvc0->dirty_3d & (NVC0_NEW_3D_ARRAYS | NVC0_NEW_3D_VERTEX))) {
|
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 (nvc0->state.vbo_mode) {
|
||||||
if (indirect && indirect->buffer)
|
if (indirect && indirect->buffer)
|
||||||
nvc0_push_vbo_indirect(nvc0, info, indirect);
|
nvc0_push_vbo_indirect(nvc0, info, indirect, &draws[0]);
|
||||||
else
|
else
|
||||||
nvc0_push_vbo(nvc0, info, indirect);
|
nvc0_push_vbo(nvc0, info, indirect, &draws[0]);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,11 +1106,11 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
||||||
shorten = false;
|
shorten = false;
|
||||||
|
|
||||||
nvc0_draw_elements(nvc0, shorten, info,
|
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);
|
info->instance_count, info->index_bias, info->index_size);
|
||||||
} else {
|
} else {
|
||||||
nvc0_draw_arrays(nvc0,
|
nvc0_draw_arrays(nvc0,
|
||||||
info->mode, info->start, info->count,
|
info->mode, draws[0].start, draws[0].count,
|
||||||
info->instance_count);
|
info->instance_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@ struct push_context {
|
||||||
|
|
||||||
static void nvc0_push_upload_vertex_ids(struct push_context *,
|
static void nvc0_push_upload_vertex_ids(struct push_context *,
|
||||||
struct nvc0_context *,
|
struct nvc0_context *,
|
||||||
const struct pipe_draw_info *);
|
const struct pipe_draw_info *,
|
||||||
|
const struct pipe_draw_start_count *draw);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nvc0_push_context_init(struct nvc0_context *nvc0, struct push_context *ctx)
|
nvc0_push_context_init(struct nvc0_context *nvc0, struct push_context *ctx)
|
||||||
|
@ -491,7 +492,8 @@ typedef struct {
|
||||||
|
|
||||||
void
|
void
|
||||||
nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
|
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
|
/* 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
|
* 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(
|
uint8_t *buf_data = nouveau_resource_map_offset(
|
||||||
&nvc0->base, buf, indirect->offset, NOUVEAU_BO_RD);
|
&nvc0->base, buf, indirect->offset, NOUVEAU_BO_RD);
|
||||||
struct pipe_draw_info single = *info;
|
struct pipe_draw_info single = *info;
|
||||||
|
struct pipe_draw_start_count sdraw = *draw;
|
||||||
for (i = 0; i < draw_count; i++, buf_data += indirect->stride) {
|
for (i = 0; i < draw_count; i++, buf_data += indirect->stride) {
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
DrawElementsIndirectCommand *cmd = (void *)buf_data;
|
DrawElementsIndirectCommand *cmd = (void *)buf_data;
|
||||||
single.start = info->start + cmd->firstIndex;
|
sdraw.start = draw->start + cmd->firstIndex;
|
||||||
single.count = cmd->count;
|
sdraw.count = cmd->count;
|
||||||
single.start_instance = cmd->baseInstance;
|
single.start_instance = cmd->baseInstance;
|
||||||
single.instance_count = cmd->primCount;
|
single.instance_count = cmd->primCount;
|
||||||
single.index_bias = cmd->baseVertex;
|
single.index_bias = cmd->baseVertex;
|
||||||
} else {
|
} else {
|
||||||
DrawArraysIndirectCommand *cmd = (void *)buf_data;
|
DrawArraysIndirectCommand *cmd = (void *)buf_data;
|
||||||
single.start = cmd->first;
|
sdraw.start = cmd->first;
|
||||||
single.count = cmd->count;
|
sdraw.count = cmd->count;
|
||||||
single.start_instance = cmd->baseInstance;
|
single.start_instance = cmd->baseInstance;
|
||||||
single.instance_count = cmd->primCount;
|
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);
|
PUSH_DATA (push, single.drawid + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
nvc0_push_vbo(nvc0, &single, NULL);
|
nvc0_push_vbo(nvc0, &single, NULL, &sdraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
nouveau_resource_unmap(buf);
|
nouveau_resource_unmap(buf);
|
||||||
|
@ -553,12 +556,13 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i
|
||||||
|
|
||||||
void
|
void
|
||||||
nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
|
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;
|
struct push_context ctx;
|
||||||
unsigned i, index_size;
|
unsigned i, index_size;
|
||||||
unsigned inst_count = info->instance_count;
|
unsigned inst_count = info->instance_count;
|
||||||
unsigned vert_count = info->count;
|
unsigned vert_count = draw->count;
|
||||||
unsigned prim;
|
unsigned prim;
|
||||||
|
|
||||||
nvc0_push_context_init(nvc0, &ctx);
|
nvc0_push_context_init(nvc0, &ctx);
|
||||||
|
@ -619,7 +623,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (unlikely(ctx.need_vertex_id))
|
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)
|
if (nvc0->screen->eng3d->oclass < GM107_3D_CLASS)
|
||||||
IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
|
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);
|
PUSH_DATA (ctx.push, prim);
|
||||||
switch (index_size) {
|
switch (index_size) {
|
||||||
case 1:
|
case 1:
|
||||||
disp_vertices_i08(&ctx, info->start, vert_count);
|
disp_vertices_i08(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
disp_vertices_i16(&ctx, info->start, vert_count);
|
disp_vertices_i16(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
disp_vertices_i32(&ctx, info->start, vert_count);
|
disp_vertices_i32(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(index_size == 0);
|
assert(index_size == 0);
|
||||||
disp_vertices_seq(&ctx, info->start, vert_count);
|
disp_vertices_seq(&ctx, draw->start, vert_count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PUSH_SPACE(ctx.push, 1);
|
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
|
static void
|
||||||
nvc0_push_upload_vertex_ids(struct push_context *ctx,
|
nvc0_push_upload_vertex_ids(struct push_context *ctx,
|
||||||
struct nvc0_context *nvc0,
|
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;
|
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)
|
if (!index_size || info->index_bias)
|
||||||
index_size = 4;
|
index_size = 4;
|
||||||
data = (uint32_t *)nouveau_scratch_get(&nvc0->base,
|
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,
|
BCTX_REFN_bo(nvc0->bufctx_3d, 3D_VTX_TMP, NOUVEAU_BO_GART | NOUVEAU_BO_RD,
|
||||||
bo);
|
bo);
|
||||||
|
@ -728,23 +733,23 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
|
||||||
|
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
if (!info->index_bias) {
|
if (!info->index_bias) {
|
||||||
memcpy(data, ctx->idxbuf, info->count * index_size);
|
memcpy(data, ctx->idxbuf, draw->count * index_size);
|
||||||
} else {
|
} else {
|
||||||
switch (info->index_size) {
|
switch (info->index_size) {
|
||||||
case 1:
|
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;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
copy_indices_u32(data, ctx->idxbuf, info->index_bias, info->count);
|
copy_indices_u32(data, ctx->idxbuf, info->index_bias, draw->count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < info->count; ++i)
|
for (i = 0; i < draw->count; ++i)
|
||||||
data[i] = i + (info->start + info->index_bias);
|
data[i] = i + (draw->start + info->index_bias);
|
||||||
}
|
}
|
||||||
|
|
||||||
format = (1 << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
|
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);
|
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_LIMIT_HIGH(1)), 2);
|
||||||
else
|
else
|
||||||
BEGIN_NVC0(push, SUBC_3D(TU102_3D_VERTEX_ARRAY_LIMIT_HIGH(1)), 2);
|
BEGIN_NVC0(push, SUBC_3D(TU102_3D_VERTEX_ARRAY_LIMIT_HIGH(1)), 2);
|
||||||
PUSH_DATAh(push, va + info->count * index_size - 1);
|
PUSH_DATAh(push, va + draw->count * index_size - 1);
|
||||||
PUSH_DATA (push, va + info->count * index_size - 1);
|
PUSH_DATA (push, va + draw->count * index_size - 1);
|
||||||
|
|
||||||
#define NVC0_3D_VERTEX_ID_REPLACE_SOURCE_ATTR_X(a) \
|
#define NVC0_3D_VERTEX_ID_REPLACE_SOURCE_ATTR_X(a) \
|
||||||
(((0x80 + (a) * 0x10) / 4) << NVC0_3D_VERTEX_ID_REPLACE_SOURCE__SHIFT)
|
(((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
|
mali_ptr
|
||||||
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
|
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned *min_index, unsigned *max_index)
|
unsigned *min_index, unsigned *max_index)
|
||||||
{
|
{
|
||||||
struct panfrost_resource *rsrc = pan_resource(info->index.resource);
|
struct panfrost_resource *rsrc = pan_resource(info->index.resource);
|
||||||
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
|
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;
|
bool needs_indices = true;
|
||||||
mali_ptr out = 0;
|
mali_ptr out = 0;
|
||||||
|
|
||||||
|
@ -85,8 +86,8 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
|
||||||
|
|
||||||
/* Check the cache */
|
/* Check the cache */
|
||||||
needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache,
|
needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache,
|
||||||
info->start,
|
draw->start,
|
||||||
info->count,
|
draw->count,
|
||||||
min_index,
|
min_index,
|
||||||
max_index);
|
max_index);
|
||||||
} else {
|
} else {
|
||||||
|
@ -94,20 +95,20 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
|
||||||
const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
|
const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
|
||||||
struct panfrost_ptr T =
|
struct panfrost_ptr T =
|
||||||
panfrost_pool_alloc_aligned(&batch->pool,
|
panfrost_pool_alloc_aligned(&batch->pool,
|
||||||
info->count * info->index_size,
|
draw->count * info->index_size,
|
||||||
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;
|
out = T.gpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needs_indices) {
|
if (needs_indices) {
|
||||||
/* Fallback */
|
/* 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)
|
if (!info->has_user_indices)
|
||||||
panfrost_minmax_cache_add(rsrc->index_cache,
|
panfrost_minmax_cache_add(rsrc->index_cache,
|
||||||
info->start, info->count,
|
draw->start, draw->count,
|
||||||
*min_index, *max_index);
|
*min_index, *max_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
|
||||||
mali_ptr
|
mali_ptr
|
||||||
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
|
panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned *min_index, unsigned *max_index);
|
unsigned *min_index, unsigned *max_index);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -228,12 +228,13 @@ panfrost_scissor_culls_everything(struct panfrost_context *ctx)
|
||||||
static void
|
static void
|
||||||
panfrost_statistics_record(
|
panfrost_statistics_record(
|
||||||
struct panfrost_context *ctx,
|
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)
|
if (!ctx->active_queries)
|
||||||
return;
|
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;
|
ctx->prims_generated += prims;
|
||||||
|
|
||||||
if (!ctx->streamout.num_targets)
|
if (!ctx->streamout.num_targets)
|
||||||
|
@ -331,6 +332,7 @@ static void
|
||||||
panfrost_draw_emit_tiler(struct panfrost_batch *batch,
|
panfrost_draw_emit_tiler(struct panfrost_batch *batch,
|
||||||
const struct pipe_draw_info *info,
|
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 *invocation_template,
|
void *invocation_template,
|
||||||
mali_ptr shared_mem, mali_ptr indices,
|
mali_ptr shared_mem, mali_ptr indices,
|
||||||
mali_ptr fs_vary, mali_ptr varyings,
|
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.index_type = panfrost_translate_index_size(info->index_size);
|
||||||
cfg.indices = indices;
|
cfg.indices = indices;
|
||||||
cfg.base_vertex_offset = info->index_bias - ctx->offset_start;
|
cfg.base_vertex_offset = info->index_bias - ctx->offset_start;
|
||||||
cfg.index_count = info->count;
|
cfg.index_count = draw->count;
|
||||||
} else {
|
} else {
|
||||||
cfg.index_count = indirect && indirect->count_from_stream_output ?
|
cfg.index_count = indirect && indirect->count_from_stream_output ?
|
||||||
pan_so_target(indirect->count_from_stream_output)->offset :
|
pan_so_target(indirect->count_from_stream_output)->offset :
|
||||||
|
@ -424,7 +426,9 @@ static void
|
||||||
panfrost_draw_vbo(
|
panfrost_draw_vbo(
|
||||||
struct pipe_context *pipe,
|
struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
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_context *ctx = pan_context(pipe);
|
||||||
struct panfrost_device *device = pan_device(ctx->base.screen);
|
struct panfrost_device *device = pan_device(ctx->base.screen);
|
||||||
|
@ -443,7 +447,7 @@ panfrost_draw_vbo(
|
||||||
|
|
||||||
if (info->primitive_restart && info->index_size
|
if (info->primitive_restart && info->index_size
|
||||||
&& info->restart_index != primitive_index) {
|
&& 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,13 +456,13 @@ panfrost_draw_vbo(
|
||||||
assert(ctx->rasterizer != NULL);
|
assert(ctx->rasterizer != NULL);
|
||||||
|
|
||||||
if (!(ctx->draw_modes & (1 << mode))) {
|
if (!(ctx->draw_modes & (1 << mode))) {
|
||||||
if (info->count < 4) {
|
if (draws[0].count < 4) {
|
||||||
/* Degenerate case? */
|
/* Degenerate case? */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +472,7 @@ panfrost_draw_vbo(
|
||||||
panfrost_batch_set_requirements(batch);
|
panfrost_batch_set_requirements(batch);
|
||||||
|
|
||||||
/* Take into account a negative bias */
|
/* 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->instance_count = info->instance_count;
|
||||||
ctx->active_prim = info->mode;
|
ctx->active_prim = info->mode;
|
||||||
|
|
||||||
|
@ -492,7 +496,7 @@ panfrost_draw_vbo(
|
||||||
mali_ptr indices = 0;
|
mali_ptr indices = 0;
|
||||||
|
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
indices = panfrost_get_index_buffer_bounded(ctx, info,
|
indices = panfrost_get_index_buffer_bounded(ctx, info, &draws[0],
|
||||||
&min_index,
|
&min_index,
|
||||||
&max_index);
|
&max_index);
|
||||||
|
|
||||||
|
@ -500,7 +504,7 @@ panfrost_draw_vbo(
|
||||||
vertex_count = max_index - min_index + 1;
|
vertex_count = max_index - min_index + 1;
|
||||||
ctx->offset_start = min_index + info->index_bias;
|
ctx->offset_start = min_index + info->index_bias;
|
||||||
} else {
|
} else {
|
||||||
ctx->offset_start = info->start;
|
ctx->offset_start = draws[0].start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode the padded vertex count */
|
/* Encode the padded vertex count */
|
||||||
|
@ -510,7 +514,7 @@ panfrost_draw_vbo(
|
||||||
else
|
else
|
||||||
ctx->padded_count = vertex_count;
|
ctx->padded_count = vertex_count;
|
||||||
|
|
||||||
panfrost_statistics_record(ctx, info);
|
panfrost_statistics_record(ctx, info, &draws[0]);
|
||||||
|
|
||||||
struct mali_invocation_packed invocation;
|
struct mali_invocation_packed invocation;
|
||||||
panfrost_pack_work_groups_compute(&invocation,
|
panfrost_pack_work_groups_compute(&invocation,
|
||||||
|
@ -529,7 +533,7 @@ panfrost_draw_vbo(
|
||||||
/* Fire off the draw itself */
|
/* Fire off the draw itself */
|
||||||
panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem,
|
panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem,
|
||||||
vs_vary, varyings, vertex.cpu);
|
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);
|
fs_vary, varyings, pos, psiz, tiler.cpu);
|
||||||
panfrost_emit_vertex_tiler_jobs(batch, &vertex, &tiler);
|
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,
|
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_element* velem;
|
||||||
struct pipe_vertex_buffer* vbuf;
|
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;
|
unsigned vertex_size = r300->velems->vertex_size_dwords;
|
||||||
|
|
||||||
/* The number of dwords for this draw operation. */
|
/* 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. */
|
/* Size of the vertex element, in dwords. */
|
||||||
unsigned size[PIPE_MAX_ATTRIBS];
|
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(
|
map[vbi] = (uint32_t*)r300->rws->buffer_map(
|
||||||
r300_resource(vbuf->buffer.resource)->buf,
|
r300_resource(vbuf->buffer.resource)->buf,
|
||||||
r300->cs, PIPE_MAP_READ | PIPE_MAP_UNSYNCHRONIZED);
|
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);
|
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);
|
BEGIN_CS(dwords);
|
||||||
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
|
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
|
||||||
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, info->count * vertex_size);
|
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, draw->count * vertex_size);
|
||||||
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (info->count << 16) |
|
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (draw->count << 16) |
|
||||||
r300_translate_primitive(info->mode));
|
r300_translate_primitive(info->mode));
|
||||||
|
|
||||||
/* Emit vertices. */
|
/* Emit vertices. */
|
||||||
for (v = 0; v < info->count; v++) {
|
for (v = 0; v < draw->count; v++) {
|
||||||
for (i = 0; i < vertex_element_count; i++) {
|
for (i = 0; i < vertex_element_count; i++) {
|
||||||
OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[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,
|
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 uint8_t *ptr1;
|
||||||
const uint16_t *ptr2;
|
const uint16_t *ptr2;
|
||||||
const uint32_t *ptr4;
|
const uint32_t *ptr4;
|
||||||
unsigned index_size = info->index_size;
|
unsigned index_size = info->index_size;
|
||||||
unsigned i, count_dwords = index_size == 4 ? info->count :
|
unsigned i, count_dwords = index_size == 4 ? draw->count :
|
||||||
(info->count + 1) / 2;
|
(draw->count + 1) / 2;
|
||||||
CS_LOCALS(r300);
|
CS_LOCALS(r300);
|
||||||
|
|
||||||
/* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
|
/* 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) {
|
switch (index_size) {
|
||||||
case 1:
|
case 1:
|
||||||
ptr1 = (uint8_t*)info->index.user;
|
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));
|
r300_translate_primitive(info->mode));
|
||||||
|
|
||||||
if (info->index_bias && !r300->screen->caps.is_r500) {
|
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) |
|
OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
|
||||||
(ptr1[i] + info->index_bias));
|
(ptr1[i] + info->index_bias));
|
||||||
|
|
||||||
if (info->count & 1)
|
if (draw->count & 1)
|
||||||
OUT_CS(ptr1[i] + info->index_bias);
|
OUT_CS(ptr1[i] + info->index_bias);
|
||||||
} else {
|
} 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) |
|
OUT_CS(((ptr1[i+1]) << 16) |
|
||||||
(ptr1[i] ));
|
(ptr1[i] ));
|
||||||
|
|
||||||
if (info->count & 1)
|
if (draw->count & 1)
|
||||||
OUT_CS(ptr1[i]);
|
OUT_CS(ptr1[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
ptr2 = (uint16_t*)info->index.user;
|
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));
|
r300_translate_primitive(info->mode));
|
||||||
|
|
||||||
if (info->index_bias && !r300->screen->caps.is_r500) {
|
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) |
|
OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
|
||||||
(ptr2[i] + info->index_bias));
|
(ptr2[i] + info->index_bias));
|
||||||
|
|
||||||
if (info->count & 1)
|
if (draw->count & 1)
|
||||||
OUT_CS(ptr2[i] + info->index_bias);
|
OUT_CS(ptr2[i] + info->index_bias);
|
||||||
} else {
|
} else {
|
||||||
OUT_CS_TABLE(ptr2, count_dwords);
|
OUT_CS_TABLE(ptr2, count_dwords);
|
||||||
|
@ -563,14 +565,14 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
ptr4 = (uint32_t*)info->index.user;
|
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_VAP_VF_CNTL__INDEX_SIZE_32bit |
|
||||||
r300_translate_primitive(info->mode));
|
r300_translate_primitive(info->mode));
|
||||||
|
|
||||||
if (info->index_bias && !r300->screen->caps.is_r500) {
|
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);
|
OUT_CS(ptr4[i] + info->index_bias);
|
||||||
} else {
|
} else {
|
||||||
OUT_CS_TABLE(ptr4, count_dwords);
|
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,
|
static void r300_draw_elements(struct r300_context *r300,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
int instance_id)
|
int instance_id)
|
||||||
{
|
{
|
||||||
struct pipe_resource *indexBuffer =
|
struct pipe_resource *indexBuffer =
|
||||||
info->has_user_indices ? NULL : info->index.resource;
|
info->has_user_indices ? NULL : info->index.resource;
|
||||||
unsigned indexSize = info->index_size;
|
unsigned indexSize = info->index_size;
|
||||||
struct pipe_resource* orgIndexBuffer = indexBuffer;
|
struct pipe_resource* orgIndexBuffer = indexBuffer;
|
||||||
unsigned start = info->start;
|
unsigned start = draw->start;
|
||||||
unsigned count = info->count;
|
unsigned count = draw->count;
|
||||||
boolean alt_num_verts = r300->screen->caps.is_r500 &&
|
boolean alt_num_verts = r300->screen->caps.is_r500 &&
|
||||||
count > 65536;
|
count > 65536;
|
||||||
unsigned short_count;
|
unsigned short_count;
|
||||||
|
@ -673,12 +676,13 @@ done:
|
||||||
|
|
||||||
static void r300_draw_arrays(struct r300_context *r300,
|
static void r300_draw_arrays(struct r300_context *r300,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
int instance_id)
|
int instance_id)
|
||||||
{
|
{
|
||||||
boolean alt_num_verts = r300->screen->caps.is_r500 &&
|
boolean alt_num_verts = r300->screen->caps.is_r500 &&
|
||||||
info->count > 65536;
|
draw->count > 65536;
|
||||||
unsigned start = info->start;
|
unsigned start = draw->start;
|
||||||
unsigned count = info->count;
|
unsigned count = draw->count;
|
||||||
unsigned short_count;
|
unsigned short_count;
|
||||||
|
|
||||||
/* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
|
/* 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,
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < info->instance_count; 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,
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < info->instance_count; 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)
|
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,
|
static void r300_draw_vbo(struct pipe_context* pipe,
|
||||||
const struct pipe_draw_info *dinfo,
|
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 r300_context* r300 = r300_context(pipe);
|
||||||
struct pipe_draw_info info = *dinfo;
|
struct pipe_draw_info info = *dinfo;
|
||||||
|
struct pipe_draw_start_count draw = draws[0];
|
||||||
|
|
||||||
if (r300->skip_rendering ||
|
if (r300->skip_rendering ||
|
||||||
!u_trim_pipe_prim(info.mode, &info.count)) {
|
!u_trim_pipe_prim(info.mode, &draw.count)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,23 +820,23 @@ static void r300_draw_vbo(struct pipe_context* pipe,
|
||||||
info.max_index = max_count - 1;
|
info.max_index = max_count - 1;
|
||||||
|
|
||||||
if (info.instance_count <= 1) {
|
if (info.instance_count <= 1) {
|
||||||
if (info.count <= 8 && info.has_user_indices) {
|
if (draw.count <= 8 && info.has_user_indices) {
|
||||||
r300_draw_elements_immediate(r300, &info);
|
r300_draw_elements_immediate(r300, &info, &draw);
|
||||||
} else {
|
} else {
|
||||||
r300_draw_elements(r300, &info, -1);
|
r300_draw_elements(r300, &info, &draw, -1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r300_draw_elements_instanced(r300, &info);
|
r300_draw_elements_instanced(r300, &info, &draw);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (info.instance_count <= 1) {
|
if (info.instance_count <= 1) {
|
||||||
if (immd_is_good_idea(r300, info.count)) {
|
if (immd_is_good_idea(r300, draw.count)) {
|
||||||
r300_draw_arrays_immediate(r300, &info);
|
r300_draw_arrays_immediate(r300, &info, &draw);
|
||||||
} else {
|
} else {
|
||||||
r300_draw_arrays(r300, &info, -1);
|
r300_draw_arrays(r300, &info, &draw, -1);
|
||||||
}
|
}
|
||||||
} else {
|
} 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. */
|
/* SW TCL elements, using Draw. */
|
||||||
static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
|
static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
|
||||||
const struct pipe_draw_info *info,
|
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_context* r300 = r300_context(pipe);
|
||||||
|
struct pipe_draw_start_count draw = draws[0];
|
||||||
|
|
||||||
if (r300->skip_rendering) {
|
if (r300->skip_rendering) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
if (!u_trim_pipe_prim(info->mode, &draw.count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
|
@ -861,7 +873,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
|
||||||
|
|
||||||
r300_update_derived_state(r300);
|
r300_update_derived_state(r300);
|
||||||
|
|
||||||
draw_vbo(r300->draw, info, NULL);
|
draw_vbo(r300->draw, info, NULL, &draw, 1);
|
||||||
draw_flush(r300->draw);
|
draw_flush(r300->draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,9 @@
|
||||||
struct r300_stencilref_context {
|
struct r300_stencilref_context {
|
||||||
void (*draw_vbo)(struct pipe_context *pipe,
|
void (*draw_vbo)(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
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 rs_cull_mode;
|
||||||
uint32_t zb_stencilrefmask;
|
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,
|
static void r300_stencilref_draw_vbo(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
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_context *r300 = r300_context(pipe);
|
||||||
struct r300_stencilref_context *sr = r300->stencilref_fallback;
|
struct r300_stencilref_context *sr = r300->stencilref_fallback;
|
||||||
|
|
||||||
if (!r300_stencilref_needed(r300)) {
|
if (!r300_stencilref_needed(r300)) {
|
||||||
sr->draw_vbo(pipe, info, NULL);
|
sr->draw_vbo(pipe, info, NULL, draws, num_draws);
|
||||||
} else {
|
} else {
|
||||||
r300_stencilref_begin(r300);
|
r300_stencilref_begin(r300);
|
||||||
sr->draw_vbo(pipe, info, NULL);
|
sr->draw_vbo(pipe, info, NULL, draws, num_draws);
|
||||||
r300_stencilref_switch_side(r300);
|
r300_stencilref_switch_side(r300);
|
||||||
sr->draw_vbo(pipe, info, NULL);
|
sr->draw_vbo(pipe, info, NULL, draws, num_draws);
|
||||||
r300_stencilref_end(r300);
|
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,
|
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 r600_context *rctx = (struct r600_context *)ctx;
|
||||||
struct pipe_resource *indexbuf = info->has_user_indices ? NULL : info->index.resource;
|
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;
|
indirect = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!indirect && !info->count && (index_size || !count_from_so)) {
|
if (!indirect && !draws[0].count && (index_size || !count_from_so)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2135,7 +2137,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index_size) {
|
if (index_size) {
|
||||||
index_offset += info->start * index_size;
|
index_offset += draws[0].start * index_size;
|
||||||
|
|
||||||
/* Translate 8-bit indices to 16-bit. */
|
/* Translate 8-bit indices to 16-bit. */
|
||||||
if (unlikely(index_size == 1)) {
|
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)) {
|
if (likely(!indirect)) {
|
||||||
start = 0;
|
start = 0;
|
||||||
count = info->count;
|
count = draws[0].count;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Have to get start/count from indirect buffer, slow path ahead... */
|
/* 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. */
|
* Note: Instanced rendering in combination with immediate indices hangs. */
|
||||||
if (has_user_indices && (R600_BIG_ENDIAN || indirect ||
|
if (has_user_indices && (R600_BIG_ENDIAN || indirect ||
|
||||||
info->instance_count > 1 ||
|
info->instance_count > 1 ||
|
||||||
info->count*index_size > 20)) {
|
draws[0].count*index_size > 20)) {
|
||||||
indexbuf = NULL;
|
indexbuf = NULL;
|
||||||
u_upload_data(ctx->stream_uploader, 0,
|
u_upload_data(ctx->stream_uploader, 0,
|
||||||
info->count * index_size, 256,
|
draws[0].count * index_size, 256,
|
||||||
info->index.user, &index_offset, &indexbuf);
|
info->index.user, &index_offset, &indexbuf);
|
||||||
has_user_indices = false;
|
has_user_indices = false;
|
||||||
}
|
}
|
||||||
index_bias = info->index_bias;
|
index_bias = info->index_bias;
|
||||||
} else {
|
} else {
|
||||||
index_bias = info->start;
|
index_bias = draws[0].start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the index offset and primitive restart. */
|
/* 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)));
|
(VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0)));
|
||||||
|
|
||||||
if (has_user_indices) {
|
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;
|
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, 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(cs, V_0287F0_DI_SRC_SEL_IMMEDIATE);
|
||||||
radeon_emit_array(cs, info->index.user, size_dw);
|
radeon_emit_array(cs, info->index.user, size_dw);
|
||||||
} else {
|
} 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, PKT3(PKT3_DRAW_INDEX, 3, render_cond_bit));
|
||||||
radeon_emit(cs, va);
|
radeon_emit(cs, va);
|
||||||
radeon_emit(cs, (va >> 32UL) & 0xFF);
|
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, V_0287F0_DI_SRC_SEL_DMA);
|
||||||
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
|
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
|
||||||
radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx,
|
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)) {
|
if (likely(!indirect)) {
|
||||||
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_AUTO, 1, render_cond_bit));
|
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_AUTO, 1, render_cond_bit));
|
||||||
radeon_emit(cs, info->count);
|
radeon_emit(cs, draws[0].count);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
radeon_emit(cs, PKT3(EG_PKT3_DRAW_INDIRECT, 1, render_cond_bit));
|
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++) {
|
for (unsigned i = 0; i < num_draws; i++) {
|
||||||
if (count && count + draws[i].count > vert_count_per_subdraw) {
|
if (count && count + draws[i].count > vert_count_per_subdraw) {
|
||||||
/* Submit previous draws. */
|
/* 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;
|
count = 0;
|
||||||
first_draw = i;
|
first_draw = i;
|
||||||
num_draws_split = 0;
|
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) {
|
if (draws[i].count > vert_count_per_subdraw) {
|
||||||
/* Submit just 1 draw. It will be split. */
|
/* 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(count == 0);
|
||||||
assert(first_draw == i);
|
assert(first_draw == i);
|
||||||
assert(num_draws_split == 0);
|
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.start = base_start + start;
|
||||||
split_draw_range.count = MIN2(count - start, vert_count_per_subdraw);
|
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) {
|
} else if (prim == PIPE_PRIM_TRIANGLE_STRIP) {
|
||||||
/* No primitive pair can be split, because strips reverse orientation
|
/* 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.start = base_start + start;
|
||||||
split_draw_range.count = MIN2(count - start, vert_count_per_subdraw + 2);
|
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 &&
|
if (start == 0 && primitive_restart &&
|
||||||
sctx->cs_prim_discard_state.current->key.opt.cs_need_correct_orientation)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void si_multi_draw_vbo(struct pipe_context *ctx,
|
static void si_draw_vbo(struct pipe_context *ctx,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
const struct pipe_draw_start_count *draws,
|
||||||
unsigned num_draws)
|
unsigned num_draws)
|
||||||
{
|
{
|
||||||
struct si_context *sctx = (struct si_context *)ctx;
|
struct si_context *sctx = (struct si_context *)ctx;
|
||||||
struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
|
struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
|
||||||
|
@ -2247,15 +2247,6 @@ return_cleanup:
|
||||||
pipe_resource_reference(&indexbuf, NULL);
|
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,
|
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,
|
blitter_get_vs_func get_vs, int x1, int y1, int x2, int y2,
|
||||||
float depth, unsigned num_instances, enum blitter_attrib_type type,
|
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));
|
pipe->bind_vs_state(pipe, si_get_blitter_vs(sctx, type, num_instances));
|
||||||
|
|
||||||
struct pipe_draw_info info = {};
|
struct pipe_draw_info info = {};
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
info.mode = SI_PRIM_RECTANGLE_LIST;
|
info.mode = SI_PRIM_RECTANGLE_LIST;
|
||||||
info.count = 3;
|
|
||||||
info.instance_count = num_instances;
|
info.instance_count = num_instances;
|
||||||
|
|
||||||
|
draw.start = 0;
|
||||||
|
draw.count = 3;
|
||||||
|
|
||||||
/* Don't set per-stage shader pointers for VS. */
|
/* Don't set per-stage shader pointers for VS. */
|
||||||
sctx->shader_pointers_dirty &= ~SI_DESCS_SHADER_MASK(VERTEX);
|
sctx->shader_pointers_dirty &= ~SI_DESCS_SHADER_MASK(VERTEX);
|
||||||
sctx->vertex_buffer_pointer_dirty = false;
|
sctx->vertex_buffer_pointer_dirty = false;
|
||||||
sctx->vertex_buffer_user_sgprs_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)
|
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)
|
void si_init_draw_functions(struct si_context *sctx)
|
||||||
{
|
{
|
||||||
sctx->b.draw_vbo = si_draw_vbo;
|
sctx->b.draw_vbo = si_draw_vbo;
|
||||||
sctx->b.multi_draw = si_multi_draw_vbo;
|
|
||||||
|
|
||||||
sctx->blitter->draw_rectangle = si_draw_rectangle;
|
sctx->blitter->draw_rectangle = si_draw_rectangle;
|
||||||
|
|
||||||
si_init_ia_multi_vgt_param_table(sctx);
|
si_init_ia_multi_vgt_param_table(sctx);
|
||||||
|
|
|
@ -60,7 +60,9 @@
|
||||||
void
|
void
|
||||||
softpipe_draw_vbo(struct pipe_context *pipe,
|
softpipe_draw_vbo(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
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 softpipe_context *sp = softpipe_context(pipe);
|
||||||
struct draw_context *draw = sp->draw;
|
struct draw_context *draw = sp->draw;
|
||||||
|
@ -130,7 +132,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
|
||||||
sp->active_statistics_queries > 0);
|
sp->active_statistics_queries > 0);
|
||||||
|
|
||||||
/* draw! */
|
/* draw! */
|
||||||
draw_vbo(draw, info, indirect);
|
draw_vbo(draw, info, indirect, draws, num_draws);
|
||||||
|
|
||||||
/* unmap vertex/index buffers - will cause draw module to flush */
|
/* unmap vertex/index buffers - will cause draw module to flush */
|
||||||
for (i = 0; i < sp->num_vertex_buffers; i++) {
|
for (i = 0; i < sp->num_vertex_buffers; i++) {
|
||||||
|
|
|
@ -181,7 +181,9 @@ softpipe_set_sampler_views(struct pipe_context *pipe,
|
||||||
void
|
void
|
||||||
softpipe_draw_vbo(struct pipe_context *pipe,
|
softpipe_draw_vbo(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
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
|
void
|
||||||
softpipe_map_texture_surfaces(struct softpipe_context *sp);
|
softpipe_map_texture_surfaces(struct softpipe_context *sp);
|
||||||
|
|
|
@ -66,6 +66,7 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl,
|
||||||
enum pipe_error
|
enum pipe_error
|
||||||
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
|
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned count);
|
unsigned count);
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
static enum pipe_error
|
static enum pipe_error
|
||||||
translate_indices(struct svga_hwtnl *hwtnl,
|
translate_indices(struct svga_hwtnl *hwtnl,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
enum pipe_prim_type gen_prim,
|
enum pipe_prim_type gen_prim,
|
||||||
unsigned orig_nr, unsigned gen_nr,
|
unsigned orig_nr, unsigned gen_nr,
|
||||||
unsigned gen_size,
|
unsigned gen_size,
|
||||||
|
@ -74,7 +75,7 @@ translate_indices(struct svga_hwtnl *hwtnl,
|
||||||
struct pipe_transfer *src_transfer = NULL;
|
struct pipe_transfer *src_transfer = NULL;
|
||||||
struct pipe_transfer *dst_transfer = NULL;
|
struct pipe_transfer *dst_transfer = NULL;
|
||||||
const unsigned size = gen_size * gen_nr;
|
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;
|
const void *src_map = NULL;
|
||||||
struct pipe_resource *dst = NULL;
|
struct pipe_resource *dst = NULL;
|
||||||
void *dst_map = NULL;
|
void *dst_map = NULL;
|
||||||
|
@ -215,6 +216,7 @@ svga_hwtnl_simple_draw_range_elements(struct svga_hwtnl *hwtnl,
|
||||||
enum pipe_error
|
enum pipe_error
|
||||||
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
|
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned count)
|
unsigned count)
|
||||||
{
|
{
|
||||||
struct pipe_context *pipe = &hwtnl->svga->pipe;
|
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)) {
|
if ((gen_type == U_TRANSLATE_MEMCPY) && (info->index_size == gen_size)) {
|
||||||
/* No need for translation, just pass through to hardware:
|
/* 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;
|
struct pipe_resource *index_buffer = NULL;
|
||||||
unsigned index_offset;
|
unsigned index_offset;
|
||||||
|
|
||||||
|
@ -269,7 +271,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
|
||||||
index_offset /= info->index_size;
|
index_offset /= info->index_size;
|
||||||
} else {
|
} else {
|
||||||
pipe_resource_reference(&index_buffer, info->index.resource);
|
pipe_resource_reference(&index_buffer, info->index.resource);
|
||||||
index_offset = info->start;
|
index_offset = draw->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(index_buffer != NULL);
|
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
|
* GL though, as index buffers are typically used only once
|
||||||
* there.
|
* there.
|
||||||
*/
|
*/
|
||||||
ret = translate_indices(hwtnl, info, gen_prim,
|
ret = translate_indices(hwtnl, info, draw, gen_prim,
|
||||||
count, gen_nr, gen_size,
|
count, gen_nr, gen_size,
|
||||||
gen_func, &gen_buf, &gen_offset);
|
gen_func, &gen_buf, &gen_offset);
|
||||||
if (ret == PIPE_OK) {
|
if (ret == PIPE_OK) {
|
||||||
|
|
|
@ -45,11 +45,12 @@
|
||||||
static enum pipe_error
|
static enum pipe_error
|
||||||
retry_draw_range_elements(struct svga_context *svga,
|
retry_draw_range_elements(struct svga_context *svga,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
const struct pipe_draw_start_count *draw,
|
||||||
unsigned count)
|
unsigned count)
|
||||||
{
|
{
|
||||||
SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_DRAWELEMENTS);
|
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));
|
SVGA_STATS_TIME_POP(svga_sws(svga));
|
||||||
return PIPE_OK;
|
return PIPE_OK;
|
||||||
|
@ -217,11 +218,13 @@ get_vcount_from_stream_output(struct svga_context *svga,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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);
|
struct svga_context *svga = svga_context(pipe);
|
||||||
enum pipe_prim_type reduced_prim = u_reduced_prim(info->mode);
|
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;
|
enum pipe_error ret = 0;
|
||||||
boolean needed_swtnl;
|
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
|
* always start from 0 for DrawArrays and does not include baseVertex for
|
||||||
* DrawIndexed.
|
* DrawIndexed.
|
||||||
*/
|
*/
|
||||||
if (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 = info->start + info->index_bias;
|
svga->curr.vertex_id_bias = draws[0].start + info->index_bias;
|
||||||
svga->dirty |= SVGA_NEW_VS_CONSTS;
|
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)) {
|
if (need_fallback_prim_restart(svga, info)) {
|
||||||
enum pipe_error r;
|
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);
|
assert(r == PIPE_OK);
|
||||||
(void) r;
|
(void) r;
|
||||||
goto done;
|
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 */
|
/* Avoid leaking the previous hwtnl bias to swtnl */
|
||||||
svga_hwtnl_set_index_bias(svga->hwtnl, 0);
|
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 {
|
else {
|
||||||
if (!svga_update_state_retry(svga, SVGA_STATE_HW_DRAW)) {
|
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);
|
ret = retry_draw_indirect(svga, info, indirect);
|
||||||
}
|
}
|
||||||
else if (info->index_size) {
|
else if (info->index_size) {
|
||||||
ret = retry_draw_range_elements(svga, info, count);
|
ret = retry_draw_range_elements(svga, info, &draws[0], count);
|
||||||
}
|
}
|
||||||
else {
|
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->start_instance, info->instance_count,
|
||||||
info->vertices_per_patch);
|
info->vertices_per_patch);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ void svga_destroy_swtnl( struct svga_context *svga );
|
||||||
enum pipe_error
|
enum pipe_error
|
||||||
svga_swtnl_draw_vbo(struct svga_context *svga,
|
svga_swtnl_draw_vbo(struct svga_context *svga,
|
||||||
const struct pipe_draw_info *info,
|
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
|
#endif
|
||||||
|
|
|
@ -332,8 +332,10 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
|
||||||
.index_bias = bias,
|
.index_bias = bias,
|
||||||
.min_index = svga_render->min_index,
|
.min_index = svga_render->min_index,
|
||||||
.max_index = svga_render->max_index,
|
.max_index = svga_render->max_index,
|
||||||
|
};
|
||||||
|
const struct pipe_draw_start_count draw = {
|
||||||
.start = 0,
|
.start = 0,
|
||||||
.count = nr_indices
|
.count = nr_indices,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert((svga_render->vbuf_offset - svga_render->vdecl_offset)
|
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_update_state_retry(svga, SVGA_STATE_HW_DRAW);
|
||||||
SVGA_RETRY_CHECK(svga, svga_hwtnl_draw_range_elements(svga->hwtnl, &info,
|
SVGA_RETRY_CHECK(svga, svga_hwtnl_draw_range_elements(svga->hwtnl, &info,
|
||||||
|
&draw,
|
||||||
nr_indices), retried);
|
nr_indices), retried);
|
||||||
if (retried) {
|
if (retried) {
|
||||||
svga->swtnl.new_vbuf = TRUE;
|
svga->swtnl.new_vbuf = TRUE;
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
enum pipe_error
|
enum pipe_error
|
||||||
svga_swtnl_draw_vbo(struct svga_context *svga,
|
svga_swtnl_draw_vbo(struct svga_context *svga,
|
||||||
const struct pipe_draw_info *info,
|
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 *vb_transfer[PIPE_MAX_ATTRIBS] = { 0 };
|
||||||
struct pipe_transfer *ib_transfer = NULL;
|
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);
|
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);
|
draw_flush(svga->swtnl.draw);
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,15 @@
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
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);
|
struct swr_context *ctx = swr_context(pipe);
|
||||||
|
|
||||||
if (!indirect &&
|
if (!indirect &&
|
||||||
!info->primitive_restart &&
|
!info->primitive_restart &&
|
||||||
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!swr_check_render_cond(pipe))
|
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);
|
swr_update_draw_context(ctx);
|
||||||
|
|
||||||
struct pipe_draw_info resolved_info;
|
struct pipe_draw_info resolved_info;
|
||||||
|
struct pipe_draw_start_count resolved_draw;
|
||||||
/* DrawTransformFeedback */
|
/* DrawTransformFeedback */
|
||||||
if (indirect && indirect->count_from_stream_output) {
|
if (indirect && indirect->count_from_stream_output) {
|
||||||
// trick copied from softpipe to modify const struct *info
|
// trick copied from softpipe to modify const struct *info
|
||||||
memcpy(&resolved_info, (void*)info, sizeof(struct pipe_draw_info));
|
memcpy(&resolved_info, (void*)info, sizeof(struct pipe_draw_info));
|
||||||
resolved_info.count = ctx->so_primCounter * resolved_info.vertices_per_patch;
|
resolved_draw.start = draws[0].start;
|
||||||
resolved_info.max_index = resolved_info.count - 1;
|
resolved_draw.count = ctx->so_primCounter * resolved_info.vertices_per_patch;
|
||||||
|
resolved_info.max_index = resolved_draw.count - 1;
|
||||||
info = &resolved_info;
|
info = &resolved_info;
|
||||||
indirect = NULL;
|
indirect = NULL;
|
||||||
|
draws = &resolved_draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->vs->pipe.stream_output.num_outputs) {
|
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)
|
if (info->index_size)
|
||||||
ctx->api.pfnSwrDrawIndexedInstanced(ctx->swrContext,
|
ctx->api.pfnSwrDrawIndexedInstanced(ctx->swrContext,
|
||||||
swr_convert_prim_topology(info->mode, info->vertices_per_patch),
|
swr_convert_prim_topology(info->mode, info->vertices_per_patch),
|
||||||
info->count,
|
draws[0].count,
|
||||||
info->instance_count,
|
info->instance_count,
|
||||||
info->start,
|
draws[0].start,
|
||||||
info->index_bias,
|
info->index_bias,
|
||||||
info->start_instance);
|
info->start_instance);
|
||||||
else
|
else
|
||||||
ctx->api.pfnSwrDrawInstanced(ctx->swrContext,
|
ctx->api.pfnSwrDrawInstanced(ctx->swrContext,
|
||||||
swr_convert_prim_topology(info->mode, info->vertices_per_patch),
|
swr_convert_prim_topology(info->mode, info->vertices_per_patch),
|
||||||
info->count,
|
draws[0].count,
|
||||||
info->instance_count,
|
info->instance_count,
|
||||||
info->start,
|
draws[0].start,
|
||||||
info->start_instance);
|
info->start_instance);
|
||||||
|
|
||||||
/* On client-buffer draw, we used client buffer directly, without
|
/* On client-buffer draw, we used client buffer directly, without
|
||||||
|
|
|
@ -1158,7 +1158,8 @@ swr_get_last_fe(const struct swr_context *ctx)
|
||||||
|
|
||||||
void
|
void
|
||||||
swr_update_derived(struct pipe_context *pipe,
|
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_context *ctx = swr_context(pipe);
|
||||||
struct swr_screen *screen = swr_screen(pipe->screen);
|
struct swr_screen *screen = swr_screen(pipe->screen);
|
||||||
|
@ -1496,7 +1497,7 @@ swr_update_derived(struct pipe_context *pipe,
|
||||||
* revalidate on each draw */
|
* revalidate on each draw */
|
||||||
post_update_dirty_flags |= SWR_NEW_VERTEX;
|
post_update_dirty_flags |= SWR_NEW_VERTEX;
|
||||||
|
|
||||||
size = info.count * pitch;
|
size = draw->count * pitch;
|
||||||
|
|
||||||
size = AlignUp(size, 4);
|
size = AlignUp(size, 4);
|
||||||
/* If size of client memory copy is too large, don't copy. The
|
/* 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 *,
|
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.
|
* Conversion functions: Convert mesa state defines to SWR.
|
||||||
|
|
|
@ -47,7 +47,9 @@ tegra_destroy(struct pipe_context *pcontext)
|
||||||
static void
|
static void
|
||||||
tegra_draw_vbo(struct pipe_context *pcontext,
|
tegra_draw_vbo(struct pipe_context *pcontext,
|
||||||
const struct pipe_draw_info *pinfo,
|
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 tegra_context *context = to_tegra_context(pcontext);
|
||||||
struct pipe_draw_indirect_info indirect;
|
struct pipe_draw_indirect_info indirect;
|
||||||
|
@ -68,7 +70,7 @@ tegra_draw_vbo(struct pipe_context *pcontext,
|
||||||
pindirect = &indirect;
|
pindirect = &indirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->gpu->draw_vbo(context->gpu, pinfo, pindirect);
|
context->gpu->draw_vbo(context->gpu, pinfo, pindirect, draws, num_draws);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -977,14 +977,15 @@ v3d_emit_gl_shader_state(struct v3d_context *v3d,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
v3d_update_primitives_generated_counter(struct v3d_context *v3d,
|
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);
|
assert(!v3d->prog.gs);
|
||||||
|
|
||||||
if (!v3d->active_queries)
|
if (!v3d->active_queries)
|
||||||
return;
|
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;
|
v3d->prims_generated += prims;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,13 +1086,15 @@ v3d_check_compiled_shaders(struct v3d_context *v3d)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
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);
|
struct v3d_context *v3d = v3d_context(pctx);
|
||||||
|
|
||||||
if (!indirect &&
|
if (!indirect &&
|
||||||
!info->primitive_restart &&
|
!info->primitive_restart &&
|
||||||
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Fall back for weird desktop GL primitive restart values. */
|
/* 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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->mode >= PIPE_PRIM_QUADS && info->mode <= PIPE_PRIM_POLYGON) {
|
if (info->mode >= PIPE_PRIM_QUADS && info->mode <= PIPE_PRIM_POLYGON) {
|
||||||
util_primconvert_save_rasterizer_state(v3d->primconvert, &v3d->rasterizer->base);
|
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",
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,17 +1263,17 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!v3d->prog.gs)
|
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);
|
uint32_t hw_prim_type = v3d_hw_prim_type(info->mode);
|
||||||
if (info->index_size) {
|
if (info->index_size) {
|
||||||
uint32_t index_size = 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;
|
struct pipe_resource *prsc;
|
||||||
if (info->has_user_indices) {
|
if (info->has_user_indices) {
|
||||||
prsc = NULL;
|
prsc = NULL;
|
||||||
u_upload_data(v3d->uploader, 0,
|
u_upload_data(v3d->uploader, 0,
|
||||||
info->count * info->index_size, 4,
|
draws[0].count * info->index_size, 4,
|
||||||
info->index.user,
|
info->index.user,
|
||||||
&offset, &prsc);
|
&offset, &prsc);
|
||||||
} else {
|
} 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.enable_primitive_restarts = info->primitive_restart;
|
||||||
|
|
||||||
prim.number_of_instances = info->instance_count;
|
prim.number_of_instances = info->instance_count;
|
||||||
prim.instance_length = info->count;
|
prim.instance_length = draws[0].count;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cl_emit(&job->bcl, INDEXED_PRIM_LIST, prim) {
|
cl_emit(&job->bcl, INDEXED_PRIM_LIST, prim) {
|
||||||
prim.index_type = ffs(info->index_size) - 1;
|
prim.index_type = ffs(info->index_size) - 1;
|
||||||
prim.length = info->count;
|
prim.length = draws[0].count;
|
||||||
#if V3D_VERSION >= 40
|
#if V3D_VERSION >= 40
|
||||||
prim.index_offset = offset;
|
prim.index_offset = offset;
|
||||||
#else /* V3D_VERSION < 40 */
|
#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;
|
indirect->count_from_stream_output : NULL;
|
||||||
uint32_t vert_count = so ?
|
uint32_t vert_count = so ?
|
||||||
v3d_stream_output_target_get_vertex_count(so) :
|
v3d_stream_output_target_get_vertex_count(so) :
|
||||||
info->count;
|
draws[0].count;
|
||||||
cl_emit(&job->bcl, VERTEX_ARRAY_INSTANCED_PRIMS, prim) {
|
cl_emit(&job->bcl, VERTEX_ARRAY_INSTANCED_PRIMS, prim) {
|
||||||
prim.mode = hw_prim_type | prim_tf_enable;
|
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.number_of_instances = info->instance_count;
|
||||||
prim.instance_length = vert_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;
|
indirect->count_from_stream_output : NULL;
|
||||||
uint32_t vert_count = so ?
|
uint32_t vert_count = so ?
|
||||||
v3d_stream_output_target_get_vertex_count(so) :
|
v3d_stream_output_target_get_vertex_count(so) :
|
||||||
info->count;
|
draws[0].count;
|
||||||
cl_emit(&job->bcl, VERTEX_ARRAY_PRIMS, prim) {
|
cl_emit(&job->bcl, VERTEX_ARRAY_PRIMS, prim) {
|
||||||
prim.mode = hw_prim_type | prim_tf_enable;
|
prim.mode = hw_prim_type | prim_tf_enable;
|
||||||
prim.length = vert_count;
|
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.
|
* needs some clamping to the buffer size.
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < v3d->streamout.num_targets; i++)
|
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) {
|
if (v3d->zsa && job->zsbuf && v3d->zsa->base.depth.enabled) {
|
||||||
struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);
|
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
|
static void
|
||||||
vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
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 vc4_context *vc4 = vc4_context(pctx);
|
||||||
struct pipe_draw_info local_info;
|
struct pipe_draw_info local_info;
|
||||||
|
|
||||||
if (!indirect &&
|
if (!indirect &&
|
||||||
!info->primitive_restart &&
|
!info->primitive_restart &&
|
||||||
!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
|
!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (info->mode >= PIPE_PRIM_QUADS) {
|
if (info->mode >= PIPE_PRIM_QUADS) {
|
||||||
if (info->mode == PIPE_PRIM_QUADS &&
|
if (info->mode == PIPE_PRIM_QUADS &&
|
||||||
info->count == 4 &&
|
draws[0].count == 4 &&
|
||||||
!vc4->rasterizer->base.flatshade) {
|
!vc4->rasterizer->base.flatshade) {
|
||||||
local_info = *info;
|
local_info = *info;
|
||||||
local_info.mode = PIPE_PRIM_TRIANGLE_FAN;
|
local_info.mode = PIPE_PRIM_TRIANGLE_FAN;
|
||||||
info = &local_info;
|
info = &local_info;
|
||||||
} else {
|
} else {
|
||||||
util_primconvert_save_rasterizer_state(vc4->primconvert, &vc4->rasterizer->base);
|
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",
|
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;
|
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->verttex);
|
||||||
vc4_predraw_check_textures(pctx, &vc4->fragtex);
|
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);
|
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);
|
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) {
|
if (vc4->prim_mode != info->mode) {
|
||||||
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) {
|
if (info->index_size) {
|
||||||
uint32_t index_size = 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;
|
struct pipe_resource *prsc;
|
||||||
if (info->index_size == 4) {
|
if (info->index_size == 4) {
|
||||||
prsc = vc4_get_shadow_index_buffer(pctx, info,
|
prsc = vc4_get_shadow_index_buffer(pctx, info,
|
||||||
offset,
|
offset,
|
||||||
info->count, &offset);
|
draws[0].count, &offset);
|
||||||
index_size = 2;
|
index_size = 2;
|
||||||
} else {
|
} else {
|
||||||
if (info->has_user_indices) {
|
if (info->has_user_indices) {
|
||||||
prsc = NULL;
|
prsc = NULL;
|
||||||
u_upload_data(vc4->uploader, 0,
|
u_upload_data(vc4->uploader, 0,
|
||||||
info->count * index_size, 4,
|
draws[0].count * index_size, 4,
|
||||||
info->index.user,
|
info->index.user,
|
||||||
&offset, &prsc);
|
&offset, &prsc);
|
||||||
} else {
|
} else {
|
||||||
|
@ -416,7 +418,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
||||||
(index_size == 2 ?
|
(index_size == 2 ?
|
||||||
VC4_INDEX_BUFFER_U16:
|
VC4_INDEX_BUFFER_U16:
|
||||||
VC4_INDEX_BUFFER_U8));
|
VC4_INDEX_BUFFER_U8));
|
||||||
cl_u32(&bcl, info->count);
|
cl_u32(&bcl, draws[0].count);
|
||||||
cl_u32(&bcl, offset);
|
cl_u32(&bcl, offset);
|
||||||
cl_u32(&bcl, vc4->max_index);
|
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)
|
if (info->index_size == 4 || info->has_user_indices)
|
||||||
pipe_resource_reference(&prsc, NULL);
|
pipe_resource_reference(&prsc, NULL);
|
||||||
} else {
|
} else {
|
||||||
uint32_t count = info->count;
|
uint32_t count = draws[0].count;
|
||||||
uint32_t start = info->start;
|
uint32_t start = draws[0].start;
|
||||||
uint32_t extra_index_bias = 0;
|
uint32_t extra_index_bias = 0;
|
||||||
static const uint32_t max_verts = 65535;
|
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,
|
static void virgl_draw_vbo(struct pipe_context *ctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
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_context *vctx = virgl_context(ctx);
|
||||||
struct virgl_screen *rs = virgl_screen(ctx->screen);
|
struct virgl_screen *rs = virgl_screen(ctx->screen);
|
||||||
|
@ -858,22 +860,22 @@ static void virgl_draw_vbo(struct pipe_context *ctx,
|
||||||
|
|
||||||
if (!indirect &&
|
if (!indirect &&
|
||||||
!dinfo->primitive_restart &&
|
!dinfo->primitive_restart &&
|
||||||
!u_trim_pipe_prim(dinfo->mode, (unsigned*)&dinfo->count))
|
!u_trim_pipe_prim(dinfo->mode, (unsigned*)&draws[0].count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
|
if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
|
||||||
util_primconvert_save_rasterizer_state(vctx->primconvert, &vctx->rs_state.rs);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (info.index_size) {
|
if (info.index_size) {
|
||||||
pipe_resource_reference(&ib.buffer, info.has_user_indices ? NULL : info.index.resource);
|
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.user_buffer = info.has_user_indices ? info.index.user : NULL;
|
||||||
ib.index_size = dinfo->index_size;
|
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) {
|
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, &ib.offset, &ib.buffer);
|
||||||
ib.user_buffer = NULL;
|
ib.user_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
@ -887,7 +889,7 @@ static void virgl_draw_vbo(struct pipe_context *ctx,
|
||||||
if (info.index_size)
|
if (info.index_size)
|
||||||
virgl_hw_set_index_buffer(vctx, &ib);
|
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);
|
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,
|
int virgl_encoder_draw_vbo(struct virgl_context *ctx,
|
||||||
const struct pipe_draw_info *info,
|
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;
|
uint32_t length = VIRGL_DRAW_VBO_SIZE;
|
||||||
if (info->mode == PIPE_PRIM_PATCHES)
|
if (info->mode == PIPE_PRIM_PATCHES)
|
||||||
|
@ -716,8 +717,8 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx,
|
||||||
if (indirect && indirect->buffer)
|
if (indirect && indirect->buffer)
|
||||||
length = VIRGL_DRAW_VBO_SIZE_INDIRECT;
|
length = VIRGL_DRAW_VBO_SIZE_INDIRECT;
|
||||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DRAW_VBO, 0, length));
|
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, draw->start);
|
||||||
virgl_encoder_write_dword(ctx->cbuf, info->count);
|
virgl_encoder_write_dword(ctx->cbuf, draw->count);
|
||||||
virgl_encoder_write_dword(ctx->cbuf, info->mode);
|
virgl_encoder_write_dword(ctx->cbuf, info->mode);
|
||||||
virgl_encoder_write_dword(ctx->cbuf, !!info->index_size);
|
virgl_encoder_write_dword(ctx->cbuf, !!info->index_size);
|
||||||
virgl_encoder_write_dword(ctx->cbuf, info->instance_count);
|
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,
|
int virgl_encoder_draw_vbo(struct virgl_context *ctx,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
int virgl_encoder_create_surface(struct virgl_context *ctx,
|
||||||
|
|
|
@ -188,6 +188,8 @@ zink_blit(struct pipe_context *pctx,
|
||||||
void
|
void
|
||||||
zink_draw_vbo(struct pipe_context *pctx,
|
zink_draw_vbo(struct pipe_context *pctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
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
|
#endif
|
||||||
|
|
|
@ -209,7 +209,9 @@ restart_supported(enum pipe_prim_type mode)
|
||||||
void
|
void
|
||||||
zink_draw_vbo(struct pipe_context *pctx,
|
zink_draw_vbo(struct pipe_context *pctx,
|
||||||
const struct pipe_draw_info *dinfo,
|
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_context *ctx = zink_context(pctx);
|
||||||
struct zink_screen *screen = zink_screen(pctx->screen);
|
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)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (dinfo->mode == PIPE_PRIM_QUADS ||
|
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_POLYGON ||
|
||||||
(dinfo->mode == PIPE_PRIM_TRIANGLE_FAN && !screen->have_triangle_fans) ||
|
(dinfo->mode == PIPE_PRIM_TRIANGLE_FAN && !screen->have_triangle_fans) ||
|
||||||
dinfo->mode == PIPE_PRIM_LINE_LOOP) {
|
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;
|
return;
|
||||||
|
|
||||||
util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base);
|
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;
|
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);
|
uint32_t restart_index = util_prim_restart_index_from_size(dinfo->index_size);
|
||||||
if ((dinfo->primitive_restart && (dinfo->restart_index != restart_index)) ||
|
if ((dinfo->primitive_restart && (dinfo->restart_index != restart_index)) ||
|
||||||
(!screen->info.have_EXT_index_type_uint8 && dinfo->index_size == 8)) {
|
(!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;
|
need_index_buffer_unref = true;
|
||||||
} else {
|
} else {
|
||||||
if (dinfo->has_user_indices) {
|
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");
|
debug_printf("util_upload_index_buffer() failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -523,8 +525,8 @@ zink_draw_vbo(struct pipe_context *pctx,
|
||||||
vkCmdDrawIndexedIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
|
vkCmdDrawIndexedIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
|
||||||
} else
|
} else
|
||||||
vkCmdDrawIndexed(batch->cmdbuf,
|
vkCmdDrawIndexed(batch->cmdbuf,
|
||||||
dinfo->count, dinfo->instance_count,
|
draws[0].count, dinfo->instance_count,
|
||||||
need_index_buffer_unref ? 0 : dinfo->start, dinfo->index_bias, dinfo->start_instance);
|
need_index_buffer_unref ? 0 : draws[0].start, dinfo->index_bias, dinfo->start_instance);
|
||||||
} else {
|
} else {
|
||||||
if (so_target && screen->info.tf_props.transformFeedbackDraw) {
|
if (so_target && screen->info.tf_props.transformFeedbackDraw) {
|
||||||
zink_batch_reference_resource_rw(batch, zink_resource(so_target->counter_buffer), true);
|
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);
|
zink_batch_reference_resource_rw(batch, indirect, false);
|
||||||
vkCmdDrawIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
|
vkCmdDrawIndirect(batch->cmdbuf, indirect->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
|
||||||
} else
|
} 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))
|
if (dinfo->index_size > 0 && (dinfo->has_user_indices || need_index_buffer_unref))
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct rendering_state {
|
||||||
bool min_samples_dirty;
|
bool min_samples_dirty;
|
||||||
struct pipe_draw_indirect_info indirect_info;
|
struct pipe_draw_indirect_info indirect_info;
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
struct pipe_grid_info dispatch_info;
|
struct pipe_grid_info dispatch_info;
|
||||||
struct pipe_framebuffer_state framebuffer;
|
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_size = 0;
|
||||||
state->info.index.resource = NULL;
|
state->info.index.resource = NULL;
|
||||||
state->info.start = cmd->u.draw.first_vertex;
|
state->draw.start = cmd->u.draw.first_vertex;
|
||||||
state->info.count = cmd->u.draw.vertex_count;
|
state->draw.count = cmd->u.draw.vertex_count;
|
||||||
state->info.start_instance = cmd->u.draw.first_instance;
|
state->info.start_instance = cmd->u.draw.first_instance;
|
||||||
state->info.instance_count = cmd->u.draw.instance_count;
|
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,
|
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.max_index = ~0;
|
||||||
state->info.index_size = state->index_size;
|
state->info.index_size = state->index_size;
|
||||||
state->info.index.resource = state->index_buffer;
|
state->info.index.resource = state->index_buffer;
|
||||||
state->info.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
|
state->draw.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
|
||||||
state->info.count = cmd->u.draw_indexed.index_count;
|
state->draw.count = cmd->u.draw_indexed.index_count;
|
||||||
state->info.start_instance = cmd->u.draw_indexed.first_instance;
|
state->info.start_instance = cmd->u.draw_indexed.first_instance;
|
||||||
state->info.instance_count = cmd->u.draw_indexed.instance_count;
|
state->info.instance_count = cmd->u.draw_indexed.instance_count;
|
||||||
state->info.index_bias = cmd->u.draw_indexed.vertex_offset;
|
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->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,
|
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.stride = cmd->u.draw_indirect.stride;
|
||||||
state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
|
state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
|
||||||
state->indirect_info.buffer = cmd->u.draw_indirect.buffer->bo;
|
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,
|
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_info so;
|
||||||
struct pipe_stream_output_target *target;
|
struct pipe_stream_output_target *target;
|
||||||
struct pipe_draw_info draw;
|
struct pipe_draw_info draw;
|
||||||
|
struct pipe_draw_start_count sc;
|
||||||
struct pipe_box box;
|
struct pipe_box box;
|
||||||
bool programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t);
|
bool programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t);
|
||||||
unsigned offsets[1] = {0};
|
unsigned offsets[1] = {0};
|
||||||
|
@ -3170,13 +3171,13 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
|
||||||
}
|
}
|
||||||
|
|
||||||
draw.mode = PIPE_PRIM_POINTS;
|
draw.mode = PIPE_PRIM_POINTS;
|
||||||
draw.count = VertexCount;
|
sc.count = VertexCount;
|
||||||
draw.start_instance = 0;
|
draw.start_instance = 0;
|
||||||
draw.primitive_restart = FALSE;
|
draw.primitive_restart = FALSE;
|
||||||
draw.restart_index = 0;
|
draw.restart_index = 0;
|
||||||
draw.instance_count = 1;
|
draw.instance_count = 1;
|
||||||
draw.index_size = 0;
|
draw.index_size = 0;
|
||||||
draw.start = 0;
|
sc.start = 0;
|
||||||
draw.index_bias = 0;
|
draw.index_bias = 0;
|
||||||
draw.min_index = 0;
|
draw.min_index = 0;
|
||||||
draw.max_index = VertexCount - 1;
|
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->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->set_stream_output_targets(pipe_sw, 0, NULL, 0);
|
||||||
pipe_sw->stream_output_target_destroy(pipe_sw, target);
|
pipe_sw->stream_output_target_destroy(pipe_sw, target);
|
||||||
|
|
|
@ -2307,10 +2307,11 @@ CSMT_ITEM_NO_WAIT(nine_context_clear_fb,
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
init_draw_info(struct pipe_draw_info *info,
|
init_draw_info(struct pipe_draw_info *info,
|
||||||
|
struct pipe_draw_start_count *draw,
|
||||||
struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count)
|
struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count)
|
||||||
{
|
{
|
||||||
info->mode = d3dprimitivetype_to_pipe_prim(type);
|
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->start_instance = 0;
|
||||||
info->instance_count = 1;
|
info->instance_count = 1;
|
||||||
if (dev->context.stream_instancedata_mask & dev->context.stream_usage_mask)
|
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 nine_context *context = &device->context;
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
nine_update_state(device);
|
nine_update_state(device);
|
||||||
|
|
||||||
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
|
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
|
||||||
info.index_size = 0;
|
info.index_size = 0;
|
||||||
info.start = StartVertex;
|
draw.start = StartVertex;
|
||||||
info.index_bias = 0;
|
info.index_bias = 0;
|
||||||
info.min_index = info.start;
|
info.min_index = draw.start;
|
||||||
info.max_index = info.count - 1;
|
info.max_index = draw.count - 1;
|
||||||
info.index.resource = NULL;
|
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,
|
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 nine_context *context = &device->context;
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
nine_update_state(device);
|
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.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_bias = BaseVertexIndex;
|
||||||
info.index_bounds_valid = true;
|
info.index_bounds_valid = true;
|
||||||
/* These don't include index bias: */
|
/* 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.max_index = MinVertexIndex + NumVertices - 1;
|
||||||
info.index.resource = context->idxbuf;
|
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,
|
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 nine_context *context = &device->context;
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
nine_update_state(device);
|
nine_update_state(device);
|
||||||
|
|
||||||
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
|
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
|
||||||
info.index_size = 0;
|
info.index_size = 0;
|
||||||
info.start = 0;
|
draw.start = 0;
|
||||||
info.index_bias = 0;
|
info.index_bias = 0;
|
||||||
info.min_index = 0;
|
info.min_index = 0;
|
||||||
info.max_index = info.count - 1;
|
info.max_index = draw.count - 1;
|
||||||
info.index.resource = NULL;
|
info.index.resource = NULL;
|
||||||
|
|
||||||
context->pipe->set_vertex_buffers(context->pipe, 0, 1, vtxbuf);
|
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,
|
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 nine_context *context = &device->context;
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
nine_update_state(device);
|
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.index_size = index_size;
|
||||||
info.start = index_offset / info.index_size;
|
draw.start = index_offset / info.index_size;
|
||||||
info.index_bias = 0;
|
info.index_bias = 0;
|
||||||
info.index_bounds_valid = true;
|
info.index_bounds_valid = true;
|
||||||
info.min_index = MinVertexIndex;
|
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->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,
|
CSMT_ITEM_NO_WAIT(nine_context_resource_copy_region,
|
||||||
|
|
|
@ -108,45 +108,38 @@ struct pipe_context {
|
||||||
* VBO drawing
|
* 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
|
* For indirect multi draws, num_draws is 1 and indirect->draw_count
|
||||||
* "info->indirect".
|
* is used instead.
|
||||||
*
|
*
|
||||||
* Differences against draw_vbo:
|
* Caps:
|
||||||
* - "start" and "count" are taken from "draws", not "info"
|
* - PIPE_CAP_MULTI_DRAW: Direct multi draws
|
||||||
* - "info->has_user_indices" is always false
|
* - PIPE_CAP_MULTI_DRAW_INDIRECT: Indirect multi draws
|
||||||
* - "info->indirect" and "info->count_from_stream_output" are always NULL
|
* - PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: Indirect draw count
|
||||||
*
|
*
|
||||||
* Differences against glMultiDraw:
|
* Differences against glMultiDraw and glMultiMode:
|
||||||
* - "info->draw_id" is 0 and should be 0 for every draw
|
* - "info->mode" and "info->index_bias" are always constant due to the lack
|
||||||
* (we could make this configurable)
|
* of hardware support and CPU performance concerns. Only start and count
|
||||||
* - "info->index_bias" is always constant due to hardware performance
|
* vary.
|
||||||
* concerns (this is very important) and the lack of apps using
|
* - if "info->increment_draw_id" is false, draw_id doesn't change between
|
||||||
* glMultiDrawElementsBaseVertex.
|
* draws
|
||||||
*
|
*
|
||||||
* The main use case is to optimize applications that submit many
|
* Direct multi draws are also generated by u_threaded_context, which looks
|
||||||
* back-to-back draws or when mesa/main or st/mesa eliminates redundant
|
* ahead in gallium command buffers and merges single draws.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* \param pipe context
|
* \param pipe context
|
||||||
* \param info draw info
|
* \param info draw info
|
||||||
* \param draws array of (start, count) pairs
|
* \param indirect indirect multi draws
|
||||||
* \param num_draws number of 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,
|
void (*draw_vbo)(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
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,
|
const struct pipe_draw_start_count *draws,
|
||||||
unsigned num_draws);
|
unsigned num_draws);
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -749,14 +749,6 @@ struct pipe_draw_start_count {
|
||||||
*/
|
*/
|
||||||
struct pipe_draw_info
|
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 */
|
enum pipe_prim_type mode:8; /**< the mode of the primitive */
|
||||||
ubyte vertices_per_patch; /**< the number of vertices per patch */
|
ubyte vertices_per_patch; /**< the number of vertices per patch */
|
||||||
ubyte index_size; /**< if 0, the draw is not indexed. */
|
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} };
|
union pipe_color_union clear_color = { {1,0,1,1} };
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
|
struct pipe_draw_start_count draw;
|
||||||
|
|
||||||
ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
|
ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
|
||||||
|
|
||||||
|
@ -194,8 +195,8 @@ static void draw( void )
|
||||||
util_draw_init_info(&info);
|
util_draw_init_info(&info);
|
||||||
info.index_size = draw_elements ? 2 : 0;
|
info.index_size = draw_elements ? 2 : 0;
|
||||||
info.mode = PIPE_PRIM_TRIANGLES;
|
info.mode = PIPE_PRIM_TRIANGLES;
|
||||||
info.start = 0;
|
draw.start = 0;
|
||||||
info.count = 3;
|
draw.count = 3;
|
||||||
/* draw NUM_INST triangles */
|
/* draw NUM_INST triangles */
|
||||||
info.instance_count = NUM_INST;
|
info.instance_count = NUM_INST;
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ static void draw( void )
|
||||||
indices);
|
indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->draw_vbo(ctx, &info, NULL);
|
ctx->draw_vbo(ctx, &info, NULL, &draw, 1);
|
||||||
|
|
||||||
pipe_resource_reference(&info.index.resource, NULL);
|
pipe_resource_reference(&info.index.resource, NULL);
|
||||||
|
|
||||||
|
|
|
@ -223,31 +223,34 @@ st_draw_vbo(struct gl_context *ctx,
|
||||||
|
|
||||||
/* do actual drawing */
|
/* do actual drawing */
|
||||||
for (i = 0; i < nr_prims; i++) {
|
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. */
|
/* Skip no-op draw calls. */
|
||||||
if (!info.count)
|
if (!draw.count)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
draw.start = start + prims[i].start;
|
||||||
|
|
||||||
info.mode = translate_prim(ctx, prims[i].mode);
|
info.mode = translate_prim(ctx, prims[i].mode);
|
||||||
info.start = start + prims[i].start;
|
|
||||||
info.index_bias = prims[i].basevertex;
|
info.index_bias = prims[i].basevertex;
|
||||||
info.drawid = prims[i].draw_id;
|
info.drawid = prims[i].draw_id;
|
||||||
if (!ib) {
|
if (!ib) {
|
||||||
info.min_index = info.start;
|
info.min_index = draw.start;
|
||||||
info.max_index = info.start + info.count - 1;
|
info.max_index = draw.start + draw.count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ST_DEBUG & DEBUG_DRAW) {
|
if (ST_DEBUG & DEBUG_DRAW) {
|
||||||
debug_printf("st/draw: mode %s start %u count %u index_size %d\n",
|
debug_printf("st/draw: mode %s start %u count %u index_size %d\n",
|
||||||
u_prim_name(info.mode),
|
u_prim_name(info.mode),
|
||||||
info.start,
|
draw.start,
|
||||||
info.count,
|
draw.count,
|
||||||
info.index_size);
|
info.index_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't call u_trim_pipe_prim. Drivers should do it if they need it. */
|
/* 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 st_context *st = st_context(ctx);
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
struct pipe_draw_indirect_info indirect;
|
struct pipe_draw_indirect_info indirect;
|
||||||
|
struct pipe_draw_start_count draw = {0};
|
||||||
|
|
||||||
assert(stride);
|
assert(stride);
|
||||||
prepare_draw(st, ctx);
|
prepare_draw(st, ctx);
|
||||||
|
|
||||||
memset(&indirect, 0, sizeof(indirect));
|
memset(&indirect, 0, sizeof(indirect));
|
||||||
util_draw_init_info(&info);
|
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.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */
|
||||||
|
|
||||||
if (ib) {
|
if (ib) {
|
||||||
|
@ -282,7 +285,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
|
||||||
|
|
||||||
info.index_size = 1 << ib->index_size_shift;
|
info.index_size = 1 << ib->index_size_shift;
|
||||||
info.index.resource = st_buffer_object(bufobj)->buffer;
|
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. */
|
/* Primitive restart is not handled by the VBO module in this case. */
|
||||||
setup_primitive_restart(ctx, &info);
|
setup_primitive_restart(ctx, &info);
|
||||||
|
@ -307,7 +310,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
|
||||||
indirect.draw_count = 1;
|
indirect.draw_count = 1;
|
||||||
for (i = 0; i < draw_count; i++) {
|
for (i = 0; i < draw_count; i++) {
|
||||||
info.drawid = i;
|
info.drawid = i;
|
||||||
cso_draw_vbo(st->cso_context, &info, &indirect);
|
cso_draw_vbo(st->cso_context, &info, &indirect, draw);
|
||||||
indirect.offset += stride;
|
indirect.offset += stride;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -318,7 +321,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
|
||||||
st_buffer_object(indirect_draw_count)->buffer;
|
st_buffer_object(indirect_draw_count)->buffer;
|
||||||
indirect.indirect_draw_count_offset = indirect_draw_count_offset;
|
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 st_context *st = st_context(ctx);
|
||||||
struct pipe_draw_info info;
|
struct pipe_draw_info info;
|
||||||
struct pipe_draw_indirect_info indirect;
|
struct pipe_draw_indirect_info indirect;
|
||||||
|
struct pipe_draw_start_count draw = {0};
|
||||||
|
|
||||||
prepare_draw(st, ctx);
|
prepare_draw(st, ctx);
|
||||||
|
|
||||||
memset(&indirect, 0, sizeof(indirect));
|
memset(&indirect, 0, sizeof(indirect));
|
||||||
util_draw_init_info(&info);
|
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.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */
|
||||||
info.mode = translate_prim(ctx, mode);
|
info.mode = translate_prim(ctx, mode);
|
||||||
info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
|
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))
|
if (!st_transform_feedback_draw_init(tfb_vertcount, stream, &indirect))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cso_draw_vbo(st->cso_context, &info, &indirect);
|
cso_draw_vbo(st->cso_context, &info, &indirect, draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue