radeon_ioctl.c revision 99ef0a03292e7dc6aa2465aaaa620f394d2c286b
15df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.11 2003/01/29 22:04:59 dawes Exp $ */
25df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/**************************************************************************
35df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
45df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulCopyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
55df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul                     VA Linux Systems Inc., Fremont, California.
65df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
75df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulAll Rights Reserved.
85df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
95df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulPermission is hereby granted, free of charge, to any person obtaining
105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paula copy of this software and associated documentation files (the
115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul"Software"), to deal in the Software without restriction, including
125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulwithout limitation the rights to use, copy, modify, merge, publish,
135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Pauldistribute, sublicense, and/or sell copies of the Software, and to
145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulpermit persons to whom the Software is furnished to do so, subject to
155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulthe following conditions:
165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulThe above copyright notice and this permission notice (including the
185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulnext paragraph) shall be included in all copies or substantial
195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulportions of the Software.
205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulIN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul**************************************************************************/
305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/*
325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Authors:
335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul *   Kevin E. Martin <martin@valinux.com>
345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul *   Gareth Hughes <gareth@valinux.com>
355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul *   Keith Whitwell <keith@tungstengraphics.com>
365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
37bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl
385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include <sched.h>
39bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl#include <errno.h>
405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "glheader.h"
425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "imports.h"
435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "simple_list.h"
445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "swrast/swrast.h"
455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_context.h"
475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_state.h"
485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_ioctl.h"
495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_tcl.h"
505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_sanity.h"
515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_macros.h"  /* for INREG() */
535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "vblank.h"
555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_TIMEOUT             512
575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_IDLE_RETRY           16
585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForIdle( radeonContextPtr rmesa );
615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* =============================================================
635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Kernel command buffer handling
645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void print_state_atom( struct radeon_state_atom *state )
675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int i;
695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_VERBOSE)
735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for (i = 0 ; i < state->cmd_size ; i++)
745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeon_emit_state_list( radeonContextPtr rmesa,
795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    struct radeon_state_atom *list )
805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   struct radeon_state_atom *state, *tmp;
825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   char *dest;
835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* From Felix Kuhling: similar to some other lockups, glaxium will
855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * lock with what we believe to be a normal command stream, but
865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * sprinkling some magic waits arounds allows it to run
875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * uninterrupted.  This has a slight effect on q3 framerates, but
885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * it might now be possible to remove the zbs hack, below.
895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    *
905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * Felix reports that this can be narrowed down to just
915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * tcl,tex0,tex1 state, but that's pretty much every statechange,
925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * so let's just put the wait in always (unless Felix wants to
935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * narrow it down further...)
945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (1) {
965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      drmRadeonCmdHeader *cmd;
975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd),
985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						     __FUNCTION__ );
995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->wait.cmd_type = RADEON_CMD_WAIT;
1005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->wait.flags = RADEON_WAIT_3D;
1015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
1025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   foreach_s( state, tmp, list ) {
1045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (state->check( rmesa->glCtx )) {
1055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
1065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 memcpy( dest, state->cmd, state->cmd_size * 4);
1075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 move_to_head( &(rmesa->hw.clean), state );
1085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (RADEON_DEBUG & DEBUG_STATE)
1095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    print_state_atom( state );
1105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
1115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else if (RADEON_DEBUG & DEBUG_STATE)
1125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "skip state %s\n", state->name);
1135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
1145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
1155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitState( radeonContextPtr rmesa )
1185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
1195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   struct radeon_state_atom *state, *tmp;
1205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
1225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
1235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Somewhat overkill:
1255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
1265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->lost_context) {
1275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL))
1285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s - lost context\n", __FUNCTION__);
1295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      foreach_s( state, tmp, &(rmesa->hw.clean) )
1315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 move_to_tail(&(rmesa->hw.dirty), state );
1325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->lost_context = 0;
1345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
1355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else if (1) {
1365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      /* This is a darstardly kludge to work around a lockup that I
1375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       * haven't otherwise figured out.
1385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       */
1395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      move_to_tail(&(rmesa->hw.dirty), &(rmesa->hw.zbs) );
1405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
1415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
1435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul     foreach_s( state, tmp, &(rmesa->hw.dirty) ) {
1445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       if (state->is_tcl) {
1455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 move_to_head( &(rmesa->hw.clean), state );
1465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       }
1475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul     }
1485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
1495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeon_emit_state_list( rmesa, &rmesa->hw.dirty );
1515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
1525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Fire a section of the retained (indexed_verts) buffer as a regular
1565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * primtive.
1575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
1585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulextern void radeonEmitVbufPrim( radeonContextPtr rmesa,
1595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint vertex_format,
1605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint primitive,
1615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint vertex_nr )
1625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
1635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonCmdHeader *cmd;
1645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
1675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
1695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
1715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__,
1725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->store.cmd_used/4);
1735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
1755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 6 * sizeof(*cmd),
1765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
1775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
1785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16);
1795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = rmesa->ioctl.vertex_offset;
1805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = vertex_nr;
1815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = vertex_format;
1825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (primitive |
1835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
1845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
1855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
1865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
1875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
1895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n",
1905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
1915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i);
1925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
1935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 4 * sizeof(*cmd),
1945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
1955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
1965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
1975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16);
1985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = vertex_format;
1995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = (primitive |
2005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
2015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_MAOS_ENABLE |
2035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
2045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
2055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
2085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n",
2095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
2105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, cmd[2].i, cmd[3].i);
2115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
2135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlushElts( radeonContextPtr rmesa )
2165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
2175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start);
2185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int dwords;
2195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2;
2215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2;
2235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
2265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
2275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( rmesa->dma.flush == radeonFlushElts );
2295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.flush = 0;
2305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Cope with odd number of elts:
2325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
2335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
2345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
2355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1] |= (dwords - 3) << 16;
2385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
2395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1] |= (dwords - 3) << 16;
2415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
2425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
2445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulGLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
2475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint vertex_format,
2485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint primitive,
2495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint min_nr )
2505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
2515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonCmdHeader *cmd;
2525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLushort *retval;
2535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
2555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr);
2565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
2585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
2605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa,
2635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  24 + min_nr*2,
2645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
2655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
2665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
2675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM;
2685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = rmesa->ioctl.vertex_offset;
2695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = 0xffff;
2705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = vertex_format;
2715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (primitive |
2725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_IND |
2735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
2755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   retval = (GLushort *)(cmd+6);
2775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa,
2795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  16 + min_nr*2,
2805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
2815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
2825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
2835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX;
2845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = vertex_format;
2855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = (primitive |
2865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_IND |
2875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_MAOS_ENABLE |
2895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
2905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   retval = (GLushort *)(cmd+4);
2925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
2955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n",
2965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
2975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, vertex_format, primitive);
2985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(!rmesa->dma.flush);
3005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
3015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.flush = radeonFlushElts;
3025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf;
3045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return retval;
3065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitVertexAOS( radeonContextPtr rmesa,
3115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  GLuint vertex_size,
3125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  GLuint offset )
3135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
3145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_size = vertex_size;
3165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_offset = offset;
3175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
3185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonCmdHeader *cmd;
3195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
3215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
3225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__, vertex_size, offset);
3235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 5 * sizeof(int),
3255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
3265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
3295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16);
3305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = 1;
3315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = vertex_size | (vertex_size << 8);
3325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = offset;
3335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
3345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitAOS( radeonContextPtr rmesa,
3385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    struct radeon_dma_region **component,
3395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    GLuint nr,
3405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    GLuint offset )
3415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
3425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( nr == 1 );
3445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( component[0]->aos_size == component[0]->aos_stride );
3455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_size = component[0]->aos_size;
3465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_offset =
3475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (component[0]->aos_start + offset * component[0]->aos_stride * 4);
3485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
3495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonCmdHeader *cmd;
3505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int sz = 3 + (nr/2 * 3) + (nr & 1) * 2;
3515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int i;
3525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int *tmp;
3535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
3555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
3565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sz * sizeof(int),
3595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
3605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
3625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | ((sz-3) << 16);
3635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = nr;
3645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   tmp = &cmd[0].i;
3655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd += 3;
3665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for (i = 0 ; i < nr ; i++) {
3685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (i & 1) {
3695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[0].i |= ((component[i]->aos_stride << 24) |
3705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		      (component[i]->aos_size << 16));
3715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[2].i = (component[i]->aos_start +
3725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     offset * component[i]->aos_stride * 4);
3735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd += 3;
3745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
3755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else {
3765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[0].i = ((component[i]->aos_stride << 8) |
3775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     (component[i]->aos_size << 0));
3785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[1].i = (component[i]->aos_start +
3795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     offset * component[i]->aos_stride * 4);
3805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
3815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
3825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_VERTS) {
3845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s:\n", __FUNCTION__);
3855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for (i = 0 ; i < sz ; i++)
3865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "   %d: %x\n", i, tmp[i]);
3875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
3885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
3895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* using already shifted color_fmt! */
3925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitBlit( radeonContextPtr rmesa, /* FIXME: which drmMinor is required? */
3935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint color_fmt,
3945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint src_pitch,
3955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint src_offset,
3965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint dst_pitch,
3975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint dst_offset,
3985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLint srcx, GLint srcy,
3995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLint dstx, GLint dsty,
4005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint w, GLuint h )
4015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
4025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonCmdHeader *cmd;
4035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
4055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
4065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
4075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      src_pitch, src_offset, srcx, srcy,
4085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      dst_pitch, dst_offset, dstx, dsty,
4095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      w, h);
4105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (src_pitch & 63) == 0 );
4125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (dst_pitch & 63) == 0 );
4135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (src_offset & 1023) == 0 );
4145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (dst_offset & 1023) == 0 );
4155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( w < (1<<16) );
4165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( h < (1<<16) );
4175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int),
4195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
4205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
4235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
4245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
4255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
4265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_DST_PITCH_OFFSET_CNTL |
4275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_BRUSH_NONE |
4285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       color_fmt |
4295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_SRC_DATATYPE_COLOR |
4305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_ROP3_S |
4315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_DP_SRC_SOURCE_MEMORY |
4325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_CLR_CMP_CNTL_DIS |
4335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_WR_MSK_DIS );
4345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10);
4365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10);
4375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (srcx << 16) | srcy;
4385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[6].i = (dstx << 16) | dsty; /* dst */
4395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[7].i = (w << 16) | h;
4405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
4415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitWait( radeonContextPtr rmesa, GLuint flags )
4445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
4455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dri.drmMinor >= 6) {
4465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      drmRadeonCmdHeader *cmd;
4475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
4495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int),
4515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						   __FUNCTION__ );
4525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].i = 0;
4535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
4545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].wait.flags = flags;
4555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
4575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
4605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    const char * caller )
4615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
4625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret, i;
4635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonCmdBuffer cmd;
4645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL) {
4665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
4675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_VERBOSE)
4695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 )
4705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    fprintf(stderr, "%d: %x\n", i/4,
4715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    *(int *)(&rmesa->store.cmd_buf[i]));
4725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_DMA)
4755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__,
4765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->dma.nr_released_bufs);
4775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_SANITY) {
4805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->state.scissor.enabled)
4815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = radeonSanityCmdBuffer( rmesa,
4825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->state.scissor.numClipRects,
4835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->state.scissor.pClipRects);
4845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else
4855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = radeonSanityCmdBuffer( rmesa,
4865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->numClipRects,
4875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->pClipRects);
4885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (ret) {
4895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "drmSanityCommandWrite: %d\n", ret);
4905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 goto out;
4915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
4925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd.bufsz = rmesa->store.cmd_used;
4965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd.buf = rmesa->store.cmd_buf;
4975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->state.scissor.enabled) {
4995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.nbox = rmesa->state.scissor.numClipRects;
5005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.boxes = (drmClipRect *)rmesa->state.scissor.pClipRects;
5015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } else {
5025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.nbox = rmesa->numClipRects;
5035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.boxes = (drmClipRect *)rmesa->pClipRects;
5045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandWrite( rmesa->dri.fd,
5075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  DRM_RADEON_CMDBUF,
5085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  &cmd, sizeof(cmd) );
5095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret)
5115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "drmCommandWrite: %d\n", ret);
5125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul out:
5145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.primnr = 0;
5155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.statenr = 0;
5165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.cmd_used = 0;
5175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.nr_released_bufs = 0;
5185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->lost_context = 1;
5195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return ret;
5205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Note: does not emit any commands to avoid recursion on
5245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * radeonAllocCmdBuf.
5255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
5265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller )
5275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
5295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
5325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = radeonFlushCmdBufLocked( rmesa, caller );
5345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
5365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret) {
5385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "drmRadeonCmdBuffer: %d (exiting)\n", ret);
5395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(ret);
5405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* =============================================================
5445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Hardware vertex buffer handling
5455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
5465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonRefillCurrentDmaRegion( radeonContextPtr rmesa )
5495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   struct radeon_dma_buffer *dmabuf;
5515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int fd = rmesa->dri.fd;
5525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int index = 0;
5535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int size = 0;
5545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmDMAReq dma;
5555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
5565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
5585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
5595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush) {
5615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
5625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.current.buf)
5655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
5665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.nr_released_bufs > 4)
5685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
5695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.context = rmesa->dri.hwContext;
5715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_count = 0;
5725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_list = NULL;
5735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_sizes = NULL;
5745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.flags = 0;
5755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_count = 1;
5765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_size = RADEON_BUFFER_SIZE;
5775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_list = &index;
5785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_sizes = &size;
5795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.granted_count = 0;
5805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE(rmesa);	/* no need to validate */
5825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmDMA( fd, &dma );
5845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret != 0) {
5865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      /* Free some up this way?
5875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       */
5885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->dma.nr_released_bufs) {
5895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
5905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
5915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_DMA)
5935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "Waiting for buffers\n");
5945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitForIdleLocked( rmesa );
5965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmDMA( fd, &dma );
5975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret != 0 ) {
5995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
6005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "Error: Could not get dma buffer... exiting\n" );
6015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( -1 );
6025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
6035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE(rmesa);
6065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_DMA)
6085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "Allocated buffer %d\n", index);
6095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf = CALLOC_STRUCT( radeon_dma_buffer );
6115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf->buf = &rmesa->radeonScreen->buffers->list[index];
6125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf->refcount = 1;
6135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.buf = dmabuf;
6155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.address = dmabuf->buf->address;
6165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.end = dmabuf->buf->total;
6175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start = 0;
6185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.ptr = 0;
6195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->c_vertexBuffers++;
6215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonReleaseDmaRegion( radeonContextPtr rmesa,
6245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     struct radeon_dma_region *region,
6255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     const char *caller )
6265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
6285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
6295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (!region->buf)
6315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      return;
6325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
6345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
6355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (--region->buf->refcount == 0) {
6375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      drmRadeonCmdHeader *cmd;
6385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
6405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
6415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		 region->buf->buf->idx);
6425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd),
6445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						     __FUNCTION__ );
6455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
6465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->dma.buf_idx = region->buf->buf->idx;
6475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      FREE(region->buf);
6485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.nr_released_bufs++;
6495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf = 0;
6525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->start = 0;
6535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Allocates a region from rmesa->dma.current.  If there isn't enough
6565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * space in current, grab a new buffer (and discard what was left of current)
6575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
6585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonAllocDmaRegion( radeonContextPtr rmesa,
6595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   struct radeon_dma_region *region,
6605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   int bytes,
6615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   int alignment )
6625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
6645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
6655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
6675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
6685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (region->buf)
6705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonReleaseDmaRegion( rmesa, region, __FUNCTION__ );
6715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   alignment--;
6735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start = rmesa->dma.current.ptr =
6745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (rmesa->dma.current.ptr + alignment) & ~alignment;
6755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
6775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonRefillCurrentDmaRegion( rmesa );
6785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->start = rmesa->dma.current.start;
6805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->ptr = rmesa->dma.current.start;
6815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->end = rmesa->dma.current.start + bytes;
6825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->address = rmesa->dma.current.address;
6835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf = rmesa->dma.current.buf;
6845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf->refcount++;
6855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
6875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start =
6885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
6895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
6925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				struct radeon_dma_region *region,
6935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int numverts,
6945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int vertsize,
6955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int alignment )
6965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonAllocDmaRegion( rmesa, region, vertsize * numverts, alignment );
6985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* ================================================================
7015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * SwapBuffers with client-side throttling
7025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
7035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic CARD32 radeonGetLastFrame (radeonContextPtr rmesa)
7055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
7075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
7085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   CARD32 frame;
7095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dri.screen->drmMinor >= 4) {
7115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      drmRadeonGetParam gp;
7125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      gp.param = RADEON_PARAM_LAST_FRAME;
714bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      gp.value = (int *)&frame;
7155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
7165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				 &gp, sizeof(gp) );
7175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else
7195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = -EINVAL;
7205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#ifndef __alpha__
7225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret == -EINVAL ) {
7235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      frame = INREG( RADEON_LAST_FRAME_REG );
7245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = 0;
7255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
7275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
7285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
7295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
7305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return frame;
7335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonEmitIrqLocked( radeonContextPtr rmesa )
7365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmRadeonIrqEmit ie;
7385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
7395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ie.irq_seq = &rmesa->iw.irq_seq;
7415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT,
7425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			      &ie, sizeof(ie) );
7435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
7445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret );
7455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
7465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitIrq( radeonContextPtr rmesa )
7515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
7535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   do {
7555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT,
7565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     &rmesa->iw, sizeof(rmesa->iw) );
7575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } while (ret && (errno == EINTR || errno == EAGAIN));
7585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
7605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
7615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
7625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
7675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEONSAREAPrivPtr sarea = rmesa->sarea;
7695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->do_irqs) {
7715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (radeonGetLastFrame(rmesa) < sarea->last_frame) {
7725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (!rmesa->irqsEmitted) {
7735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    while (radeonGetLastFrame (rmesa) < sarea->last_frame)
7745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       ;
7755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
7765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 else {
7775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    UNLOCK_HARDWARE( rmesa );
7785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    radeonWaitIrq( rmesa );
7795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    LOCK_HARDWARE( rmesa );
7805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
7815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->irqsEmitted = 10;
7825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
7835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->irqsEmitted) {
7855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 radeonEmitIrqLocked( rmesa );
7865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->irqsEmitted--;
7875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
7885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else {
7905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      while (radeonGetLastFrame (rmesa) < sarea->last_frame) {
7915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
7925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (rmesa->do_usleeps)
7935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    DO_USLEEP( 1 );
7945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 LOCK_HARDWARE( rmesa );
7955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
7965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Copy the back color buffer to the front color buffer.
8005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
8015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
8025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
8035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa;
8045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint nbox, i, ret;
8055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLboolean   missed_target;
80699ef0a03292e7dc6aa2465aaaa620f394d2c286bAlan Hourihane   int64_t     ust;
8075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv);
8095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv);
8105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv->driverPrivate);
8115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
8135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
8155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx );
8165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
8195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
8205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the frame rate -- only allow one pending swap buffers
8225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * request at a time.
8235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
8245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForFrameCompletion( rmesa );
8255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
8265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
8275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
8285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   nbox = dPriv->numClipRects; /* must be in locked region */
8305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for ( i = 0 ; i < nbox ; ) {
8325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
8335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      XF86DRIClipRectPtr box = dPriv->pClipRects;
8345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      XF86DRIClipRectPtr b = rmesa->sarea->boxes;
8355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint n = 0;
8365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for ( ; i < nr ; i++ ) {
8385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 *b++ = box[i];
8395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 n++;
8405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = n;
8425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
8445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
8465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret );
8475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
8485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( 1 );
8495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
8535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_count++;
8545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   (*rmesa->get_ust)( & ust );
8555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( missed_target ) {
8565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_count++;
8575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_ust = ust - rmesa->swap_ust;
8585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_ust = ust;
8615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonPageFlip( const __DRIdrawablePrivate *dPriv )
8645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
8655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa;
8665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint ret;
8675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLboolean   missed_target;
8685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv);
8705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv);
8715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv->driverPrivate);
8725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
8745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
8765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
8775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->sarea->pfCurrentPage);
8785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
8815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
8825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Need to do this for the perf box placement:
8845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
8855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (dPriv->numClipRects)
8865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   {
8875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      XF86DRIClipRectPtr box = dPriv->pClipRects;
8885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      XF86DRIClipRectPtr b = rmesa->sarea->boxes;
8895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      b[0] = box[0];
8905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = 1;
8915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the frame rate -- only allow a few pending swap buffers
8945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * request at a time.
8955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
8965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForFrameCompletion( rmesa );
8975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
8985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
8995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( missed_target ) {
9005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_count++;
9015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (void) (*rmesa->get_ust)( & rmesa->swap_missed_ust );
9025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
9065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
9105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
9115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit( 1 );
9125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_count++;
9155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   (void) (*rmesa->get_ust)( & rmesa->swap_ust );
9165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( rmesa->sarea->pfCurrentPage == 1 ) {
9185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
9195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawPitch  = rmesa->radeonScreen->frontPitch;
9205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } else {
9215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
9225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawPitch  = rmesa->radeonScreen->backPitch;
9235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_STATECHANGE( rmesa, ctx );
92699ef0a03292e7dc6aa2465aaaa620f394d2c286bAlan Hourihane   rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
92799ef0a03292e7dc6aa2465aaaa620f394d2c286bAlan Hourihane					   + rmesa->radeonScreen->fbLocation;
9285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
9295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
9305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* ================================================================
9335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Buffer clear
9345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
9355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_MAX_CLEARS	256
9365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
9385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			 GLint cx, GLint cy, GLint cw, GLint ch )
9395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
9405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
9415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
9425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEONSAREAPrivPtr sarea = rmesa->sarea;
9435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
9445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   CARD32 clear;
9455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLuint flags = 0;
9465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLuint color_mask = 0;
9475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint ret, i;
9485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
9505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s:  all=%d cx=%d cy=%d cw=%d ch=%d\n",
9515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       __FUNCTION__, all, cx, cy, cw, ch );
9525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
9555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Need to cope with lostcontext here as kernel relies on
9575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * some residual state:
9585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
9595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
9605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask & DD_FRONT_LEFT_BIT ) {
9625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_FRONT;
9635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
9645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_FRONT_LEFT_BIT;
9655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask & DD_BACK_LEFT_BIT ) {
9685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_BACK;
9695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
9705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_BACK_LEFT_BIT;
9715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask & DD_DEPTH_BIT ) {
9745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ctx->Depth.Mask ) flags |= RADEON_DEPTH; /* FIXME: ??? */
9755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_DEPTH_BIT;
9765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) {
9795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_STENCIL;
9805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_STENCIL_BIT;
9815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask ) {
9845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_FALLBACKS)
9855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
9865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
9875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( !flags )
9905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      return;
9915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Flip top to bottom */
9945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cx += dPriv->x;
9955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cy  = dPriv->y + dPriv->h - cy - ch;
9965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the number of clear ioctls we do.
10005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
10015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   while ( 1 ) {
10025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      int ret;
10035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->dri.screen->drmMinor >= 4) {
10055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	drmRadeonGetParam gp;
10065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	gp.param = RADEON_PARAM_LAST_CLEAR;
1008bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl	gp.value = (int *)&clear;
10095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	ret = drmCommandWriteRead( rmesa->dri.fd,
10105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				   DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
10115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      } else
10125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	ret = -EINVAL;
10135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#ifndef __alpha__
10155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret == -EINVAL ) {
10165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 clear = INREG( RADEON_LAST_CLEAR_REG );
10175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = 0;
10185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
10205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
10215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
10225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit(1);
10235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( RADEON_DEBUG & DEBUG_IOCTL ) {
10255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "%s( %d )\n", __FUNCTION__, (int)clear );
10265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if ( ret ) fprintf( stderr, " ( RADEON_LAST_CLEAR register read directly )\n" );
10275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
10305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 break;
10315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( rmesa->do_usleeps ) {
10345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
10355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 DO_USLEEP( 1 );
10365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 LOCK_HARDWARE( rmesa );
10375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for ( i = 0 ; i < dPriv->numClipRects ; ) {
10415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
10425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      XF86DRIClipRectPtr box = dPriv->pClipRects;
10435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      XF86DRIClipRectPtr b = rmesa->sarea->boxes;
10445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      drmRadeonClearType clear;
10455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
10465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint n = 0;
10475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( !all ) {
10495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for ( ; i < nr ; i++ ) {
10505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint x = box[i].x1;
10515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint y = box[i].y1;
10525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint w = box[i].x2 - x;
10535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint h = box[i].y2 - y;
10545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( x < cx ) w -= cx - x, x = cx;
10565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( y < cy ) h -= cy - y, y = cy;
10575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( x + w > cx + cw ) w = cx + cw - x;
10585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( y + h > cy + ch ) h = cy + ch - y;
10595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( w <= 0 ) continue;
10605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( h <= 0 ) continue;
10615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->x1 = x;
10635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->y1 = y;
10645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->x2 = x + w;
10655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->y2 = y + h;
10665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b++;
10675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    n++;
10685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
10695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      } else {
10705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for ( ; i < nr ; i++ ) {
10715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    *b++ = box[i];
10725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    n++;
10735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
10745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = n;
10775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.flags       = flags;
10795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.clear_color = rmesa->state.color.clear;
10805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.clear_depth = rmesa->state.depth.clear;
10815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
10825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.depth_mask  = rmesa->state.stencil.clear;
10835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.depth_boxes = depth_boxes;
10845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      n--;
10865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      b = rmesa->sarea->boxes;
10875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for ( ; n >= 0 ; n-- ) {
10885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 depth_boxes[n].f[RADEON_CLEAR_X1] = (float)b[n].x1;
10895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 depth_boxes[n].f[RADEON_CLEAR_Y1] = (float)b[n].y1;
10905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 depth_boxes[n].f[RADEON_CLEAR_X2] = (float)b[n].x2;
10915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 depth_boxes[n].f[RADEON_CLEAR_Y2] = (float)b[n].y2;
10925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 depth_boxes[n].f[RADEON_CLEAR_DEPTH] =
10935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    (float)rmesa->state.depth.clear;
10945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR,
10975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     &clear, sizeof(drmRadeonClearType));
10985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
11005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
11015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
11025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( 1 );
11035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
11055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
11075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonWaitForIdleLocked( radeonContextPtr rmesa )
11115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
11125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int fd = rmesa->dri.fd;
11135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int to = 0;
11145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int ret, i = 0;
11155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    rmesa->c_drawWaits++;
11175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    do {
11195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul        do {
11205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul            ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE);
11215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul        } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY );
11225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) );
11235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    if ( ret < 0 ) {
11255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	UNLOCK_HARDWARE( rmesa );
11265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	fprintf( stderr, "Error: Radeon timed out... exiting\n" );
11275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	exit( -1 );
11285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    }
11295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForIdle( radeonContextPtr rmesa )
11335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
11345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE(rmesa);
11355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForIdleLocked( rmesa );
11365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE(rmesa);
11375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlush( GLcontext *ctx )
11415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
11425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
11435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
11455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
11465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
11485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
11495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1150bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl   if (!is_empty_list(&rmesa->hw.dirty))
1151bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      radeonEmitState( rmesa );
11525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1153bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl   if (rmesa->store.cmd_used)
1154bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
11555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Make sure all commands have been sent to the hardware and have
11585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * completed processing.
11595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
11605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFinish( GLcontext *ctx )
11615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
11625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
11635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonFlush( ctx );
11645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->do_irqs) {
11665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      LOCK_HARDWARE( rmesa );
11675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonEmitIrqLocked( rmesa );
11685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      UNLOCK_HARDWARE( rmesa );
11695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitIrq( rmesa );
11705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
11715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else
11725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitForIdle( rmesa );
11735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonInitIoctlFuncs( GLcontext *ctx )
11775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
11785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Clear = radeonClear;
11795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Finish = radeonFinish;
11805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Flush = radeonFlush;
11815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1183