raedon/r200/r300: mega-FBO commits.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_ioctl.c
index 45d750dbf42912affeebdd9288a75b1f71cfa5ac..f18aa1a4dae112f3d96a5ed8a0bc2b246491fdc1 100644 (file)
@@ -37,14 +37,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <sched.h>
 #include <errno.h> 
 
+#include "main/attrib.h"
+#include "main/enable.h"
+#include "main/blend.h"
+#include "main/bufferobj.h"
+#include "main/buffers.h"
+#include "main/depth.h"
+#include "main/shaders.h"
+#include "main/texstate.h"
+#include "main/varray.h"
+#include "glapi/dispatch.h"
+#include "swrast/swrast.h"
+#include "main/stencil.h"
+#include "main/matrix.h"
+
 #include "main/glheader.h"
 #include "main/imports.h"
 #include "main/simple_list.h"
 #include "swrast/swrast.h"
 
 #include "radeon_context.h"
-#include "common_cmdbuf.h"
-#include "radeon_cs.h"
+#include "radeon_common.h"
 #include "radeon_state.h"
 #include "radeon_ioctl.h"
 #include "radeon_tcl.h"
@@ -59,60 +72,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define RADEON_TIMEOUT             512
 #define RADEON_IDLE_RETRY           16
 
-#define DEBUG_CMDBUF         1
-
-static void radeonSaveHwState( r100ContextPtr rmesa )
-{
-   struct radeon_state_atom *atom;
-   char * dest = rmesa->backup_store.cmd_buf;
-
-   if (RADEON_DEBUG & DEBUG_STATE)
-      fprintf(stderr, "%s\n", __FUNCTION__);
-   
-   rmesa->backup_store.cmd_used = 0;
-
-   foreach( atom, &rmesa->hw.atomlist ) {
-      if ( atom->check( rmesa->radeon.glCtx, 0 ) ) {
-        int size = atom->cmd_size * 4;
-        memcpy( dest, atom->cmd, size);
-        dest += size;
-        rmesa->backup_store.cmd_used += size;
-        if (RADEON_DEBUG & DEBUG_STATE)
-           radeon_print_state_atom( atom );
-      }
-   }
-
-   assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ );
-   if (RADEON_DEBUG & DEBUG_STATE)
-      fprintf(stderr, "Returning to radeonEmitState\n");
-}
-
-/* At this point we were in FlushCmdBufLocked but we had lost our context, so
- * we need to unwire our current cmdbuf, hook the one with the saved state in
- * it, flush it, and then put the current one back.  This is so commands at the
- * start of a cmdbuf can rely on the state being kept from the previous one.
- */
-static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa )
-{
-   GLuint nr_released_bufs;
-   struct radeon_store saved_store;
-
-   if (rmesa->backup_store.cmd_used == 0)
-      return;
-
-   if (RADEON_DEBUG & DEBUG_STATE)
-      fprintf(stderr, "Emitting backup state on lost context\n");
-
-   rmesa->radeon.lost_context = GL_FALSE;
-
-   nr_released_bufs = rmesa->radeon.dma.nr_released_bufs;
-   saved_store = rmesa->store;
-   rmesa->radeon.dma.nr_released_bufs = 0;
-   rmesa->store = rmesa->backup_store;
-   rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ );
-   rmesa->radeon.dma.nr_released_bufs = nr_released_bufs;
-   rmesa->store = saved_store;
-}
 
 /* =============================================================
  * Kernel command buffer handling
@@ -125,107 +84,33 @@ void radeonSetUpAtomList( r100ContextPtr rmesa )
 {
    int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits;
 
-   make_empty_list(&rmesa->hw.atomlist);
-   rmesa->hw.atomlist.name = "atom-list";
+   make_empty_list(&rmesa->radeon.hw.atomlist);
+   rmesa->radeon.hw.atomlist.name = "atom-list";
 
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
    for (i = 0; i < mtu; ++i) {
-       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]);
-       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]);
-       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.cube[i]);
+       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
+       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
+       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
    }
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
    for (i = 0; i < 3 + mtu; ++i)
-      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]);
+      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
    for (i = 0; i < 8; ++i)
-      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]);
+      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
    for (i = 0; i < 6; ++i)
-      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog);
-   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt);
-}
-
-static INLINE void radeonEmitAtoms(r100ContextPtr r100, GLboolean dirty)
-{
-   BATCH_LOCALS(&r100->radeon);
-   struct radeon_state_atom *atom;
-   int dwords;
-
-   /* Emit actual atoms */
-   foreach(atom, &r100->hw.atomlist) {
-     if ((atom->dirty || r100->hw.all_dirty) == dirty) {
-       dwords = (*atom->check) (r100->radeon.glCtx, atom);
-       if (dwords) {
-         if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
-            radeon_print_state_atom(atom);
-         }
-        if (atom->emit) {
-          (*atom->emit)(r100->radeon.glCtx, atom);
-        } else {
-          BEGIN_BATCH_NO_AUTOSTATE(dwords);
-          OUT_BATCH_TABLE(atom->cmd, dwords);
-          END_BATCH();
-        }
-        atom->dirty = GL_FALSE;
-       } else {
-         if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
-            fprintf(stderr, "  skip state %s\n",
-                    atom->name);
-         }
-       }
-     }
-   }
-   
-   COMMIT_BATCH();
-}
-
-void radeonEmitState( r100ContextPtr rmesa )
-{
-   if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
-      fprintf(stderr, "%s\n", __FUNCTION__);
-
-   if (rmesa->save_on_next_emit) {
-      radeonSaveHwState(rmesa);
-      rmesa->save_on_next_emit = GL_FALSE;
-   }
-
-   /* this code used to return here but now it emits zbs */
-
-   /* To avoid going across the entire set of states multiple times, just check
-    * for enough space for the case of emitting all state, and inline the
-    * radeonAllocCmdBuf code here without all the checks.
-    */
-   rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->hw.max_state_size, __FUNCTION__);
-
-   /* We always always emit zbs, this is due to a bug found by keithw in
-      the hardware and rediscovered after Erics changes by me.
-      if you ever touch this code make sure you emit zbs otherwise
-      you get tcl lockups on at least M7/7500 class of chips - airlied */
-   rmesa->hw.zbs.dirty=1;
-
-   if (!rmesa->radeon.cmdbuf.cs->cdw) {
-     if (RADEON_DEBUG & DEBUG_STATE)
-       fprintf(stderr, "Begin reemit state\n");
-     
-     radeonEmitAtoms(rmesa, GL_FALSE);
-   }
-
-   if (RADEON_DEBUG & DEBUG_STATE)
-     fprintf(stderr, "Begin dirty state\n");
-
-   radeonEmitAtoms(rmesa, GL_TRUE);
-   rmesa->hw.is_dirty = GL_FALSE;
-   rmesa->hw.all_dirty = GL_FALSE;
-
+      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
+   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
 }
 
 /* Fire a section of the retained (indexed_verts) buffer as a regular
@@ -240,18 +125,31 @@ extern void radeonEmitVbufPrim( r100ContextPtr rmesa,
 
    assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
    
-   radeonEmitState( rmesa );
+   radeonEmitState(&rmesa->radeon);
 
 #if RADEON_OLD_PACKETS
    BEGIN_BATCH(8);
    OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
-   OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
+   if (!rmesa->radeon.radeonScreen->kernel_mm) {
+     OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
+   } else {
+     OUT_BATCH(rmesa->ioctl.vertex_offset);
+   }
+    
    OUT_BATCH(vertex_nr);
    OUT_BATCH(vertex_format);
    OUT_BATCH(primitive |  RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
             RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
             RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
             (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
+
+   if (rmesa->radeon.radeonScreen->kernel_mm) {
+     radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
+                          rmesa->ioctl.bo,
+                          RADEON_GEM_DOMAIN_GTT,
+                          0, 0);
+   }
+   
    END_BATCH();
    
 #else   
@@ -284,7 +182,11 @@ void radeonFlushElts( GLcontext *ctx )
 
    nr = rmesa->tcl.elt_used;
 
-   rmesa->radeon.cmdbuf.cs->cdw += dwords;
+#if RADEON_OLD_PACKETS
+   if (rmesa->radeon.radeonScreen->kernel_mm) {
+     dwords -= 2;
+   }
+#endif
 
 #if RADEON_OLD_PACKETS
    cmd[1] |= (dwords + 3) << 16;
@@ -294,7 +196,18 @@ void radeonFlushElts( GLcontext *ctx )
    cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
 #endif
 
+   rmesa->radeon.cmdbuf.cs->cdw += dwords;
    rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
+
+#if RADEON_OLD_PACKETS
+   if (rmesa->radeon.radeonScreen->kernel_mm) {
+      radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
+                           rmesa->ioctl.bo,
+                           RADEON_GEM_DOMAIN_GTT,
+                           0, 0);
+   }
+#endif
+
    END_BATCH();
 
    if (RADEON_DEBUG & DEBUG_SYNC) {
@@ -318,7 +231,7 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
 
    assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
    
-   radeonEmitState( rmesa );
+   radeonEmitState(&rmesa->radeon);
    
    rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
 
@@ -328,7 +241,11 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
 #if RADEON_OLD_PACKETS
    BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
    OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
-   OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
+   if (!rmesa->radeon.radeonScreen->kernel_mm) {
+     OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
+   } else {
+     OUT_BATCH(rmesa->ioctl.vertex_offset);
+   }
    OUT_BATCH(0xffff);
    OUT_BATCH(vertex_format);
    OUT_BATCH(primitive | 
@@ -502,72 +419,20 @@ void radeonEmitAOS( r100ContextPtr rmesa,
  */
 #define RADEON_MAX_CLEARS      256
 
