More vblank cleanups.
[mesa.git] / src / mesa / drivers / dri / r200 / r200_cmdbuf.c
index e3829f9a9575baff8d4a9c9b5b9774d7a9593b84..c1d51e87001621c10e4649db8833c94f462c774b 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c,v 1.1 2002/10/30 12:51:51 alanh Exp $ */
 /*
 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 
@@ -88,33 +87,75 @@ void r200SetUpAtomList( r200ContextPtr rmesa )
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.fog );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tam );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tf );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.atf );
    for (i = 0; i < mtu; ++i)
        insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tex[i] );
    for (i = 0; i < mtu; ++i)
        insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.cube[i] );
+   for (i = 0; i < 6; ++i)
+       insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pix[i] );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.afs[0] );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.afs[1] );
+   for (i = 0; i < 8; ++i)
+       insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lit[i] );
    for (i = 0; i < 3 + mtu; ++i)
        insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mat[i] );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.eye );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.glt );
    for (i = 0; i < 2; ++i)
       insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mtl[i] );
-   for (i = 0; i < 8; ++i)
-       insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lit[i] );
    for (i = 0; i < 6; ++i)
        insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ucp[i] );
-   for (i = 0; i < 6; ++i)
-       insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pix[i] );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.spr );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ptp );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.prf );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pvs );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[0] );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[1] );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpi[0] );
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpi[1] );
+}
+
+static void r200SaveHwState( r200ContextPtr rmesa )
+{
+   struct r200_state_atom *atom;
+   char * dest = rmesa->backup_store.cmd_buf;
+
+   if (R200_DEBUG & DEBUG_STATE)
+      fprintf(stderr, "%s\n", __FUNCTION__);
+
+   rmesa->backup_store.cmd_used = 0;
+
+   foreach( atom, &rmesa->hw.atomlist ) {
+      if ( atom->check( rmesa->glCtx, atom->idx ) ) {
+        int size = atom->cmd_size * 4;
+        memcpy( dest, atom->cmd, size);
+        dest += size;
+        rmesa->backup_store.cmd_used += size;
+        if (R200_DEBUG & DEBUG_STATE)
+           print_state_atom( atom );
+      }
+   }
+
+   assert( rmesa->backup_store.cmd_used <= R200_CMD_BUF_SZ );
+   if (R200_DEBUG & DEBUG_STATE)
+      fprintf(stderr, "Returning to r200EmitState\n");
 }
 
 void r200EmitState( r200ContextPtr rmesa )
 {
    char *dest;
-   int i, mtu;
+   int mtu;
    struct r200_state_atom *atom;
 
    if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
       fprintf(stderr, "%s\n", __FUNCTION__);
 
+   if (rmesa->save_on_next_emit) {
+      r200SaveHwState(rmesa);
+      rmesa->save_on_next_emit = GL_FALSE;
+   }
+
    if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty)
       return;
 
@@ -124,9 +165,11 @@ void r200EmitState( r200ContextPtr rmesa )
     * for enough space for the case of emitting all state, and inline the
     * r200AllocCmdBuf code here without all the checks.
     */
-   dest = rmesa->store.cmd_buf + rmesa->store.cmd_used;
    r200EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size );
 
+   /* we need to calculate dest after EnsureCmdBufSpace
+      as we may flush the buffer - airlied */
+   dest = rmesa->store.cmd_buf + rmesa->store.cmd_used;
    if (R200_DEBUG & DEBUG_STATE) {
       foreach( atom, &rmesa->hw.atomlist ) {
         if ( atom->dirty || rmesa->hw.all_dirty ) {
@@ -161,9 +204,9 @@ void r200EmitState( r200ContextPtr rmesa )
 /* Fire a section of the retained (indexed_verts) buffer as a regular
  * primtive.  
  */
-extern void r200EmitVbufPrim( r200ContextPtr rmesa,
-                               GLuint primitive,
-                               GLuint vertex_nr )
+void r200EmitVbufPrim( r200ContextPtr rmesa,
+                       GLuint primitive,
+                       GLuint vertex_nr )
 {
    drm_radeon_cmd_header_t *cmd;
 
@@ -197,7 +240,7 @@ void r200FlushElts( r200ContextPtr rmesa )
       fprintf(stderr, "%s\n", __FUNCTION__);
 
    assert( rmesa->dma.flush == r200FlushElts );
-   rmesa->dma.flush = 0;
+   rmesa->dma.flush = NULL;
 
    /* Cope with odd number of elts:
     */
@@ -373,15 +416,13 @@ void r200EmitBlit( r200ContextPtr rmesa,
 
 void r200EmitWait( r200ContextPtr rmesa, GLuint flags )
 {
-   if (rmesa->dri.drmMinor >= 6) {
-      drm_radeon_cmd_header_t *cmd;
-
-      assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
-      
-      cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 1 * sizeof(int),
-                                                  __FUNCTION__ );
-      cmd[0].i = 0;
-      cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
-      cmd[0].wait.flags = flags;
-   }
+   drm_radeon_cmd_header_t *cmd;
+
+   assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
+
+   cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 1 * sizeof(int),
+                                          __FUNCTION__ );
+   cmd[0].i = 0;
+   cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
+   cmd[0].wait.flags = flags;
 }