nv50/vbo: wrap draw_vbo to avoid ovehead from multidraw
Same as the nvc0 patch pretty much, similar improvement. Signed-off-by: Yusuf Khan <yusisamerican@gmail.com> Reviewed-by: Karol Herbst <kherbst@redhat.com> --- v2: remove tmp_info as per Karol Herbst suggestion v3: nv50_draw_vbo -> nv50_draw_single_vbo per Karol's suggestion v4: mutex assertion and remove num_draws Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28641>
This commit is contained in:
@@ -354,9 +354,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 *, unsigned,
|
void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *, unsigned,
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
const struct pipe_draw_start_count_bias *draws,
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
unsigned num_draws);
|
unsigned num_draws);
|
||||||
|
|
||||||
void *
|
void *
|
||||||
nv50_vertex_state_create(struct pipe_context *pipe,
|
nv50_vertex_state_create(struct pipe_context *pipe,
|
||||||
|
@@ -754,21 +754,12 @@ nv50_draw_vbo_kick_notify(struct nouveau_context *context)
|
|||||||
_nouveau_fence_update(context->screen, true);
|
_nouveau_fence_update(context->screen, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
nv50_draw_single_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
||||||
unsigned drawid_offset,
|
unsigned drawid_offset,
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
const struct pipe_draw_start_count_bias *draws,
|
const struct pipe_draw_start_count_bias *draws)
|
||||||
unsigned num_draws)
|
|
||||||
{
|
{
|
||||||
if (num_draws > 1) {
|
|
||||||
util_draw_multi(pipe, info, drawid_offset, indirect, draws, num_draws);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!indirect && (!draws[0].count || !info->instance_count))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* We don't actually support indirect draws, so add a fallback for ES 3.1's
|
/* We don't actually support indirect draws, so add a fallback for ES 3.1's
|
||||||
* benefit.
|
* benefit.
|
||||||
*/
|
*/
|
||||||
@@ -782,41 +773,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
|||||||
bool tex_dirty = false;
|
bool tex_dirty = false;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
if (info->index_size && !info->has_user_indices)
|
simple_mtx_assert_locked(&nv50->screen->state_lock);
|
||||||
BCTX_REFN(nv50->bufctx_3d, 3D_INDEX, nv04_resource(info->index.resource), RD);
|
|
||||||
|
|
||||||
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
|
|
||||||
if (info->index_bounds_valid) {
|
|
||||||
nv50->vb_elt_first = info->min_index + (info->index_size ? draws->index_bias : 0);
|
|
||||||
nv50->vb_elt_limit = info->max_index - info->min_index;
|
|
||||||
} else {
|
|
||||||
nv50->vb_elt_first = 0;
|
|
||||||
nv50->vb_elt_limit = ~0;
|
|
||||||
}
|
|
||||||
nv50->instance_off = info->start_instance;
|
|
||||||
nv50->instance_max = info->instance_count - 1;
|
|
||||||
|
|
||||||
/* For picking only a few vertices from a large user buffer, push is better,
|
|
||||||
* if index count is larger and we expect repeated vertices, suggest upload.
|
|
||||||
*/
|
|
||||||
nv50->vbo_push_hint = /* the 64 is heuristic */
|
|
||||||
!(info->index_size && ((nv50->vb_elt_limit + 64) < draws[0].count));
|
|
||||||
|
|
||||||
if (nv50->dirty_3d & (NV50_NEW_3D_ARRAYS | NV50_NEW_3D_VERTEX))
|
|
||||||
nv50->vbo_constant = nv50->vertex->vbo_constant & nv50->vbo_user;
|
|
||||||
if (nv50->vbo_user && !(nv50->dirty_3d & (NV50_NEW_3D_ARRAYS | NV50_NEW_3D_VERTEX))) {
|
|
||||||
if (!!nv50->vbo_fifo != nv50->vbo_push_hint)
|
|
||||||
nv50->dirty_3d |= NV50_NEW_3D_ARRAYS;
|
|
||||||
else
|
|
||||||
if (!nv50->vbo_fifo)
|
|
||||||
nv50_update_user_vbufs(nv50);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(nv50->num_so_targets && !nv50->gmtyprog))
|
|
||||||
nv50->state.prim_size = nv50_pipe_prim_to_prim_size[info->mode];
|
|
||||||
|
|
||||||
simple_mtx_lock(&nv50->screen->state_lock);
|
|
||||||
nv50_state_validate_3d(nv50, ~0);
|
|
||||||
|
|
||||||
nv50->base.kick_notify = nv50_draw_vbo_kick_notify;
|
nv50->base.kick_notify = nv50_draw_vbo_kick_notify;
|
||||||
|
|
||||||
@@ -869,7 +826,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, &draws[0]);
|
nv50_push_vbo(nv50, info, indirect, &draws[0]);
|
||||||
goto cleanup;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv50->state.instance_base != info->start_instance) {
|
if (nv50->state.instance_base != info->start_instance) {
|
||||||
@@ -923,8 +880,73 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
|||||||
info->mode, draws[0].start, draws[0].count,
|
info->mode, draws[0].start, draws[0].count,
|
||||||
info->instance_count);
|
info->instance_count);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Thin wrapper to avoid kicking every 3 ns during multidraw */
|
||||||
|
|
||||||
|
void
|
||||||
|
nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
|
||||||
|
unsigned drawid_offset,
|
||||||
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
|
unsigned num_draws)
|
||||||
|
{
|
||||||
|
struct nv50_context *nv50 = nv50_context(pipe);
|
||||||
|
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||||
|
|
||||||
|
/* The rest is copied straight from util_multi_draw
|
||||||
|
*
|
||||||
|
* XXX: Properly rewrite vbo handling in nvc0/nv50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned drawid = drawid_offset;
|
||||||
|
|
||||||
|
/* dont wanna start trippin */
|
||||||
|
simple_mtx_lock(&nv50->screen->state_lock);
|
||||||
|
|
||||||
|
if (info->index_size && !info->has_user_indices)
|
||||||
|
BCTX_REFN(nv50->bufctx_3d, 3D_INDEX, nv04_resource(info->index.resource), RD);
|
||||||
|
|
||||||
|
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
|
||||||
|
if (info->index_bounds_valid) {
|
||||||
|
nv50->vb_elt_first = info->min_index + (info->index_size ? draws->index_bias : 0);
|
||||||
|
nv50->vb_elt_limit = info->max_index - info->min_index;
|
||||||
|
} else {
|
||||||
|
nv50->vb_elt_first = 0;
|
||||||
|
nv50->vb_elt_limit = ~0;
|
||||||
|
}
|
||||||
|
nv50->instance_off = info->start_instance;
|
||||||
|
nv50->instance_max = info->instance_count - 1;
|
||||||
|
|
||||||
|
/* For picking only a few vertices from a large user buffer, push is better,
|
||||||
|
* if index count is larger and we expect repeated vertices, suggest upload.
|
||||||
|
*/
|
||||||
|
nv50->vbo_push_hint = /* the 64 is heuristic */
|
||||||
|
!(info->index_size && ((nv50->vb_elt_limit + 64) < draws[0].count));
|
||||||
|
|
||||||
|
if (nv50->dirty_3d & (NV50_NEW_3D_ARRAYS | NV50_NEW_3D_VERTEX))
|
||||||
|
nv50->vbo_constant = nv50->vertex->vbo_constant & nv50->vbo_user;
|
||||||
|
if (nv50->vbo_user && !(nv50->dirty_3d & (NV50_NEW_3D_ARRAYS | NV50_NEW_3D_VERTEX))) {
|
||||||
|
if (!!nv50->vbo_fifo != nv50->vbo_push_hint)
|
||||||
|
nv50->dirty_3d |= NV50_NEW_3D_ARRAYS;
|
||||||
|
else
|
||||||
|
if (!nv50->vbo_fifo)
|
||||||
|
nv50_update_user_vbufs(nv50);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(nv50->num_so_targets && !nv50->gmtyprog))
|
||||||
|
nv50->state.prim_size = nv50_pipe_prim_to_prim_size[info->mode];
|
||||||
|
|
||||||
|
nv50_state_validate_3d(nv50, ~0);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < num_draws; i++) {
|
||||||
|
if (indirect || (draws[i].count && info->instance_count))
|
||||||
|
nv50_draw_single_vbo(pipe, info, drawid, indirect, &draws[i]);
|
||||||
|
if (info->increment_draw_id)
|
||||||
|
drawid++;
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
PUSH_KICK(push);
|
PUSH_KICK(push);
|
||||||
simple_mtx_unlock(&nv50->screen->state_lock);
|
simple_mtx_unlock(&nv50->screen->state_lock);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user