summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <darktama@iinet.net.au>2006-12-26 21:10:38 +1100
committerBen Skeggs <darktama@iinet.net.au>2006-12-26 21:36:15 +1100
commit0b2b2de6cff23bc224f5471cc8d0812661a0d363 (patch)
tree96894d5975b0df79c07a70347cc7feba4ddf4272
parentc0a63d8e5e33b7fe3057e32f04c22969ac2adc1d (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.c3
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fifo.c39
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_sync.c14
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_sync.h2
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