diff options
author | Ben Skeggs <darktama@iinet.net.au> | 2006-12-26 21:10:38 +1100 |
---|---|---|
committer | Ben Skeggs <darktama@iinet.net.au> | 2006-12-26 21:36:15 +1100 |
commit | 0b2b2de6cff23bc224f5471cc8d0812661a0d363 (patch) | |
tree | 96894d5975b0df79c07a70347cc7feba4ddf4272 | |
parent | c0a63d8e5e33b7fe3057e32f04c22969ac2adc1d (diff) |
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.
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 39 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_sync.c | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_sync.h | 2 |
4 files changed, 23 insertions, 35 deletions
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 7aca31d0d3..d68f4e77e7 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 5c2b2c7552..7af9f1e3c2 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 698f778c4b..5c1c030913 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 b20c2565ca..d9e3d4b80c 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 |