-static void radeonClear( GLcontext *ctx, GLbitfield mask )
+static void radeonUserClear(GLcontext *ctx, GLuint mask)
 {
-   r100ContextPtr rmesa = R100_CONTEXT(ctx);
+   radeon_clear_tris(ctx, mask);
+}
+
+static void radeonKernelClear(GLcontext *ctx, GLuint flags)
+{
+     r100ContextPtr rmesa = R100_CONTEXT(ctx);
    __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
    drm_radeon_sarea_t *sarea = rmesa->radeon.sarea;
    uint32_t clear;
-   GLuint flags = 0;
-   GLuint color_mask = 0;
    GLint ret, i;
    GLint cx, cy, cw, ch;
 
-   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
-      fprintf( stderr, "radeonClear\n");
-   }
-
-   {
-      LOCK_HARDWARE( &rmesa->radeon );
-      UNLOCK_HARDWARE( &rmesa->radeon );
-      if ( dPriv->numClipRects == 0 ) 
-        return;
-   }
-   
-   radeonFlush( ctx ); 
-
-   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
-      flags |= RADEON_FRONT;
-      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
-      mask &= ~BUFFER_BIT_FRONT_LEFT;
-   }
-
-   if ( mask & BUFFER_BIT_BACK_LEFT ) {
-      flags |= RADEON_BACK;
-      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
-      mask &= ~BUFFER_BIT_BACK_LEFT;
-   }
-
-   if ( mask & BUFFER_BIT_DEPTH ) {
-      flags |= RADEON_DEPTH;
-      mask &= ~BUFFER_BIT_DEPTH;
-   }
-
-   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) {
-      flags |= RADEON_STENCIL;
-      mask &= ~BUFFER_BIT_STENCIL;
-   }
-
-   if ( mask ) {
-      if (RADEON_DEBUG & DEBUG_FALLBACKS)
-        fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
-      _swrast_Clear( ctx, mask );
-   }
-
-   if ( !flags ) 
-      return;
-
-   if (rmesa->using_hyperz) {
-      flags |= RADEON_USE_COMP_ZBUF;
-/*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) 
-         flags |= RADEON_USE_HIERZ; */
-      if (!(rmesa->radeon.state.stencil.hwBuffer) ||
-        ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
-           ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
-         flags |= RADEON_CLEAR_FASTZ;
-      }
-   }
-
    LOCK_HARDWARE( &rmesa->radeon );
 
    /* compute region after locking: */
@@ -677,36 +542,78 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
         exit( 1 );
       }
    }
-
    UNLOCK_HARDWARE( &rmesa->radeon );
-   rmesa->hw.all_dirty = GL_TRUE;
 }
 
-void radeonFlush( GLcontext *ctx )
+static void radeonClear( GLcontext *ctx, GLbitfield mask )
 {
-   r100ContextPtr rmesa = R100_CONTEXT( ctx );
-
-   if (RADEON_DEBUG & DEBUG_IOCTL)
-      fprintf(stderr, "%s\n", __FUNCTION__);
+   r100ContextPtr rmesa = R100_CONTEXT(ctx);
+   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
+   GLuint flags = 0;
+   GLuint color_mask = 0;
+   GLuint orig_mask = mask;
 
-   if (rmesa->radeon.dma.flush)
-      rmesa->radeon.dma.flush( ctx );
+   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
+      fprintf( stderr, "radeonClear\n");
+   }
 
-   radeonEmitState( rmesa );
+   {
+      LOCK_HARDWARE( &rmesa->radeon );
+      UNLOCK_HARDWARE( &rmesa->radeon );
+      if ( dPriv->numClipRects == 0 ) 
+        return;
+   }
    
-   if (rmesa->radeon.cmdbuf.cs->cdw)
-      rcommonFlushCmdBuf( &rmesa->radeon, __FUNCTION__ );
-}
+   radeon_firevertices(&rmesa->radeon); 
 
