diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h index e6cd7657913..b4c88c18e84 100644 --- a/src/gallium/drivers/nouveau/nouveau_context.h +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -16,6 +16,7 @@ struct nouveau_context { struct nouveau_client *client; struct nouveau_pushbuf *pushbuf; struct nouveau_fence *fence; + void (*kick_notify)(struct nouveau_context *); struct util_debug_callback debug; bool vbo_dirty; @@ -66,7 +67,7 @@ nouveau_context(struct pipe_context *pipe) void nouveau_context_init_vdec(struct nouveau_context *); -void +int MUST_CHECK nouveau_context_init(struct nouveau_context *, struct nouveau_screen *); void @@ -100,6 +101,9 @@ nouveau_context_destroy(struct nouveau_context *ctx) if (ctx->scratch.bo[i]) nouveau_bo_ref(NULL, &ctx->scratch.bo[i]); + nouveau_pushbuf_destroy(&ctx->pushbuf); + nouveau_client_del(&ctx->client); + FREE(ctx); } diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index 96b324d89cf..05808ebd68e 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -79,7 +79,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) fence_list->tail = fence; - fence_list->emit(&screen->base, &fence->sequence); + fence_list->emit(&fence->context->pipe, &fence->sequence); assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING); fence->state = NOUVEAU_FENCE_STATE_EMITTED; @@ -189,6 +189,7 @@ nouveau_fence_signalled(struct nouveau_fence *fence) static bool nouveau_fence_kick(struct nouveau_fence *fence) { + struct nouveau_context *context = fence->context; struct nouveau_screen *screen = fence->screen; bool current = !fence->sequence; @@ -196,12 +197,12 @@ nouveau_fence_kick(struct nouveau_fence *fence) assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING); if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) { - PUSH_SPACE(screen->pushbuf, 8); + PUSH_SPACE(context->pushbuf, 8); nouveau_fence_emit(fence); } if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) - if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel)) + if (nouveau_pushbuf_kick(context->pushbuf, context->pushbuf->channel)) return false; if (current) diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h index 2ea996521b1..49e74bfc52c 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.h +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -35,7 +35,7 @@ struct nouveau_fence_list { struct nouveau_fence *tail; uint32_t sequence; uint32_t sequence_ack; - void (*emit)(struct pipe_screen *, uint32_t *sequence); + void (*emit)(struct pipe_context *, uint32_t *sequence); uint32_t (*update)(struct pipe_screen *); }; diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 2338ff38b15..8121082c9e3 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -201,6 +201,48 @@ nouveau_query_memory_info(struct pipe_screen *pscreen, info->avail_staging_memory = dev->gart_limit / 1024; } +static void +nouveau_pushbuf_cb(struct nouveau_pushbuf *push) +{ + struct nouveau_pushbuf_priv *p = (struct nouveau_pushbuf_priv *)push->user_priv; + + if (p->context) + p->context->kick_notify(p->context); + else + nouveau_fence_update(p->screen, true); + + NOUVEAU_DRV_STAT(p->screen, pushbuf_count, 1); +} + +int +nouveau_pushbuf_create(struct nouveau_screen *screen, struct nouveau_context *context, + struct nouveau_client *client, struct nouveau_object *chan, int nr, + uint32_t size, bool immediate, struct nouveau_pushbuf **push) +{ + int ret; + ret = nouveau_pushbuf_new(client, chan, nr, size, immediate, push); + if (ret) + return ret; + + struct nouveau_pushbuf_priv *p = MALLOC_STRUCT(nouveau_pushbuf_priv); + if (!p) { + nouveau_pushbuf_del(push); + return -ENOMEM; + } + p->screen = screen; + p->context = context; + (*push)->kick_notify = nouveau_pushbuf_cb; + (*push)->user_priv = p; + return 0; +} + +void +nouveau_pushbuf_destroy(struct nouveau_pushbuf **push) +{ + FREE((*push)->user_priv); + nouveau_pushbuf_del(push); +} + int nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) { @@ -315,9 +357,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) ret = nouveau_client_new(screen->device, &screen->client); if (ret) goto err; - ret = nouveau_pushbuf_new(screen->client, screen->channel, - 4, 512 * 1024, 1, - &screen->pushbuf); + ret = nouveau_pushbuf_create(screen, NULL, screen->client, screen->channel, + 4, 512 * 1024, 1, + &screen->pushbuf); if (ret) goto err; @@ -384,7 +426,7 @@ nouveau_screen_fini(struct nouveau_screen *screen) nouveau_mm_destroy(screen->mm_GART); nouveau_mm_destroy(screen->mm_VRAM); - nouveau_pushbuf_del(&screen->pushbuf); + nouveau_pushbuf_destroy(&screen->pushbuf); nouveau_client_del(&screen->client); nouveau_object_del(&screen->channel); @@ -408,12 +450,23 @@ nouveau_set_debug_callback(struct pipe_context *pipe, memset(&context->debug, 0, sizeof(context->debug)); } -void +int nouveau_context_init(struct nouveau_context *context, struct nouveau_screen *screen) { - context->pipe.set_debug_callback = nouveau_set_debug_callback; + int ret; + context->pipe.set_debug_callback = nouveau_set_debug_callback; context->screen = screen; - context->client = screen->client; - context->pushbuf = screen->pushbuf; + + ret = nouveau_client_new(screen->device, &context->client); + if (ret) + return ret; + + ret = nouveau_pushbuf_create(screen, context, context->client, screen->channel, + 4, 512 * 1024, 1, + &context->pushbuf); + if (ret) + return ret; + + return 0; } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 100e9b207b2..eafeeb91b7e 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -110,6 +110,11 @@ struct nouveau_screen { #endif }; +struct nouveau_pushbuf_priv { + struct nouveau_screen *screen; + struct nouveau_context *context; +}; + #define NV_VRAM_DOMAIN(screen) ((screen)->vram_domain) #ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS @@ -150,4 +155,10 @@ void nouveau_screen_fini(struct nouveau_screen *); void nouveau_screen_init_vdec(struct nouveau_screen *); +int +nouveau_pushbuf_create(struct nouveau_screen *, struct nouveau_context *, struct nouveau_client *, + struct nouveau_object *chan, int nr, uint32_t size, bool immediate, + struct nouveau_pushbuf **); +void nouveau_pushbuf_destroy(struct nouveau_pushbuf **); + #endif diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c index 9637f39c8e2..a5596f980a5 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.c +++ b/src/gallium/drivers/nouveau/nouveau_video.c @@ -486,7 +486,7 @@ nouveau_decoder_destroy(struct pipe_video_codec *decoder) if (dec->bufctx) nouveau_bufctx_del(&dec->bufctx); if (dec->push) - nouveau_pushbuf_del(&dec->push); + nouveau_pushbuf_destroy(&dec->push); if (dec->client) nouveau_client_del(&dec->client); if (dec->chan) @@ -532,7 +532,7 @@ nouveau_create_decoder(struct pipe_context *context, ret = nouveau_client_new(screen->device, &dec->client); if (ret) goto fail; - ret = nouveau_pushbuf_new(dec->client, dec->chan, 2, 4096, 1, &dec->push); + ret = nouveau_pushbuf_create(screen, nouveau_context(context), dec->client, dec->chan, 2, 4096, 1, &dec->push); if (ret) goto fail; ret = nouveau_bufctx_new(dec->client, NV31_VIDEO_BIND_COUNT, &dec->bufctx); diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.c b/src/gallium/drivers/nouveau/nouveau_vp3_video.c index b3d93a69195..02cbe246520 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video.c +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.c @@ -214,11 +214,11 @@ nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder) if (dec->channel[0] != dec->channel[1]) { for (i = 0; i < 3; ++i) { - nouveau_pushbuf_del(&dec->pushbuf[i]); + nouveau_pushbuf_destroy(&dec->pushbuf[i]); nouveau_object_del(&dec->channel[i]); } } else { - nouveau_pushbuf_del(dec->pushbuf); + nouveau_pushbuf_destroy(dec->pushbuf); nouveau_object_del(dec->channel); } diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c index 2b8ea9700cf..7122858b9d1 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c @@ -30,6 +30,7 @@ #include "nv_object.xml.h" #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" +#include "nv30/nv30_winsys.h" #include "nv30/nv30_format.h" static inline uint32_t diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c index 3f25855d045..50c5071b266 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_context.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c @@ -33,19 +33,15 @@ #include "nv30/nv30_context.h" #include "nv30/nv30_transfer.h" #include "nv30/nv30_state.h" +#include "nv30/nv30_winsys.h" static void nv30_context_kick_notify(struct nouveau_pushbuf *push) { - struct nouveau_screen *screen; - struct nv30_context *nv30; + struct nouveau_pushbuf_priv *p = push->user_priv; + struct nouveau_screen *screen = p->screen; - if (!push->user_priv) - return; - nv30 = container_of(push->user_priv, struct nv30_context, bufctx); - screen = &nv30->screen->base; - - nouveau_fence_next(&nv30->base); + nouveau_fence_next(p->context); nouveau_fence_update(screen, true); if (push->bufctx) { @@ -53,13 +49,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(nv30->base.fence, &res->fence); + nouveau_fence_ref(p->context->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(nv30->base.fence, &res->fence_wr); + nouveau_fence_ref(p->context->fence, &res->fence_wr); res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING | NOUVEAU_BUFFER_STATUS_DIRTY; } @@ -168,9 +164,6 @@ nv30_context_destroy(struct pipe_context *pipe) if (nv30->blit_fp) pipe_resource_reference(&nv30->blit_fp, NULL); - if (nv30->screen->base.pushbuf->user_priv == &nv30->bufctx) - nv30->screen->base.pushbuf->user_priv = NULL; - nouveau_bufctx_del(&nv30->bufctx); if (nv30->screen->cur_ctx == nv30) @@ -207,7 +200,10 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) pipe->destroy = nv30_context_destroy; pipe->flush = nv30_context_flush; - nouveau_context_init(&nv30->base, &screen->base); + if (nouveau_context_init(&nv30->base, &screen->base)) { + nv30_context_destroy(pipe); + return NULL; + } nv30->base.pushbuf->kick_notify = nv30_context_kick_notify; nv30->base.pipe.stream_uploader = u_upload_create_default(&nv30->base.pipe); diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c index 0a08bda700d..0aafb506cb4 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c @@ -33,6 +33,7 @@ #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" #include "nv30/nv30_format.h" +#include "nv30/nv30_winsys.h" struct nv30_render { struct vbuf_render base; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c index 55857781f5f..9bc55b60a61 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c @@ -30,6 +30,7 @@ #include "nv_object.xml.h" #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" +#include "nv30/nv30_winsys.h" #include "nv30/nvfx_shader.h" static void diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c b/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c index 1a06eac4746..a46c4c4f1d9 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c @@ -29,6 +29,7 @@ #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" #include "nv30/nv30_format.h" +#include "nv30/nv30_winsys.h" void nv30_fragtex_validate(struct nv30_context *nv30) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c index 992a5d41d57..f712134f6cc 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c @@ -33,6 +33,7 @@ #include "nv30/nv30_context.h" #include "nv30/nv30_resource.h" #include "nv30/nv30_transfer.h" +#include "nv30/nv30_winsys.h" static inline unsigned layer_offset(struct pipe_resource *pt, unsigned level, unsigned layer) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_push.c b/src/gallium/drivers/nouveau/nv30/nv30_push.c index 4bd799c39f9..7b762bcb054 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_push.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_push.c @@ -33,6 +33,7 @@ #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" #include "nv30/nv30_resource.h" +#include "nv30/nv30_winsys.h" struct push_context { struct nouveau_pushbuf *push; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_query.c b/src/gallium/drivers/nouveau/nv30/nv30_query.c index 1335cb99b12..f15184f232f 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_query.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_query.c @@ -27,6 +27,7 @@ #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_screen.h" #include "nv30/nv30_context.h" +#include "nv30/nv30_winsys.h" struct nv30_query_object { struct list_head list; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 6c42b32eade..7fb6ecb605a 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -39,6 +39,7 @@ #include "nv30/nv30_context.h" #include "nv30/nv30_resource.h" #include "nv30/nv30_format.h" +#include "nv30/nv30_winsys.h" #define RANKINE_0397_CHIPSET 0x00000003 #define RANKINE_0497_CHIPSET 0x000001e0 @@ -519,10 +520,11 @@ nv30_screen_get_compiler_options(struct pipe_screen *pscreen, } static void -nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence) +nv30_screen_fence_emit(struct pipe_context *pcontext, uint32_t *sequence) { - struct nv30_screen *screen = nv30_screen(pscreen); - struct nouveau_pushbuf *push = screen->base.pushbuf; + struct nv30_context *nv30 = nv30_context(pcontext); + struct nv30_screen *screen = nv30->screen; + struct nouveau_pushbuf *push = nv30->base.pushbuf; *sequence = ++screen->base.fence.sequence; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.h b/src/gallium/drivers/nouveau/nv30/nv30_screen.h index c61a1ece54b..f0bc3683685 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.h +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.h @@ -9,7 +9,6 @@ #include "nouveau_screen.h" #include "nouveau_fence.h" #include "nouveau_heap.h" -#include "nv30/nv30_winsys.h" #include "nv30/nv30_resource.h" #include "compiler/nir/nir.h" diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c index 66f19f5906f..8de11ab67d0 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c @@ -31,6 +31,7 @@ #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" #include "nv30/nv30_format.h" +#include "nv30/nv30_winsys.h" static void nv30_validate_fb(struct nv30_context *nv30) @@ -457,7 +458,6 @@ nv30_state_context_switch(struct nv30_context *nv30) nv30->dirty &= ~NV30_NEW_ZSA; nv30->screen->cur_ctx = nv30; - nv30->base.pushbuf->user_priv = &nv30->bufctx; } bool diff --git a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c index c78b896a729..c5f5866af6b 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c @@ -36,6 +36,7 @@ #include "nv30/nv30_context.h" #include "nv30/nv30_transfer.h" +#include "nv30/nv30_winsys.h" /* Various helper functions to transfer different types of data in a number * of different ways. diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c index 3e24e90c735..22e309eb773 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c @@ -34,6 +34,7 @@ #include "nv30/nv30-40_3d.xml.h" #include "nv30/nv30_context.h" #include "nv30/nv30_format.h" +#include "nv30/nv30_winsys.h" static void nv30_emit_vtxattr(struct nv30_context *nv30, struct pipe_vertex_buffer *vb, @@ -586,7 +587,6 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, if (nv30->vbo_push_hint != !!nv30->vbo_fifo) nv30->dirty |= NV30_NEW_ARRAYS; - push->user_priv = &nv30->bufctx; if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS))) nv30_update_user_vbufs(nv30); diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c b/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c index 3866709c138..53e64a38722 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c @@ -33,6 +33,7 @@ #include "nv30/nv30_context.h" #include "nv30/nvfx_shader.h" #include "nv30/nv30_state.h" +#include "nv30/nv30_winsys.h" static void nv30_vertprog_destroy(struct nv30_vertprog *vp) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_winsys.h b/src/gallium/drivers/nouveau/nv30/nv30_winsys.h index 25897ea9f6b..a72af87c9b6 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_winsys.h +++ b/src/gallium/drivers/nouveau/nv30/nv30_winsys.h @@ -3,7 +3,9 @@ #include #include "nouveau_winsys.h" +#include "nouveau_context.h" #include "nouveau_buffer.h" +#include "nv30_context.h" /*XXX: rnn */ #define NV40_3D_VTXTEX_OFFSET(i) (0x0900 + ((i) * 0x20)) // 401e80 @@ -29,8 +31,8 @@ PUSH_RELOC(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t offset, static inline struct nouveau_bufctx * bufctx(struct nouveau_pushbuf *push) { - struct nouveau_bufctx **pctx = push->user_priv; - return *pctx; + struct nouveau_pushbuf_priv *p = push->user_priv; + return nv30_context(&p->context->pipe)->bufctx; } static inline void diff --git a/src/gallium/drivers/nouveau/nv30/nv40_verttex.c b/src/gallium/drivers/nouveau/nv30/nv40_verttex.c index 578695a22ab..04f428ea6ac 100644 --- a/src/gallium/drivers/nouveau/nv30/nv40_verttex.c +++ b/src/gallium/drivers/nouveau/nv30/nv40_verttex.c @@ -25,6 +25,7 @@ #include "util/u_inlines.h" #include "nv30/nv30_context.h" +#include "nv30/nv30_winsys.h" void nv40_verttex_validate(struct nv30_context *nv30) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c index 9fd5f08be4c..bbc4131a499 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_context.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c @@ -132,16 +132,13 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len) } void -nv50_default_kick_notify(struct nouveau_pushbuf *push) +nv50_default_kick_notify(struct nouveau_context *context) { - struct nv50_screen *screen = push->user_priv; - struct nv50_context *context = screen->cur_ctx; + struct nv50_context *nv50 = nv50_context(&context->pipe); - if (context) { - nouveau_fence_next(&context->base); - nouveau_fence_update(&screen->base, true); - context->state.flushed = true; - } + nouveau_fence_next(context); + nouveau_fence_update(context->screen, true); + nv50->state.flushed = true; } static void @@ -313,7 +310,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) if (!nv50_blitctx_create(nv50)) goto out_err; - nouveau_context_init(&nv50->base, &screen->base); + if (nouveau_context_init(&nv50->base, &screen->base)) + goto out_err; ret = nouveau_bufctx_new(nv50->base.client, 2, &nv50->bufctx); if (!ret) @@ -355,9 +353,11 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) */ nv50->state = screen->save_state; screen->cur_ctx = nv50; - nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx); } - nv50->base.pushbuf->kick_notify = nv50_default_kick_notify; + nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx); + nv50->base.kick_notify = nv50_default_kick_notify; + nv50->base.pushbuf->rsvd_kick = 5; + PUSH_SPACE(nv50->base.pushbuf, 8); nv50_init_query_functions(nv50); nv50_init_surface_functions(nv50); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h index dd3333a9dd2..5173d8d1f44 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_context.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h @@ -277,7 +277,7 @@ struct pipe_context *nv50_create(struct pipe_screen *, void *, unsigned flags); void nv50_bufctx_fence(struct nv50_context *, struct nouveau_bufctx *, bool on_flush); -void nv50_default_kick_notify(struct nouveau_pushbuf *); +void nv50_default_kick_notify(struct nouveau_context *); /* nv50_draw.c */ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 79a8f73ad85..7890791b2ef 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -624,9 +624,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen) if (!nouveau_drm_screen_unref(&screen->base)) return; - if (screen->base.pushbuf) - screen->base.pushbuf->user_priv = NULL; - if (screen->blitter) nv50_blitter_destroy(screen); if (screen->pm.prog) { @@ -660,10 +657,11 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } static void -nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) +nv50_screen_fence_emit(struct pipe_context *pcontext, u32 *sequence) { - struct nv50_screen *screen = nv50_screen(pscreen); - struct nouveau_pushbuf *push = screen->base.pushbuf; + struct nv50_context *nv50 = nv50_context(pcontext); + struct nv50_screen *screen = nv50->screen; + struct nouveau_pushbuf *push = nv50->base.pushbuf; /* we need to do it after possible flush in MARK_RING */ *sequence = ++screen->base.fence.sequence; @@ -1029,7 +1027,6 @@ nv50_screen_create(struct nouveau_device *dev) screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER; - screen->base.pushbuf->user_priv = screen; screen->base.pushbuf->rsvd_kick = 5; chan = screen->base.channel; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c index b8ea652a727..f2aebccb235 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c @@ -747,11 +747,9 @@ nva0_draw_stream_output(struct nv50_context *nv50, } static void -nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan) +nv50_draw_vbo_kick_notify(struct nouveau_context *context) { - struct nv50_screen *screen = chan->user_priv; - - nouveau_fence_update(&screen->base, true); + nouveau_fence_update(context->screen, true); } void @@ -815,7 +813,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, nv50_state_validate_3d(nv50, ~0); - push->kick_notify = nv50_draw_vbo_kick_notify; + nv50->base.kick_notify = nv50_draw_vbo_kick_notify; for (s = 0; s < NV50_MAX_3D_SHADER_STAGES && !nv50->cb_dirty; ++s) { if (nv50->constbuf_coherent[s]) @@ -922,7 +920,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, } cleanup: - push->kick_notify = nv50_default_kick_notify; + nv50->base.kick_notify = nv50_default_kick_notify; nv50_release_user_vbufs(nv50); diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c index 41f74a66770..f013d57c6f2 100644 --- a/src/gallium/drivers/nouveau/nv50/nv84_video.c +++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c @@ -249,11 +249,11 @@ nv84_decoder_destroy(struct pipe_video_codec *decoder) nouveau_object_del(&dec->vp); nouveau_bufctx_del(&dec->bsp_bufctx); - nouveau_pushbuf_del(&dec->bsp_pushbuf); + nouveau_pushbuf_destroy(&dec->bsp_pushbuf); nouveau_object_del(&dec->bsp_channel); nouveau_bufctx_del(&dec->vp_bufctx); - nouveau_pushbuf_del(&dec->vp_pushbuf); + nouveau_pushbuf_destroy(&dec->vp_pushbuf); nouveau_object_del(&dec->vp_channel); nouveau_client_del(&dec->client); @@ -337,8 +337,8 @@ nv84_create_decoder(struct pipe_context *context, if (ret) goto fail; - ret = nouveau_pushbuf_new(dec->client, dec->bsp_channel, 4, - 32 * 1024, true, &dec->bsp_pushbuf); + ret = nouveau_pushbuf_create(screen, &nv50->base, dec->client, dec->bsp_channel, + 4, 32 * 1024, true, &dec->bsp_pushbuf); if (ret) goto fail; @@ -352,8 +352,8 @@ nv84_create_decoder(struct pipe_context *context, &nv04_data, sizeof(nv04_data), &dec->vp_channel); if (ret) goto fail; - ret = nouveau_pushbuf_new(dec->client, dec->vp_channel, 4, - 32 * 1024, true, &dec->vp_pushbuf); + ret = nouveau_pushbuf_create(screen, &nv50->base, dec->client, dec->vp_channel, + 4, 32 * 1024, true, &dec->vp_pushbuf); if (ret) goto fail; diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video.c b/src/gallium/drivers/nouveau/nv50/nv98_video.c index 07cb05550b1..44e6f26daad 100644 --- a/src/gallium/drivers/nouveau/nv50/nv98_video.c +++ b/src/gallium/drivers/nouveau/nv50/nv98_video.c @@ -120,8 +120,8 @@ nv98_create_decoder(struct pipe_context *context, &nv04_data, sizeof(nv04_data), &dec->channel[0]); if (!ret) - ret = nouveau_pushbuf_new(nv50->base.client, dec->channel[0], 4, - 32 * 1024, true, &dec->pushbuf[0]); + ret = nouveau_pushbuf_create(screen, &nv50->base, nv50->base.client, dec->channel[0], + 4, 32 * 1024, true, &dec->pushbuf[0]); for (i = 1; i < 3; ++i) { dec->channel[i] = dec->channel[0]; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c index adc36531b28..1fd77b1db64 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c @@ -276,17 +276,14 @@ nvc0_destroy(struct pipe_context *pipe) } void -nvc0_default_kick_notify(struct nouveau_pushbuf *push) +nvc0_default_kick_notify(struct nouveau_context *context) { - struct nvc0_screen *screen = push->user_priv; - struct nvc0_context *nvc0 = screen->cur_ctx; + struct nvc0_context *nvc0 = nvc0_context(&context->pipe); - if (nvc0) { - nouveau_fence_next(&nvc0->base); - nouveau_fence_update(&screen->base, true); - nvc0->state.flushed = true; - NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1); - } + nouveau_fence_next(context); + nouveau_fence_update(context->screen, true); + + nvc0->state.flushed = true; } static int @@ -425,7 +422,10 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) if (!nvc0_blitctx_create(nvc0)) goto out_err; - nouveau_context_init(&nvc0->base, &screen->base); + if (nouveau_context_init(&nvc0->base, &screen->base)) + goto out_err; + nvc0->base.kick_notify = nvc0_default_kick_notify; + nvc0->base.pushbuf->rsvd_kick = 5; ret = nouveau_bufctx_new(nvc0->base.client, 2, &nvc0->bufctx); if (!ret) @@ -496,9 +496,9 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) if (!screen->cur_ctx) { nvc0->state = screen->save_state; screen->cur_ctx = nvc0; - nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx); } - screen->base.pushbuf->kick_notify = nvc0_default_kick_notify; + nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx); + PUSH_SPACE(nvc0->base.pushbuf, 8); /* add permanently resident buffers to bufctxts */ diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h index bda081d190f..6711e950e25 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h @@ -338,7 +338,7 @@ nvc0_resource_validate(struct nvc0_context *nvc0, struct nv04_resource *res, uin struct pipe_context *nvc0_create(struct pipe_screen *, void *, unsigned flags); void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *, bool on_flush); -void nvc0_default_kick_notify(struct nouveau_pushbuf *); +void nvc0_default_kick_notify(struct nouveau_context *); const void *nvc0_get_sample_locations(unsigned); /* nvc0_draw.c */ diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c index ff89fb6b461..86dd15520a5 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c @@ -905,7 +905,7 @@ nvc0_program_upload(struct nvc0_context *nvc0, struct nvc0_program *prog) IMMED_NVC0(nvc0->base.pushbuf, NVC0_3D(SERIALIZE), 0); if ((screen->text->size << 1) <= (1 << 23)) { - ret = nvc0_screen_resize_text_area(screen, screen->text->size << 1); + ret = nvc0_screen_resize_text_area(screen, nvc0->base.pushbuf, screen->text->size << 1); if (ret) { NOUVEAU_ERR("Error allocating TEXT area: %d\n", ret); return false; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index a7f3e5dbf2f..e6aac565bd2 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -715,9 +715,6 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) if (!nouveau_drm_screen_unref(&screen->base)) return; - if (screen->base.pushbuf) - screen->base.pushbuf->user_priv = NULL; - if (screen->blitter) nvc0_blitter_destroy(screen); if (screen->pm.prog) { @@ -859,10 +856,11 @@ nvc0_magic_3d_init(struct nouveau_pushbuf *push, uint16_t obj_class) } static void -nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) +nvc0_screen_fence_emit(struct pipe_context *pcontext, u32 *sequence) { - struct nvc0_screen *screen = nvc0_screen(pscreen); - struct nouveau_pushbuf *push = screen->base.pushbuf; + struct nvc0_context *nvc0 = nvc0_context(pcontext); + struct nvc0_screen *screen = nvc0->screen; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; /* we need to do it after possible flush in MARK_RING */ *sequence = ++screen->base.fence.sequence; @@ -942,9 +940,9 @@ nvc0_screen_resize_tls_area(struct nvc0_screen *screen, } int -nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size) +nvc0_screen_resize_text_area(struct nvc0_screen *screen, struct nouveau_pushbuf *push, + uint64_t size) { - struct nouveau_pushbuf *push = screen->base.pushbuf; struct nouveau_bo *bo; int ret; @@ -957,7 +955,7 @@ nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size) * segment, as it may have commands that will reference it. */ if (screen->text) - PUSH_REF1(push, screen->text, + PUSH_REF1(screen->base.pushbuf, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD); nouveau_bo_ref(NULL, &screen->text); screen->text = bo; @@ -986,13 +984,11 @@ nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size) } void -nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, bool *can_serialize, - int stage, int index, int size, uint64_t addr) +nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, struct nouveau_pushbuf *push, + bool *can_serialize, int stage, int index, int size, uint64_t addr) { assert(stage != 5); - struct nouveau_pushbuf *push = screen->base.pushbuf; - if (screen->base.class_3d >= GM107_3D_CLASS) { struct nvc0_cb_binding *binding = &screen->cb_bindings[stage][index]; @@ -1077,7 +1073,6 @@ nvc0_screen_create(struct nouveau_device *dev) FAIL_SCREEN_INIT("Base screen init failed: %d\n", ret); chan = screen->base.channel; push = screen->base.pushbuf; - push->user_priv = screen; push->rsvd_kick = 5; /* TODO: could this be higher on Kepler+? how does reclocking vs no @@ -1310,7 +1305,7 @@ nvc0_screen_create(struct nouveau_device *dev) nvc0_magic_3d_init(push, screen->eng3d->oclass); - ret = nvc0_screen_resize_text_area(screen, 1 << 19); + ret = nvc0_screen_resize_text_area(screen, push, 1 << 19); if (ret) FAIL_SCREEN_INIT("Error allocating TEXT area: %d\n", ret); @@ -1524,7 +1519,7 @@ nvc0_screen_create(struct nouveau_device *dev) /* TIC and TSC entries for each unit (nve4+ only) */ /* auxiliary constants (6 user clip planes, base instance id) */ - nvc0_screen_bind_cb_3d(screen, NULL, i, 15, NVC0_CB_AUX_SIZE, + nvc0_screen_bind_cb_3d(screen, push, NULL, i, 15, NVC0_CB_AUX_SIZE, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i)); if (screen->eng3d->oclass >= NVE4_3D_CLASS) { unsigned j; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h index 3a17bbcb3c9..3af38b59503 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h @@ -152,10 +152,10 @@ int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *); int nve4_screen_compute_setup(struct nvc0_screen *, struct nouveau_pushbuf *); int nvc0_screen_compute_setup(struct nvc0_screen *, struct nouveau_pushbuf *); -int nvc0_screen_resize_text_area(struct nvc0_screen *, uint64_t); +int nvc0_screen_resize_text_area(struct nvc0_screen *, struct nouveau_pushbuf *, uint64_t); // 3D Only -void nvc0_screen_bind_cb_3d(struct nvc0_screen *, bool *, int, int, int, uint64_t); +void nvc0_screen_bind_cb_3d(struct nvc0_screen *, struct nouveau_pushbuf *, bool *, int, int, int, uint64_t); struct nvc0_format { uint32_t rt; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c index 41d357e5848..3fb69b51208 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c @@ -577,6 +577,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) unsigned s; bool can_serialize = true; + struct nouveau_pushbuf *push = nvc0->base.pushbuf; for (s = 0; s < 5; ++s) { while (nvc0->constbuf_dirty[s]) { @@ -593,7 +594,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) if (!nvc0->state.uniform_buffer_bound[s]) { nvc0->state.uniform_buffer_bound[s] = true; - nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, + nvc0_screen_bind_cb_3d(nvc0->screen, push, &can_serialize, s, i, NVC0_MAX_CONSTBUF_SIZE, bo->offset + base); } nvc0_cb_bo_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base), @@ -604,7 +605,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) struct nv04_resource *res = nv04_resource(nvc0->constbuf[s][i].u.buf); if (res) { - nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, + nvc0_screen_bind_cb_3d(nvc0->screen, push, &can_serialize, s, i, nvc0->constbuf[s][i].size, res->address + nvc0->constbuf[s][i].offset); @@ -616,7 +617,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) if (i == 0) nvc0->state.uniform_buffer_bound[s] = false; } else if (i != 0) { - nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, -1, 0); + nvc0_screen_bind_cb_3d(nvc0->screen, push, &can_serialize, s, i, -1, 0); } } } @@ -717,7 +718,7 @@ nvc0_validate_driverconst(struct nvc0_context *nvc0) int i; for (i = 0; i < 5; ++i) - nvc0_screen_bind_cb_3d(screen, NULL, i, 15, NVC0_CB_AUX_SIZE, + nvc0_screen_bind_cb_3d(screen, nvc0->base.pushbuf, NULL, i, 15, NVC0_CB_AUX_SIZE, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i)); nvc0->dirty_cp |= NVC0_NEW_CP_DRIVERCONST; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index b9ca992ffcb..8f11296f812 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -557,13 +557,9 @@ nvc0_prim_gl(unsigned prim) } static void -nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push) +nvc0_draw_vbo_kick_notify(struct nouveau_context *context) { - struct nvc0_screen *screen = push->user_priv; - - nouveau_fence_update(&screen->base, true); - - NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1); + nouveau_fence_update(context->screen, true); } static void @@ -1047,7 +1043,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, nvc0->seamless_cube_map ? NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP : 0); } - push->kick_notify = nvc0_draw_vbo_kick_notify; + nvc0->base.kick_notify = nvc0_draw_vbo_kick_notify; for (s = 0; s < 5 && !nvc0->cb_dirty; ++s) { if (nvc0->constbuf_coherent[s]) @@ -1131,7 +1127,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, } cleanup: - push->kick_notify = nvc0_default_kick_notify; + nvc0->base.kick_notify = nvc0_default_kick_notify; nvc0_release_user_vbufs(nvc0); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c index 3ffc4204b81..d2aed4a7030 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c @@ -161,8 +161,8 @@ nvc0_create_decoder(struct pipe_context *context, data, size, &dec->channel[i]); if (!ret) - ret = nouveau_pushbuf_new(nvc0->base.client, dec->channel[i], 4, - 32 * 1024, true, &dec->pushbuf[i]); + ret = nouveau_pushbuf_create(screen, &nvc0->base, nvc0->base.client, dec->channel[i], + 4, 32 * 1024, true, &dec->pushbuf[i]); if (ret) break; }