[Nouveau] [RFC PATCH 3/8] nv50: allocate and map a notifier buffer object for PM
Ilia Mirkin
imirkin at alum.mit.edu
Thu Jun 25 16:02:55 PDT 2015
On Mon, Jun 22, 2015 at 4:53 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> This notifier buffer object will be used to read back global performance
> counters results written by the kernel.
>
> For each domain, we will store the handle of the perfdom object, an
> array of 4 counters and the number of cycles. Like the Gallium's HUD,
> we keep a list of busy queries in a ring in order to prevent stalls
> when reading queries.
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
> src/gallium/drivers/nouveau/nv50/nv50_screen.c | 29 ++++++++++++++++++++++++++
> src/gallium/drivers/nouveau/nv50/nv50_screen.h | 6 ++++++
> 2 files changed, 35 insertions(+)
>
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> index c985344..3a99cc8 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> @@ -368,6 +368,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
> nouveau_object_del(&screen->m2mf);
> nouveau_object_del(&screen->sync);
> nouveau_object_del(&screen->sw);
> + nouveau_object_del(&screen->query);
>
> nouveau_screen_fini(&screen->base);
>
> @@ -699,9 +700,11 @@ nv50_screen_create(struct nouveau_device *dev)
> struct nv50_screen *screen;
> struct pipe_screen *pscreen;
> struct nouveau_object *chan;
> + struct nv04_fifo *fifo;
> uint64_t value;
> uint32_t tesla_class;
> unsigned stack_size;
> + uint32_t length;
> int ret;
>
> screen = CALLOC_STRUCT(nv50_screen);
> @@ -727,6 +730,7 @@ nv50_screen_create(struct nouveau_device *dev)
> screen->base.pushbuf->rsvd_kick = 5;
>
> chan = screen->base.channel;
> + fifo = chan->data;
>
> pscreen->destroy = nv50_screen_destroy;
> pscreen->context_create = nv50_create;
> @@ -772,6 +776,23 @@ nv50_screen_create(struct nouveau_device *dev)
> goto fail;
> }
>
> + /* Compute size (in bytes) of the notifier buffer object which is used
> + * in order to read back global performance counters results written
> + * by the kernel. For each domain, we store the handle of the perfdom
> + * object, an array of 4 counters and the number of cycles. Like for
> + * the Gallium's HUD, we keep a list of busy queries in a ring in order
> + * to prevent stalls when reading queries. */
> + length = (1 + (NV50_HW_PM_RING_BUFFER_NUM_DOMAINS * 6) *
> + NV50_HW_PM_RING_BUFFER_MAX_QUERIES) * 4;
This calculation may become apparent to me later, but it certainly
isn't now. What's the *6? You refer to an array of 4 counters...
should that have been 6 counters? Or should this have been a 4?
> +
> + ret = nouveau_object_new(chan, 0xbeef0302, NOUVEAU_NOTIFIER_CLASS,
> + &(struct nv04_notify){ .length = length },
> + sizeof(struct nv04_notify), &screen->query);
> + if (ret) {
> + NOUVEAU_ERR("Failed to allocate notifier object for PM: %d\n", ret);
> + goto fail;
> + }
> +
> ret = nouveau_object_new(chan, 0xbeef506e, 0x506e,
> NULL, 0, &screen->sw);
> if (ret) {
> @@ -845,6 +866,14 @@ nv50_screen_create(struct nouveau_device *dev)
> nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
> nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
>
> + ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify_bo);
> + if (ret == 0)
> + nouveau_bo_map(screen->notify_bo, 0, screen->base.client);
ret = ...
> + if (ret) {
> + NOUVEAU_ERR("Failed to map notifier object for PM: %d\n", ret);
> + goto fail;
> + }
> +
> nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
>
> screen->TPs = util_bitcount(value & 0xffff);
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.h b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
> index 69fdfdb..71a5247 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.h
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
> @@ -59,6 +59,7 @@ struct nv50_screen {
> struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */
> struct nouveau_bo *stack_bo;
> struct nouveau_bo *tls_bo;
> + struct nouveau_bo *notify_bo;
>
> unsigned TPs;
> unsigned MPsInTP;
> @@ -89,6 +90,7 @@ struct nv50_screen {
> } fence;
>
> struct nouveau_object *sync;
> + struct nouveau_object *query;
>
> struct nouveau_object *tesla;
> struct nouveau_object *eng2d;
> @@ -96,6 +98,10 @@ struct nv50_screen {
> struct nouveau_object *sw;
> };
>
> +/* Parameters of the ring buffer used to read back global PM counters. */
> +#define NV50_HW_PM_RING_BUFFER_NUM_DOMAINS 8
> +#define NV50_HW_PM_RING_BUFFER_MAX_QUERIES 9 /* HUD_NUM_QUERIES + 1 */
> +
> static INLINE struct nv50_screen *
> nv50_screen(struct pipe_screen *screen)
> {
> --
> 2.4.4
>
> _______________________________________________
> Nouveau mailing list
> Nouveau at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
More information about the Nouveau
mailing list