mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-11 23:10:28 +01:00
etnaviv: rework the stream flush to always go through the context flush
This way we can ensure that the pipe driver tracking of pending resources stays in sync with the actual command buffer state, even if a space reservation triggers a forced flush. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Jonathan Marek <jonathan@marek.ca>
This commit is contained in:
parent
1864fcd8c7
commit
1194afdfe3
4 changed files with 61 additions and 68 deletions
|
|
@ -57,7 +57,7 @@ etna_cmd_stream_priv(struct etna_cmd_stream *stream)
|
|||
|
||||
struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe,
|
||||
uint32_t size,
|
||||
void (*reset_notify)(struct etna_cmd_stream *stream, void *priv),
|
||||
void (*force_flush)(struct etna_cmd_stream *stream, void *priv),
|
||||
void *priv)
|
||||
{
|
||||
struct etna_cmd_stream_priv *stream = NULL;
|
||||
|
|
@ -84,8 +84,8 @@ struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe,
|
|||
|
||||
stream->base.size = size;
|
||||
stream->pipe = pipe;
|
||||
stream->reset_notify = reset_notify;
|
||||
stream->reset_notify_priv = priv;
|
||||
stream->force_flush = force_flush;
|
||||
stream->force_flush_priv = priv;
|
||||
|
||||
return &stream->base;
|
||||
|
||||
|
|
@ -106,18 +106,12 @@ void etna_cmd_stream_del(struct etna_cmd_stream *stream)
|
|||
free(priv);
|
||||
}
|
||||
|
||||
static void reset_buffer(struct etna_cmd_stream *stream)
|
||||
void etna_cmd_stream_force_flush(struct etna_cmd_stream *stream)
|
||||
{
|
||||
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
|
||||
|
||||
stream->offset = 0;
|
||||
priv->submit.nr_bos = 0;
|
||||
priv->submit.nr_relocs = 0;
|
||||
priv->submit.nr_pmrs = 0;
|
||||
priv->nr_bos = 0;
|
||||
|
||||
if (priv->reset_notify)
|
||||
priv->reset_notify(stream, priv->reset_notify_priv);
|
||||
if (priv->force_flush)
|
||||
priv->force_flush(stream, priv->force_flush_priv);
|
||||
}
|
||||
|
||||
uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream)
|
||||
|
|
@ -180,8 +174,8 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo,
|
|||
return idx;
|
||||
}
|
||||
|
||||
static void flush(struct etna_cmd_stream *stream, int in_fence_fd,
|
||||
int *out_fence_fd)
|
||||
void etna_cmd_stream_flush(struct etna_cmd_stream *stream, int in_fence_fd,
|
||||
int *out_fence_fd)
|
||||
{
|
||||
struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
|
||||
int ret, id = priv->pipe->id;
|
||||
|
|
@ -230,20 +224,12 @@ static void flush(struct etna_cmd_stream *stream, int in_fence_fd,
|
|||
|
||||
if (out_fence_fd)
|
||||
*out_fence_fd = req.fence_fd;
|
||||
}
|
||||
|
||||
void etna_cmd_stream_flush(struct etna_cmd_stream *stream)
|
||||
{
|
||||
flush(stream, -1, NULL);
|
||||
reset_buffer(stream);
|
||||
}
|
||||
|
||||
void etna_cmd_stream_flush2(struct etna_cmd_stream *stream,
|
||||
int in_fence_fd,
|
||||
int *out_fence_fd)
|
||||
{
|
||||
flush(stream, in_fence_fd, out_fence_fd);
|
||||
reset_buffer(stream);
|
||||
stream->offset = 0;
|
||||
priv->submit.nr_bos = 0;
|
||||
priv->submit.nr_relocs = 0;
|
||||
priv->submit.nr_pmrs = 0;
|
||||
priv->nr_bos = 0;
|
||||
}
|
||||
|
||||
void etna_cmd_stream_reloc(struct etna_cmd_stream *stream,
|
||||
|
|
|
|||
|
|
@ -143,9 +143,9 @@ struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe, uint32_t siz
|
|||
void *priv);
|
||||
void etna_cmd_stream_del(struct etna_cmd_stream *stream);
|
||||
uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream);
|
||||
void etna_cmd_stream_flush(struct etna_cmd_stream *stream);
|
||||
void etna_cmd_stream_flush2(struct etna_cmd_stream *stream, int in_fence_fd,
|
||||
void etna_cmd_stream_flush(struct etna_cmd_stream *stream, int in_fence_fd,
|
||||
int *out_fence_fd);
|
||||
void etna_cmd_stream_force_flush(struct etna_cmd_stream *stream);
|
||||
|
||||
static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream)
|
||||
{
|
||||
|
|
@ -157,7 +157,7 @@ static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream)
|
|||
static inline void etna_cmd_stream_reserve(struct etna_cmd_stream *stream, size_t n)
|
||||
{
|
||||
if (etna_cmd_stream_avail(stream) < n)
|
||||
etna_cmd_stream_flush(stream);
|
||||
etna_cmd_stream_force_flush(stream);
|
||||
}
|
||||
|
||||
static inline void etna_cmd_stream_emit(struct etna_cmd_stream *stream, uint32_t data)
|
||||
|
|
|
|||
|
|
@ -150,8 +150,8 @@ struct etna_cmd_stream_priv {
|
|||
uint32_t nr_bos, max_bos;
|
||||
|
||||
/* notify callback if buffer reset happened */
|
||||
void (*reset_notify)(struct etna_cmd_stream *stream, void *priv);
|
||||
void *reset_notify_priv;
|
||||
void (*force_flush)(struct etna_cmd_stream *stream, void *priv);
|
||||
void *force_flush_priv;
|
||||
|
||||
void *bo_table;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -336,37 +336,9 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||
pipe_resource_reference(&indexbuf, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
|
||||
enum pipe_flush_flags flags)
|
||||
static void etna_reset_gpu_state(struct etna_context *ctx)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_screen *screen = ctx->screen;
|
||||
int out_fence_fd = -1;
|
||||
|
||||
mtx_lock(&screen->lock);
|
||||
|
||||
list_for_each_entry(struct etna_hw_query, hq, &ctx->active_hw_queries, node)
|
||||
etna_hw_query_suspend(hq, ctx);
|
||||
|
||||
etna_cmd_stream_flush2(ctx->stream, ctx->in_fence_fd,
|
||||
(flags & PIPE_FLUSH_FENCE_FD) ? &out_fence_fd :
|
||||
NULL);
|
||||
|
||||
list_for_each_entry(struct etna_hw_query, hq, &ctx->active_hw_queries, node)
|
||||
etna_hw_query_resume(hq, ctx);
|
||||
|
||||
if (fence)
|
||||
*fence = etna_fence_create(pctx, out_fence_fd);
|
||||
|
||||
mtx_unlock(&screen->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
|
||||
{
|
||||
struct etna_context *ctx = priv;
|
||||
struct etna_screen *screen = ctx->screen;
|
||||
struct etna_cmd_stream *stream = ctx->stream;
|
||||
|
||||
etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL);
|
||||
etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x00000001);
|
||||
|
|
@ -417,12 +389,34 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
|
|||
|
||||
ctx->dirty = ~0L;
|
||||
ctx->dirty_sampler_views = ~0L;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
|
||||
enum pipe_flush_flags flags)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_screen *screen = ctx->screen;
|
||||
int out_fence_fd = -1;
|
||||
|
||||
mtx_lock(&screen->lock);
|
||||
|
||||
list_for_each_entry(struct etna_hw_query, hq, &ctx->active_hw_queries, node)
|
||||
etna_hw_query_suspend(hq, ctx);
|
||||
|
||||
etna_cmd_stream_flush(ctx->stream, ctx->in_fence_fd,
|
||||
(flags & PIPE_FLUSH_FENCE_FD) ? &out_fence_fd : NULL);
|
||||
|
||||
list_for_each_entry(struct etna_hw_query, hq, &ctx->active_hw_queries, node)
|
||||
etna_hw_query_resume(hq, ctx);
|
||||
|
||||
if (fence)
|
||||
*fence = etna_fence_create(pctx, out_fence_fd);
|
||||
|
||||
/*
|
||||
* Go through all _resources_ pending in this _context_ and mark them as
|
||||
* not pending in this _context_ anymore, since they were just flushed.
|
||||
*/
|
||||
mtx_lock(&screen->lock);
|
||||
* Go through all _resources_ pending in this _context_ and mark them as
|
||||
* not pending in this _context_ anymore, since they were just flushed.
|
||||
*/
|
||||
set_foreach(ctx->used_resources, entry) {
|
||||
struct etna_resource *rsc = (struct etna_resource *)entry->key;
|
||||
struct pipe_resource *referenced = &rsc->base;
|
||||
|
|
@ -434,7 +428,19 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
|
|||
pipe_resource_reference(&referenced, NULL);
|
||||
}
|
||||
_mesa_set_clear(ctx->used_resources, NULL);
|
||||
|
||||
mtx_unlock(&screen->lock);
|
||||
|
||||
etna_reset_gpu_state(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_context_force_flush(struct etna_cmd_stream *stream, void *priv)
|
||||
{
|
||||
struct pipe_context *pctx = priv;
|
||||
|
||||
pctx->flush(pctx, NULL, 0);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -468,7 +474,8 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
|||
pctx->const_uploader = pctx->stream_uploader;
|
||||
|
||||
screen = etna_screen(pscreen);
|
||||
ctx->stream = etna_cmd_stream_new(screen->pipe, 0x2000, &etna_cmd_stream_reset_notify, ctx);
|
||||
ctx->stream = etna_cmd_stream_new(screen->pipe, 0x2000,
|
||||
&etna_context_force_flush, pctx);
|
||||
if (ctx->stream == NULL)
|
||||
goto fail;
|
||||
|
||||
|
|
@ -484,7 +491,7 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
|||
ctx->sample_mask = 0xffff;
|
||||
|
||||
/* Set sensible defaults for state */
|
||||
etna_cmd_stream_reset_notify(ctx->stream, ctx);
|
||||
etna_reset_gpu_state(ctx);
|
||||
|
||||
ctx->in_fence_fd = -1;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue