mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
nouveau/fence: per context fence
This doesn't add a fence list per pipe context, it simply makes us track the current fence per context so we can safely modify the fence object per thread. Signed-off-by: Karol Herbst <kherbst@redhat.com> Acked-by: M Henning <drawoc@darkrefraction.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
This commit is contained in:
parent
962a09c90f
commit
8e30cfc231
25 changed files with 124 additions and 141 deletions
|
|
@ -229,8 +229,8 @@ nouveau_transfer_write(struct nouveau_context *nv, struct nouveau_transfer *tx,
|
|||
else
|
||||
nv->push_data(nv, buf->bo, buf->offset + base, buf->domain, size, data);
|
||||
|
||||
nouveau_fence_ref(nv->screen->fence.current, &buf->fence);
|
||||
nouveau_fence_ref(nv->screen->fence.current, &buf->fence_wr);
|
||||
nouveau_fence_ref(nv->fence, &buf->fence);
|
||||
nouveau_fence_ref(nv->fence, &buf->fence_wr);
|
||||
}
|
||||
|
||||
/* Does a CPU wait for the buffer's backing data to become reliably accessible
|
||||
|
|
@ -299,10 +299,9 @@ nouveau_buffer_transfer_del(struct nouveau_context *nv,
|
|||
{
|
||||
if (tx->map) {
|
||||
if (likely(tx->bo)) {
|
||||
nouveau_fence_work(nv->screen->fence.current,
|
||||
nouveau_fence_unref_bo, tx->bo);
|
||||
nouveau_fence_work(nv->fence, nouveau_fence_unref_bo, tx->bo);
|
||||
if (tx->mm)
|
||||
release_allocation(&tx->mm, nv->screen->fence.current);
|
||||
release_allocation(&tx->mm, nv->fence);
|
||||
} else {
|
||||
align_free(tx->map -
|
||||
(tx->base.box.x & NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK));
|
||||
|
|
@ -597,11 +596,11 @@ nouveau_copy_buffer(struct nouveau_context *nv,
|
|||
src->bo, src->offset + srcx, src->domain, size);
|
||||
|
||||
dst->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
nouveau_fence_ref(nv->screen->fence.current, &dst->fence);
|
||||
nouveau_fence_ref(nv->screen->fence.current, &dst->fence_wr);
|
||||
nouveau_fence_ref(nv->fence, &dst->fence);
|
||||
nouveau_fence_ref(nv->fence, &dst->fence_wr);
|
||||
|
||||
src->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
nouveau_fence_ref(nv->screen->fence.current, &src->fence);
|
||||
nouveau_fence_ref(nv->fence, &src->fence);
|
||||
} else {
|
||||
struct pipe_box src_box;
|
||||
src_box.x = srcx;
|
||||
|
|
@ -849,9 +848,9 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
|
|||
nv->copy_data(nv, buf->bo, buf->offset, new_domain,
|
||||
bo, offset, old_domain, buf->base.width0);
|
||||
|
||||
nouveau_fence_work(screen->fence.current, nouveau_fence_unref_bo, bo);
|
||||
nouveau_fence_work(nv->fence, nouveau_fence_unref_bo, bo);
|
||||
if (mm)
|
||||
release_allocation(&mm, screen->fence.current);
|
||||
release_allocation(&mm, nv->fence);
|
||||
} else
|
||||
if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
|
||||
struct nouveau_transfer tx;
|
||||
|
|
@ -960,7 +959,7 @@ nouveau_scratch_runout_release(struct nouveau_context *nv)
|
|||
if (!nv->scratch.runout)
|
||||
return;
|
||||
|
||||
if (!nouveau_fence_work(nv->screen->fence.current, nouveau_scratch_unref_bos,
|
||||
if (!nouveau_fence_work(nv->fence, nouveau_scratch_unref_bos,
|
||||
nv->scratch.runout))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ struct nouveau_context {
|
|||
|
||||
struct nouveau_client *client;
|
||||
struct nouveau_pushbuf *pushbuf;
|
||||
struct nouveau_fence *fence;
|
||||
struct util_debug_callback debug;
|
||||
|
||||
bool vbo_dirty;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_winsys.h"
|
||||
#include "nouveau_fence.h"
|
||||
#include "util/os_time.h"
|
||||
|
|
@ -30,13 +31,14 @@
|
|||
#endif
|
||||
|
||||
bool
|
||||
nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence)
|
||||
nouveau_fence_new(struct nouveau_context *nv, struct nouveau_fence **fence)
|
||||
{
|
||||
*fence = CALLOC_STRUCT(nouveau_fence);
|
||||
if (!*fence)
|
||||
return false;
|
||||
|
||||
(*fence)->screen = screen;
|
||||
(*fence)->screen = nv->screen;
|
||||
(*fence)->context = nv;
|
||||
(*fence)->ref = 1;
|
||||
list_inithead(&(*fence)->work);
|
||||
|
||||
|
|
@ -112,18 +114,18 @@ nouveau_fence_del(struct nouveau_fence *fence)
|
|||
}
|
||||
|
||||
void
|
||||
nouveau_fence_cleanup(struct nouveau_fence_list *fence_list)
|
||||
nouveau_fence_cleanup(struct nouveau_context *nv)
|
||||
{
|
||||
if (fence_list->current) {
|
||||
if (nv->fence) {
|
||||
struct nouveau_fence *current = NULL;
|
||||
|
||||
/* nouveau_fence_wait will create a new current fence, so wait on the
|
||||
* _current_ one, and remove both.
|
||||
*/
|
||||
nouveau_fence_ref(fence_list->current, ¤t);
|
||||
nouveau_fence_ref(nv->fence, ¤t);
|
||||
nouveau_fence_wait(current, NULL);
|
||||
nouveau_fence_ref(NULL, ¤t);
|
||||
nouveau_fence_ref(NULL, &fence_list->current);
|
||||
nouveau_fence_ref(NULL, &nv->fence);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +190,7 @@ static bool
|
|||
nouveau_fence_kick(struct nouveau_fence *fence)
|
||||
{
|
||||
struct nouveau_screen *screen = fence->screen;
|
||||
struct nouveau_fence_list *fence_list = &screen->fence;
|
||||
bool current = !fence->sequence;
|
||||
|
||||
/* wtf, someone is waiting on a fence in flush_notify handler? */
|
||||
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
|
||||
|
|
@ -202,8 +204,8 @@ nouveau_fence_kick(struct nouveau_fence *fence)
|
|||
if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
|
||||
return false;
|
||||
|
||||
if (fence == fence_list->current)
|
||||
nouveau_fence_next(screen);
|
||||
if (current)
|
||||
nouveau_fence_next(fence->context);
|
||||
|
||||
nouveau_fence_update(screen, false);
|
||||
|
||||
|
|
@ -251,20 +253,18 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu
|
|||
}
|
||||
|
||||
void
|
||||
nouveau_fence_next(struct nouveau_screen *screen)
|
||||
nouveau_fence_next(struct nouveau_context *nv)
|
||||
{
|
||||
struct nouveau_fence_list *fence_list = &screen->fence;
|
||||
|
||||
if (fence_list->current->state < NOUVEAU_FENCE_STATE_EMITTING) {
|
||||
if (fence_list->current->ref > 1)
|
||||
nouveau_fence_emit(fence_list->current);
|
||||
if (nv->fence->state < NOUVEAU_FENCE_STATE_EMITTING) {
|
||||
if (nv->fence->ref > 1)
|
||||
nouveau_fence_emit(nv->fence);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
nouveau_fence_ref(NULL, &fence_list->current);
|
||||
nouveau_fence_ref(NULL, &nv->fence);
|
||||
|
||||
nouveau_fence_new(screen, &fence_list->current);
|
||||
nouveau_fence_new(nv, &nv->fence);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct nouveau_fence_work {
|
|||
struct nouveau_fence {
|
||||
struct nouveau_fence *next;
|
||||
struct nouveau_screen *screen;
|
||||
struct nouveau_context *context;
|
||||
int state;
|
||||
int ref;
|
||||
uint32_t sequence;
|
||||
|
|
@ -32,7 +33,6 @@ struct nouveau_fence {
|
|||
struct nouveau_fence_list {
|
||||
struct nouveau_fence *head;
|
||||
struct nouveau_fence *tail;
|
||||
struct nouveau_fence *current;
|
||||
uint32_t sequence;
|
||||
uint32_t sequence_ack;
|
||||
void (*emit)(struct pipe_screen *, uint32_t *sequence);
|
||||
|
|
@ -42,11 +42,11 @@ struct nouveau_fence_list {
|
|||
void nouveau_fence_emit(struct nouveau_fence *);
|
||||
void nouveau_fence_del(struct nouveau_fence *);
|
||||
|
||||
bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **);
|
||||
void nouveau_fence_cleanup(struct nouveau_fence_list *);
|
||||
bool nouveau_fence_new(struct nouveau_context *, struct nouveau_fence **);
|
||||
void nouveau_fence_cleanup(struct nouveau_context *);
|
||||
bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
|
||||
void nouveau_fence_update(struct nouveau_screen *, bool flushed);
|
||||
void nouveau_fence_next(struct nouveau_screen *);
|
||||
void nouveau_fence_next(struct nouveau_context *);
|
||||
bool nouveau_fence_wait(struct nouveau_fence *, struct util_debug_callback *);
|
||||
bool nouveau_fence_signalled(struct nouveau_fence *);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
|
|||
nv30 = container_of(push->user_priv, struct nv30_context, bufctx);
|
||||
screen = &nv30->screen->base;
|
||||
|
||||
nouveau_fence_next(screen);
|
||||
nouveau_fence_next(&nv30->base);
|
||||
nouveau_fence_update(screen, true);
|
||||
|
||||
if (push->bufctx) {
|
||||
|
|
@ -53,13 +53,13 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
|
|||
LIST_FOR_EACH_ENTRY(bref, &push->bufctx->current, thead) {
|
||||
struct nv04_resource *res = bref->priv;
|
||||
if (res && res->mm) {
|
||||
nouveau_fence_ref(screen->fence.current, &res->fence);
|
||||
nouveau_fence_ref(nv30->base.fence, &res->fence);
|
||||
|
||||
if (bref->flags & NOUVEAU_BO_RD)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
if (bref->flags & NOUVEAU_BO_WR) {
|
||||
nouveau_fence_ref(screen->fence.current, &res->fence_wr);
|
||||
nouveau_fence_ref(nv30->base.fence, &res->fence_wr);
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
|
||||
NOUVEAU_BUFFER_STATUS_DIRTY;
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ nv30_context_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence,
|
|||
struct nouveau_pushbuf *push = nv30->base.pushbuf;
|
||||
|
||||
if (fence)
|
||||
nouveau_fence_ref(nv30->screen->base.fence.current,
|
||||
nouveau_fence_ref(nv30->base.fence,
|
||||
(struct nouveau_fence **)fence);
|
||||
|
||||
PUSH_KICK(push);
|
||||
|
|
@ -176,6 +176,7 @@ nv30_context_destroy(struct pipe_context *pipe)
|
|||
if (nv30->screen->cur_ctx == nv30)
|
||||
nv30->screen->cur_ctx = NULL;
|
||||
|
||||
nouveau_fence_cleanup(&nv30->base);
|
||||
nouveau_context_destroy(&nv30->base);
|
||||
}
|
||||
|
||||
|
|
@ -257,6 +258,7 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
|||
}
|
||||
|
||||
nouveau_context_init_vdec(&nv30->base);
|
||||
nouveau_fence_new(&nv30->base, &nv30->base.fence);
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ nv30_miptree_transfer_unmap(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
/* Allow the copies above to finish executing before freeing the source */
|
||||
nouveau_fence_work(nv30->screen->base.fence.current,
|
||||
nouveau_fence_work(nv30->base.fence,
|
||||
nouveau_fence_unref_bo, tx->tmp.bo);
|
||||
} else {
|
||||
nouveau_bo_ref(NULL, &tx->tmp.bo);
|
||||
|
|
|
|||
|
|
@ -549,8 +549,6 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
|
|||
if (!nouveau_drm_screen_unref(&screen->base))
|
||||
return;
|
||||
|
||||
nouveau_fence_cleanup(&screen->base.fence);
|
||||
|
||||
nouveau_bo_ref(NULL, &screen->notify);
|
||||
|
||||
nouveau_heap_destroy(&screen->query_heap);
|
||||
|
|
@ -861,6 +859,5 @@ nv30_screen_create(struct nouveau_device *dev)
|
|||
PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);
|
||||
PUSH_KICK (push);
|
||||
|
||||
nouveau_fence_new(&screen->base, &screen->base.fence.current);
|
||||
return &screen->base;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,7 +463,6 @@ nv30_state_context_switch(struct nv30_context *nv30)
|
|||
bool
|
||||
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl)
|
||||
{
|
||||
struct nouveau_screen *screen = &nv30->screen->base;
|
||||
struct nouveau_pushbuf *push = nv30->base.pushbuf;
|
||||
struct nouveau_bufctx *bctx = nv30->bufctx;
|
||||
struct nouveau_bufref *bref;
|
||||
|
|
@ -523,13 +522,13 @@ nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl)
|
|||
LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) {
|
||||
struct nv04_resource *res = bref->priv;
|
||||
if (res && res->mm) {
|
||||
nouveau_fence_ref(screen->fence.current, &res->fence);
|
||||
nouveau_fence_ref(nv30->base.fence, &res->fence);
|
||||
|
||||
if (bref->flags & NOUVEAU_BO_RD)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
if (bref->flags & NOUVEAU_BO_WR) {
|
||||
nouveau_fence_ref(screen->fence.current, &res->fence_wr);
|
||||
nouveau_fence_ref(nv30->base.fence, &res->fence_wr);
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ nv50_state_validate_cp(struct nv50_context *nv50, uint32_t mask)
|
|||
nv50->bufctx_cp);
|
||||
|
||||
if (unlikely(nv50->state.flushed))
|
||||
nv50_bufctx_fence(nv50->bufctx_cp, true);
|
||||
nv50_bufctx_fence(nv50, nv50->bufctx_cp, true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -552,7 +552,7 @@ nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
|
|||
BEGIN_NV04(push, NV50_CP(USER_PARAM(1)), size / 4);
|
||||
nouveau_pushbuf_data(push, bo, offset, size);
|
||||
|
||||
nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, mm);
|
||||
nouveau_fence_work(nv50->base.fence, nouveau_mm_free_work, mm);
|
||||
nouveau_bo_ref(NULL, &bo);
|
||||
nouveau_bufctx_reset(nv50->bufctx, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,10 +34,9 @@ nv50_flush(struct pipe_context *pipe,
|
|||
unsigned flags)
|
||||
{
|
||||
struct nouveau_context *context = nouveau_context(pipe);
|
||||
struct nouveau_screen *screen = context->screen;
|
||||
|
||||
if (fence)
|
||||
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
|
||||
nouveau_fence_ref(context->fence, (struct nouveau_fence **)fence);
|
||||
|
||||
PUSH_KICK(context->pushbuf);
|
||||
|
||||
|
|
@ -136,12 +135,12 @@ void
|
|||
nv50_default_kick_notify(struct nouveau_pushbuf *push)
|
||||
{
|
||||
struct nv50_screen *screen = push->user_priv;
|
||||
struct nv50_context *context = screen->cur_ctx;
|
||||
|
||||
if (screen) {
|
||||
nouveau_fence_next(&screen->base);
|
||||
if (context) {
|
||||
nouveau_fence_next(&context->base);
|
||||
nouveau_fence_update(&screen->base, true);
|
||||
if (screen->cur_ctx)
|
||||
screen->cur_ctx->state.flushed = true;
|
||||
context->state.flushed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,6 +199,7 @@ nv50_destroy(struct pipe_context *pipe)
|
|||
|
||||
FREE(nv50->blit);
|
||||
|
||||
nouveau_fence_cleanup(&nv50->base);
|
||||
nouveau_context_destroy(&nv50->base);
|
||||
}
|
||||
|
||||
|
|
@ -414,6 +414,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
|||
// zero entry if it's not otherwise set.
|
||||
nv50->dirty_3d |= NV50_NEW_3D_SAMPLERS;
|
||||
|
||||
nouveau_fence_new(&nv50->base, &nv50->base.fence);
|
||||
|
||||
return pipe;
|
||||
|
||||
out_err:
|
||||
|
|
@ -431,7 +433,7 @@ out_err:
|
|||
}
|
||||
|
||||
void
|
||||
nv50_bufctx_fence(struct nouveau_bufctx *bufctx, bool on_flush)
|
||||
nv50_bufctx_fence(struct nv50_context *nv50, struct nouveau_bufctx *bufctx, bool on_flush)
|
||||
{
|
||||
struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
|
||||
struct nouveau_list *it;
|
||||
|
|
@ -440,7 +442,7 @@ nv50_bufctx_fence(struct nouveau_bufctx *bufctx, bool on_flush)
|
|||
struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
|
||||
struct nv04_resource *res = ref->priv;
|
||||
if (res)
|
||||
nv50_resource_validate(res, (unsigned)ref->priv_data);
|
||||
nv50_resource_validate(nv50, res, (unsigned)ref->priv_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,10 +254,28 @@ nv50_context_shader_stage(unsigned pipe)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
nv50_resource_validate(struct nv50_context *context, struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
if (likely(res->bo)) {
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
|
||||
NOUVEAU_BUFFER_STATUS_DIRTY;
|
||||
if (flags & NOUVEAU_BO_RD)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
if (res->mm) {
|
||||
nouveau_fence_ref(context->base.fence, &res->fence);
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
nouveau_fence_ref(context->base.fence, &res->fence_wr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nv50_context.c */
|
||||
struct pipe_context *nv50_create(struct pipe_screen *, void *, unsigned flags);
|
||||
|
||||
void nv50_bufctx_fence(struct nouveau_bufctx *, bool on_flush);
|
||||
void nv50_bufctx_fence(struct nv50_context *, struct nouveau_bufctx *, bool on_flush);
|
||||
|
||||
void nv50_default_kick_notify(struct nouveau_pushbuf *);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
|
|||
if (hq->state == NV50_HW_QUERY_STATE_READY)
|
||||
nouveau_mm_free(hq->mm);
|
||||
else
|
||||
nouveau_fence_work(screen->base.fence.current,
|
||||
nouveau_fence_work(nv50->base.fence,
|
||||
nouveau_mm_free_work, hq->mm);
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +265,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
|
|||
break;
|
||||
}
|
||||
if (hq->is64bit)
|
||||
nouveau_fence_ref(nv50->screen->base.fence.current, &hq->fence);
|
||||
nouveau_fence_ref(nv50->base.fence, &hq->fence);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -624,8 +624,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
|
|||
if (!nouveau_drm_screen_unref(&screen->base))
|
||||
return;
|
||||
|
||||
nouveau_fence_cleanup(&screen->base.fence);
|
||||
|
||||
if (screen->base.pushbuf)
|
||||
screen->base.pushbuf->user_priv = NULL;
|
||||
|
||||
|
|
@ -1215,8 +1213,6 @@ nv50_screen_create(struct nouveau_device *dev)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
nouveau_fence_new(&screen->base, &screen->base.fence.current);
|
||||
|
||||
return &screen->base;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -133,32 +133,6 @@ int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
|
|||
|
||||
int nv50_screen_compute_setup(struct nv50_screen *, struct nouveau_pushbuf *);
|
||||
|
||||
static inline void
|
||||
nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_screen(res->base.screen);
|
||||
|
||||
if (res->mm) {
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence);
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
nv50_resource_validate(struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
if (likely(res->bo)) {
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
|
||||
NOUVEAU_BUFFER_STATUS_DIRTY;
|
||||
if (flags & NOUVEAU_BO_RD)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
nv50_resource_fence(res, flags);
|
||||
}
|
||||
}
|
||||
|
||||
struct nv50_format {
|
||||
uint32_t rt;
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -556,7 +556,7 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask,
|
|||
PUSH_DATA (nv50->base.pushbuf, 0);
|
||||
}
|
||||
|
||||
nv50_bufctx_fence(bufctx, false);
|
||||
nv50_bufctx_fence(nv50, bufctx, false);
|
||||
}
|
||||
nouveau_pushbuf_bufctx(nv50->base.pushbuf, bufctx);
|
||||
ret = PUSH_VAL(nv50->base.pushbuf);
|
||||
|
|
@ -575,7 +575,7 @@ nv50_state_validate_3d(struct nv50_context *nv50, uint32_t mask)
|
|||
|
||||
if (unlikely(nv50->state.flushed)) {
|
||||
nv50->state.flushed = false;
|
||||
nv50_bufctx_fence(nv50->bufctx_3d, true);
|
||||
nv50_bufctx_fence(nv50, nv50->bufctx_3d, true);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -692,7 +692,7 @@ nv50_clear_buffer_push(struct pipe_context *pipe,
|
|||
count -= nr;
|
||||
}
|
||||
|
||||
nv50_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nv50_resource_validate(nv50, buf, NOUVEAU_BO_WR);
|
||||
|
||||
nouveau_bufctx_reset(nv50->bufctx, 0);
|
||||
}
|
||||
|
|
@ -815,7 +815,7 @@ nv50_clear_buffer(struct pipe_context *pipe,
|
|||
BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
|
||||
PUSH_DATA (push, nv50->cond_condmode);
|
||||
|
||||
nv50_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nv50_resource_validate(nv50, buf, NOUVEAU_BO_WR);
|
||||
|
||||
if (width * height != elements) {
|
||||
offset += width * height * data_size;
|
||||
|
|
@ -1679,7 +1679,7 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
|
|||
PUSH_DATA (push, srcy >> 32);
|
||||
}
|
||||
}
|
||||
nv50_bufctx_fence(nv50->bufctx, false);
|
||||
nv50_bufctx_fence(nv50, nv50->bufctx, false);
|
||||
|
||||
nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
|
||||
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx,
|
|||
}
|
||||
|
||||
/* Allow the copies above to finish executing before freeing the source */
|
||||
nouveau_fence_work(nv50->screen->base.fence.current,
|
||||
nouveau_fence_work(nv50->base.fence,
|
||||
nouveau_fence_unref_bo, tx->rect[1].bo);
|
||||
} else {
|
||||
nouveau_bo_ref(NULL, &tx->rect[1].bo);
|
||||
|
|
|
|||
|
|
@ -81,10 +81,9 @@ nvc0_flush(struct pipe_context *pipe,
|
|||
unsigned flags)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(pipe);
|
||||
struct nouveau_screen *screen = &nvc0->screen->base;
|
||||
|
||||
if (fence)
|
||||
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
|
||||
nouveau_fence_ref(nvc0->base.fence, (struct nouveau_fence **)fence);
|
||||
|
||||
PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
|
||||
|
||||
|
|
@ -272,6 +271,7 @@ nvc0_destroy(struct pipe_context *pipe)
|
|||
free(pos);
|
||||
}
|
||||
|
||||
nouveau_fence_cleanup(&nvc0->base);
|
||||
nouveau_context_destroy(&nvc0->base);
|
||||
}
|
||||
|
||||
|
|
@ -279,12 +279,12 @@ void
|
|||
nvc0_default_kick_notify(struct nouveau_pushbuf *push)
|
||||
{
|
||||
struct nvc0_screen *screen = push->user_priv;
|
||||
struct nvc0_context *nvc0 = screen->cur_ctx;
|
||||
|
||||
if (screen) {
|
||||
nouveau_fence_next(&screen->base);
|
||||
if (nvc0) {
|
||||
nouveau_fence_next(&nvc0->base);
|
||||
nouveau_fence_update(&screen->base, true);
|
||||
if (screen->cur_ctx)
|
||||
screen->cur_ctx->state.flushed = true;
|
||||
nvc0->state.flushed = true;
|
||||
NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -549,6 +549,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
|||
nvc0->dirty_cp |= NVC0_NEW_CP_SAMPLERS;
|
||||
}
|
||||
|
||||
nouveau_fence_new(&nvc0->base, &nvc0->base.fence);
|
||||
|
||||
return pipe;
|
||||
|
||||
out_err:
|
||||
|
|
@ -579,7 +581,7 @@ nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
|
|||
struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
|
||||
struct nv04_resource *res = ref->priv;
|
||||
if (res)
|
||||
nvc0_resource_validate(res, (unsigned)ref->priv_data);
|
||||
nvc0_resource_validate(nvc0, res, (unsigned)ref->priv_data);
|
||||
NOUVEAU_DRV_STAT_IFD(count++);
|
||||
}
|
||||
NOUVEAU_DRV_STAT(&nvc0->screen->base, resource_validate_count, count);
|
||||
|
|
|
|||
|
|
@ -310,6 +310,29 @@ nvc0_shader_stage(unsigned pipe)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
nvc0_resource_fence(struct nvc0_context *nvc0, struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
if (res->mm) {
|
||||
nouveau_fence_ref(nvc0->base.fence, &res->fence);
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
nouveau_fence_ref(nvc0->base.fence, &res->fence_wr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
nvc0_resource_validate(struct nvc0_context *nvc0, struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
if (likely(res->bo)) {
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
|
||||
NOUVEAU_BUFFER_STATUS_DIRTY;
|
||||
if (flags & NOUVEAU_BO_RD)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
nvc0_resource_fence(nvc0, res, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* nvc0_context.c */
|
||||
struct pipe_context *nvc0_create(struct pipe_screen *, void *, unsigned flags);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ nvc0_hw_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q,
|
|||
if (hq->state == NVC0_HW_QUERY_STATE_READY)
|
||||
nouveau_mm_free(hq->mm);
|
||||
else
|
||||
nouveau_fence_work(screen->base.fence.current,
|
||||
nouveau_fence_work(nvc0->base.fence,
|
||||
nouveau_mm_free_work, hq->mm);
|
||||
}
|
||||
}
|
||||
|
|
@ -301,7 +301,7 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q)
|
|||
break;
|
||||
}
|
||||
if (hq->is64bit)
|
||||
nouveau_fence_ref(nvc0->screen->base.fence.current, &hq->fence);
|
||||
nouveau_fence_ref(nvc0->base.fence, &hq->fence);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -412,7 +412,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
|
|||
util_range_add(&buf->base, &buf->valid_buffer_range, offset,
|
||||
offset + (result_type >= PIPE_QUERY_TYPE_I64 ? 8 : 4));
|
||||
|
||||
nvc0_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -511,7 +511,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
|
|||
util_range_add(&buf->base, &buf->valid_buffer_range, offset,
|
||||
offset + (result_type >= PIPE_QUERY_TYPE_I64 ? 8 : 4));
|
||||
|
||||
nvc0_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
|
||||
}
|
||||
|
||||
static const struct nvc0_query_funcs hw_query_funcs = {
|
||||
|
|
|
|||
|
|
@ -715,8 +715,6 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
|
|||
if (!nouveau_drm_screen_unref(&screen->base))
|
||||
return;
|
||||
|
||||
nouveau_fence_cleanup(&screen->base.fence);
|
||||
|
||||
if (screen->base.pushbuf)
|
||||
screen->base.pushbuf->user_priv = NULL;
|
||||
|
||||
|
|
@ -1573,8 +1571,6 @@ nvc0_screen_create(struct nouveau_device *dev)
|
|||
if (!nvc0_blitter_create(screen))
|
||||
goto fail;
|
||||
|
||||
nouveau_fence_new(&screen->base, &screen->base.fence.current);
|
||||
|
||||
return &screen->base;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -157,32 +157,6 @@ int nvc0_screen_resize_text_area(struct nvc0_screen *, uint64_t);
|
|||
// 3D Only
|
||||
void nvc0_screen_bind_cb_3d(struct nvc0_screen *, bool *, int, int, int, uint64_t);
|
||||
|
||||
static inline void
|
||||
nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0_screen(res->base.screen);
|
||||
|
||||
if (res->mm) {
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence);
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
nvc0_resource_validate(struct nv04_resource *res, uint32_t flags)
|
||||
{
|
||||
if (likely(res->bo)) {
|
||||
if (flags & NOUVEAU_BO_WR)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
|
||||
NOUVEAU_BUFFER_STATUS_DIRTY;
|
||||
if (flags & NOUVEAU_BO_RD)
|
||||
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
|
||||
|
||||
nvc0_resource_fence(res, flags);
|
||||
}
|
||||
}
|
||||
|
||||
struct nvc0_format {
|
||||
uint32_t rt;
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
|
|||
PUSH_DATA(push, 0);
|
||||
PUSH_DATA(push, 0);
|
||||
|
||||
nvc0_resource_fence(res, NOUVEAU_BO_WR);
|
||||
nvc0_resource_fence(nvc0, res, NOUVEAU_BO_WR);
|
||||
|
||||
assert(!fb->zsbuf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ nvc0_clear_render_target(struct pipe_context *pipe,
|
|||
IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0);
|
||||
|
||||
/* tiled textures don't have to be fenced, they're not mapped directly */
|
||||
nvc0_resource_fence(res, NOUVEAU_BO_WR);
|
||||
nvc0_resource_fence(nvc0, res, NOUVEAU_BO_WR);
|
||||
}
|
||||
|
||||
if (!render_condition_enabled)
|
||||
|
|
@ -410,7 +410,7 @@ nvc0_clear_buffer_push_nvc0(struct pipe_context *pipe,
|
|||
size -= nr * 4;
|
||||
}
|
||||
|
||||
nvc0_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
|
||||
|
||||
nouveau_bufctx_reset(nvc0->bufctx, 0);
|
||||
}
|
||||
|
|
@ -457,7 +457,7 @@ nvc0_clear_buffer_push_nve4(struct pipe_context *pipe,
|
|||
size -= nr * 4;
|
||||
}
|
||||
|
||||
nvc0_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
|
||||
|
||||
nouveau_bufctx_reset(nvc0->bufctx, 0);
|
||||
}
|
||||
|
|
@ -604,7 +604,7 @@ nvc0_clear_buffer(struct pipe_context *pipe,
|
|||
|
||||
IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
|
||||
|
||||
nvc0_resource_validate(buf, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
|
||||
|
||||
if (width * height != elements) {
|
||||
offset += width * height * data_size;
|
||||
|
|
@ -1589,8 +1589,8 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
|
|||
PUSH_DATA (push, srcy >> 32);
|
||||
}
|
||||
}
|
||||
nvc0_resource_validate(&dst->base, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(&src->base, NOUVEAU_BO_RD);
|
||||
nvc0_resource_validate(nvc0, &dst->base, NOUVEAU_BO_WR);
|
||||
nvc0_resource_validate(nvc0, &src->base, NOUVEAU_BO_RD);
|
||||
|
||||
nouveau_bufctx_reset(nvc0->bufctx, NVC0_BIND_2D);
|
||||
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
|
|||
NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_transfers_wr, 1);
|
||||
|
||||
/* Allow the copies above to finish executing before freeing the source */
|
||||
nouveau_fence_work(nvc0->screen->base.fence.current,
|
||||
nouveau_fence_work(nvc0->base.fence,
|
||||
nouveau_fence_unref_bo, tx->rect[1].bo);
|
||||
} else {
|
||||
nouveau_bo_ref(NULL, &tx->rect[1].bo);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue