Refactor "class" texture environments to be implemented in terms of
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_ioctl.c
index a388720aba11e4bc287623b453e5c45ef297c99e..7b27d3f76684f51348d57fc376395be0cb2f124a 100644 (file)
@@ -34,8 +34,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Gareth Hughes <gareth@valinux.com>
  *   Keith Whitwell <keith@tungstengraphics.com>
  */
+
 #include <sched.h>
-#include <errno.h>
+#include <errno.h> 
 
 #include "glheader.h"
 #include "imports.h"
@@ -79,30 +80,21 @@ static void radeon_emit_state_list( radeonContextPtr rmesa,
 {
    struct radeon_state_atom *state, *tmp;
    char *dest;
-
-   /* From Felix Kuhling: similar to some other lockups, glaxium will
-    * lock with what we believe to be a normal command stream, but
-    * sprinkling some magic waits arounds allows it to run
-    * uninterrupted.  This has a slight effect on q3 framerates, but
-    * it might now be possible to remove the zbs hack, below.
-    *
-    * Felix reports that this can be narrowed down to just
-    * tcl,tex0,tex1 state, but that's pretty much every statechange,
-    * so let's just put the wait in always (unless Felix wants to
-    * narrow it down further...)
+   int i, size, texunits;
+
+   /* It appears that some permutations of state atoms lock up the
+    * chip.  Therefore we make sure that state atoms are emitted in a
+    * fixed order. First mark all dirty state atoms and then go
+    * through all state atoms in a well defined order and emit only
+    * the marked ones.
+    * FIXME: This requires knowledge of which state atoms exist.
+    * FIXME: Is the zbs hack below still needed?
     */
-   if (1) {
-      drmRadeonCmdHeader *cmd;
-      cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd), 
-                                                    __FUNCTION__ );
-      cmd->wait.cmd_type = RADEON_CMD_WAIT;
-      cmd->wait.flags = RADEON_WAIT_3D;
-   }
-
+   size = 0;
    foreach_s( state, tmp, list ) {
       if (state->check( rmesa->glCtx )) {
-        dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
-        memcpy( dest, state->cmd, state->cmd_size * 4);
+        size += state->cmd_size;
+        state->dirty = GL_TRUE;
         move_to_head( &(rmesa->hw.clean), state );
         if (RADEON_DEBUG & DEBUG_STATE) 
            print_state_atom( state );
@@ -110,6 +102,47 @@ static void radeon_emit_state_list( radeonContextPtr rmesa,
       else if (RADEON_DEBUG & DEBUG_STATE)
         fprintf(stderr, "skip state %s\n", state->name);
    }
+   /* short cut */
+   if (!size)
+       return;
+
+   dest = radeonAllocCmdBuf( rmesa, size * 4, __FUNCTION__);
+   texunits = rmesa->glCtx->Const.MaxTextureUnits;
+
+#define EMIT_ATOM(ATOM) \
+do { \
+   if (rmesa->hw.ATOM.dirty) { \
+      rmesa->hw.ATOM.dirty = GL_FALSE; \
+      memcpy( dest, rmesa->hw.ATOM.cmd, rmesa->hw.ATOM.cmd_size * 4); \
+      dest += rmesa->hw.ATOM.cmd_size * 4; \
+   } \
+} while (0)
+
+   EMIT_ATOM (ctx);
+   EMIT_ATOM (set);
+   EMIT_ATOM (lin);
+   EMIT_ATOM (msk);
+   EMIT_ATOM (vpt);
+   EMIT_ATOM (tcl);
+   EMIT_ATOM (msc);
+   for (i = 0; i < texunits; ++i) {
+       EMIT_ATOM (tex[i]);
+       EMIT_ATOM (txr[i]);
+   }
+   EMIT_ATOM (zbs);
+   EMIT_ATOM (mtl);
+   for (i = 0; i < 3 + texunits; ++i)
+       EMIT_ATOM (mat[i]);
+   for (i = 0; i < 8; ++i)
+       EMIT_ATOM (lit[i]);
+   for (i = 0; i < 6; ++i)
+       EMIT_ATOM (ucp[i]);
+   EMIT_ATOM (eye);
+   EMIT_ATOM (grd);
+   EMIT_ATOM (fog);
+   EMIT_ATOM (glt);
+
+#undef EMIT_ATOM
 }
 
 
@@ -162,7 +195,6 @@ extern void radeonEmitVbufPrim( radeonContextPtr rmesa,
    drmRadeonCmdHeader *cmd;
 
 
-   assert(rmesa->dri.drmMinor >= 3); 
    assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
    
    radeonEmitState( rmesa );
@@ -254,7 +286,6 @@ GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
    if (RADEON_DEBUG & DEBUG_IOCTL)
       fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr);
 
-   assert(rmesa->dri.drmMinor >= 3); 
    assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
    
    radeonEmitState( rmesa );
@@ -317,7 +348,6 @@ void radeonEmitVertexAOS( radeonContextPtr rmesa,
    rmesa->ioctl.vertex_offset = offset;
 #else
    drmRadeonCmdHeader *cmd;
-   assert(rmesa->dri.drmMinor >= 3); 
 
    if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
       fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
@@ -356,7 +386,6 @@ void radeonEmitAOS( radeonContextPtr rmesa,
    if (RADEON_DEBUG & DEBUG_IOCTL)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
-   assert(rmesa->dri.drmMinor >= 3); 
 
    cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sz * sizeof(int),
                                                  __FUNCTION__ );
@@ -531,8 +560,6 @@ void radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller )
    int ret;
 
              
-   assert (rmesa->dri.drmMinor >= 3);
-
    LOCK_HARDWARE( rmesa );
 
    ret = radeonFlushCmdBufLocked( rmesa, caller );
@@ -691,9 +718,6 @@ void radeonAllocDmaRegion( radeonContextPtr rmesa,
    rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
    rmesa->dma.current.start = 
       rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;  
-
-   if ( rmesa->dri.drmMinor < 3 ) 
-      radeonRefillCurrentDmaRegion( rmesa );
 }
 
 void radeonAllocDmaRegionVerts( radeonContextPtr rmesa, 
@@ -719,7 +743,7 @@ static CARD32 radeonGetLastFrame (radeonContextPtr rmesa)
       drmRadeonGetParam gp;
 
       gp.param = RADEON_PARAM_LAST_FRAME;
-      gp.value = &frame;
+      gp.value = (int *)&frame;
       ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
                                 &gp, sizeof(gp) );
    } 
@@ -811,7 +835,7 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
    radeonContextPtr rmesa;
    GLint nbox, i, ret;
    GLboolean   missed_target;
-   uint64_t     ust;
+   uint64_t ust;
 
    assert(dPriv);
    assert(dPriv->driContextPriv);
@@ -931,7 +955,8 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
    }
 
    RADEON_STATECHANGE( rmesa, ctx );
-   rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset;
+   rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
+                                          + rmesa->radeonScreen->fbLocation;
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
 }
 
@@ -1012,7 +1037,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
        drmRadeonGetParam gp;
 
        gp.param = RADEON_PARAM_LAST_CLEAR;
-       gp.value = &clear;
+       gp.value = (int *)&clear;
        ret = drmCommandWriteRead( rmesa->dri.fd,
                                   DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
       } else
@@ -1154,13 +1179,11 @@ void radeonFlush( GLcontext *ctx )
    if (rmesa->dma.flush)
       rmesa->dma.flush( rmesa );
 
-   if (rmesa->dri.drmMinor >= 3) {
-      if (!is_empty_list(&rmesa->hw.dirty)) 
-        radeonEmitState( rmesa );
+   if (!is_empty_list(&rmesa->hw.dirty)) 
+      radeonEmitState( rmesa );
    
-      if (rmesa->store.cmd_used)
-        radeonFlushCmdBuf( rmesa, __FUNCTION__ );
-   }
+   if (rmesa->store.cmd_used)
+      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
 }
 
 /* Make sure all commands have been sent to the hardware and have