-/* Make sure all commands have been sent to the hardware and have
- * completed processing.
- */
-void radeonFinish( GLcontext *ctx )
-{
-   radeonFlush( ctx );
-   radeon_common_finish(ctx);
-}
+   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
+      flags |= RADEON_FRONT;
+      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
+      mask &= ~BUFFER_BIT_FRONT_LEFT;
+   }
+
+   if ( mask & BUFFER_BIT_BACK_LEFT ) {
+      flags |= RADEON_BACK;
+      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
+      mask &= ~BUFFER_BIT_BACK_LEFT;
+   }
+
+   if ( mask & BUFFER_BIT_DEPTH ) {
+      flags |= RADEON_DEPTH;
+      mask &= ~BUFFER_BIT_DEPTH;
+   }
+
+   if ( (mask & BUFFER_BIT_STENCIL) ) {
+      flags |= RADEON_STENCIL;
+      mask &= ~BUFFER_BIT_STENCIL;
+   }
+
+   if ( mask ) {
+      if (RADEON_DEBUG & DEBUG_FALLBACKS)
+        fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
+      _swrast_Clear( ctx, mask );
+   }
+
+   if ( !flags ) 
+      return;
 
+   if (rmesa->using_hyperz) {
+      flags |= RADEON_USE_COMP_ZBUF;
+/*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) 
+         flags |= RADEON_USE_HIERZ; */
+      if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
+           ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
+         flags |= RADEON_CLEAR_FASTZ;
+      }
+   }
+
+   if (rmesa->radeon.radeonScreen->kernel_mm)
+     radeonUserClear(ctx, orig_mask);
+   else {
+      radeonKernelClear(ctx, flags);
+      rmesa->radeon.hw.all_dirty = GL_TRUE;
+   }
+}
 
 void radeonInitIoctlFuncs( GLcontext *ctx )
 {