nouveau: Wait on notifier to check for completion of previous commands.
authorBen Skeggs <darktama@iinet.net.au>
Tue, 26 Dec 2006 10:10:38 +0000 (21:10 +1100)
committerBen Skeggs <darktama@iinet.net.au>
Tue, 26 Dec 2006 10:36:15 +0000 (21:36 +1100)
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.

src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_fifo.c
src/mesa/drivers/dri/nouveau/nouveau_sync.c
src/mesa/drivers/dri/nouveau/nouveau_sync.h

index 7aca31d0d3e5608f084deef10187d61f831bca0a..d68f4e77e73dfe9a72fedcdbc3670560de3433c1 100644 (file)
@@ -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);
 
index 5c2b2c755230414042fe822fb07e7462684d2aa2..7af9f1e3c2fd8d86e5640d8534841398844a4bd6 100644 (file)
@@ -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)
index 698f778c4bd68fd7a4e0daf916290b12c793ead8..5c1c030913f01d8d9d82bdda26dfdbc29c90386d 100644 (file)
@@ -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;
 }
 
index b20c2565ca70ba0fd42515aedbee832490fc3daa..d9e3d4b80c1213187f3f14554c68f5949f21e3a0 100644 (file)
@@ -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