From: Ben Skeggs Date: Tue, 26 Dec 2006 10:10:38 +0000 (+1100) Subject: nouveau: Wait on notifier to check for completion of previous commands. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0b2b2de6cff23bc224f5471cc8d0812661a0d363;p=mesa.git nouveau: Wait on notifier to check for completion of previous commands. We can't wait on NV_PGRAPH_STATUS. We don't have the regs mapped, and there's no guarantee that we'll catch PGRAPH idle when multiple channels are active. --- diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 7aca31d0d3e..d68f4e77e73 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -222,7 +222,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; } - nouveauSyncInitFuncs(ctx); + if (!nouveauSyncInitFuncs(ctx)) + return GL_FALSE; nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 5c2b2c75523..7af9f1e3c2f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -35,6 +35,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" #include "nouveau_fifo.h" #include "nouveau_lock.h" +#include "nouveau_object.h" +#include "nouveau_sync.h" #define RING_SKIPS 8 @@ -68,45 +70,18 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) } /* - * Wait for the card to be idle + * Wait for the channel to be idle */ void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) { - int i,status; - + /* Wait for FIFO idle */ FIRE_RING(); while(RING_AHEAD()>0); - /* We can't wait on PGRAPH going idle.. - * 1) We don't have the regs mapped - * 2) PGRAPH may not go idle with multiple channels active - * Look into replacing this with a NOTIFY/NOP + wait notifier sequence. + /* Wait on notifier to indicate all commands in the channel have + * been completed. */ -#if 0 - for(i=0;i<1000000;i++) /* 1 second */ - { - switch(nmesa->screen->card->type) - { - case NV_03: - status=NV_READ(NV03_STATUS); - break; - case NV_04: - case NV_05: - case NV_10: - case NV_20: - case NV_30: - case NV_40: - case NV_44: - case NV_50: - default: - status=NV_READ(NV04_STATUS); - break; - } - if (status) - return; - DO_USLEEP(1); - } -#endif + nouveau_notifier_wait_nop(nmesa->glCtx, nmesa->syncNotifier, NvSub3D); } void nouveauWaitForIdle(nouveauContextPtr nmesa) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 698f778c4bd..5c1c030913f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -106,10 +106,22 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, if (ret) MESSAGE("wait on notifier failed\n"); } -void nouveauSyncInitFuncs(GLcontext *ctx) +GLboolean nouveauSyncInitFuncs(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); + if (!nmesa->syncNotifier) { + MESSAGE("Failed to create channel sync notifier\n"); + return GL_FALSE; + } + + /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D + * object classes + */ + BEGIN_RING_CACHE(NvSub3D, 0x180, 1); + OUT_RING_CACHE (NvSyncNotify); + + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index b20c2565ca7..d9e3d4b80c1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -32,5 +32,5 @@ extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, extern void nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *, GLuint subc); -extern void nouveauSyncInitFuncs(GLcontext *ctx); +extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx); #endif