X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fnouveau%2Fnouveau_sync.c;h=abb3088032ba140b486456b3c1a17e518b0af69f;hb=b7c93de6d798d7ccfc7bfa12b9c8f474de955d55;hp=0bf20e723bbfa545b169ca5c58e3f294ed18939d;hpb=6a3fdc3a1ea6c306d9543791bf172dd1052d7382;p=mesa.git diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 0bf20e723bb..abb3088032b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -1,57 +1,90 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + #include "vblank.h" /* for DO_USLEEP */ #include "nouveau_context.h" -#include "nouveau_buffers.h" -#include "nouveau_object.h" #include "nouveau_fifo.h" -#include "nouveau_reg.h" +#include "nouveau_mem.h" #include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" #include "nouveau_sync.h" -nouveau_notifier * -nouveau_notifier_new(GLcontext *ctx, GLuint handle) +#define NOTIFIER(__v) \ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ + volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset + +struct drm_nouveau_notifierobj_alloc * +nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_notifier *notifier; + struct drm_nouveau_notifierobj_alloc *notifier; + int ret; - notifier = CALLOC_STRUCT(nouveau_notifier_t); +#ifdef NOUVEAU_RING_DEBUG + return NULL; +#endif + notifier = CALLOC_STRUCT(drm_nouveau_notifierobj_alloc); if (!notifier) return NULL; - notifier->mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, - 32, - 0); - if (!notifier->mem) { + notifier->channel = nmesa->fifo.channel; + notifier->handle = handle; + notifier->count = count; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, + notifier, sizeof(*notifier)); + if (ret) { + MESSAGE("Failed to create notifier 0x%08x: %d\n", handle, ret); FREE(notifier); return NULL; } - if (!nouveauCreateDmaObject(nmesa, handle, notifier->mem->offset, - notifier->mem->size, - 0 /* NV_DMA_TARGET_FB */, - 0 /* NV_DMA_ACCESS_RW */)) { - nouveau_mem_free(ctx, notifier->mem); - FREE(notifier); - return NULL; - } - - notifier->handle = handle; return notifier; } void -nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) +nouveau_notifier_destroy(GLcontext *ctx, + struct drm_nouveau_notifierobj_alloc *notifier) { - /*XXX: free DMA object.. */ - nouveau_mem_free(ctx, notifier->mem); + /*XXX: free notifier object.. */ FREE(notifier); } void -nouveau_notifier_reset(nouveau_notifier *notifier) +nouveau_notifier_reset(GLcontext *ctx, + struct drm_nouveau_notifierobj_alloc *notifier, + GLuint id) { - volatile GLuint *n = notifier->mem->map; + NOTIFIER(n); + +#ifdef NOUVEAU_RING_DEBUG + return; +#endif n[NV_NOTIFY_TIME_0 /4] = 0x00000000; n[NV_NOTIFY_TIME_1 /4] = 0x00000000; @@ -60,17 +93,42 @@ nouveau_notifier_reset(nouveau_notifier *notifier) NV_NOTIFY_STATE_STATUS_SHIFT); } +GLuint +nouveau_notifier_status(GLcontext *ctx, + struct drm_nouveau_notifierobj_alloc *notifier, + GLuint id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +GLuint +nouveau_notifier_return_val(GLcontext *ctx, + struct drm_nouveau_notifierobj_alloc *notifier, + GLuint id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + GLboolean -nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, - GLuint timeout) +nouveau_notifier_wait_status(GLcontext *ctx, + struct drm_nouveau_notifierobj_alloc *notifier, + GLuint id, GLuint status, GLuint timeout) { - volatile GLuint *n = notifier->mem->map; + NOTIFIER(n); unsigned int time = 0; +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + while (time <= timeout) { if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { MESSAGE("Notifier returned error: 0x%04x\n", - n[NV_NOTIFY_STATE] & + n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK); return GL_FALSE; } @@ -90,13 +148,14 @@ nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, } void -nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, - GLuint subc) +nouveau_notifier_wait_nop(GLcontext *ctx, + struct drm_nouveau_notifierobj_alloc *notifier, + GLuint subc) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + NOTIFIER(n); GLboolean ret; - nouveau_notifier_reset(notifier); + nouveau_notifier_reset(ctx, notifier, 0); BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); @@ -104,7 +163,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, OUT_RING (0); FIRE_RING(); - ret = nouveau_notifier_wait_status(notifier, + ret = nouveau_notifier_wait_status(ctx, notifier, 0, NV_NOTIFY_STATE_STATUS_COMPLETED, 0 /* no timeout */); if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); @@ -114,7 +173,11 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1); if (!nmesa->syncNotifier) { MESSAGE("Failed to create channel sync notifier\n"); return GL_FALSE;