radeon_ioctl.c revision da84f0b642a65614c2618121869d5cd45ad986f5
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
52462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane#define STANDALONE_MMIO
535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "radeon_macros.h"  /* for INREG() */
545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
55da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul#include "drirenderbuffer.h"
565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "vblank.h"
575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_TIMEOUT             512
595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_IDLE_RETRY           16
605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForIdle( radeonContextPtr rmesa );
635562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholtstatic int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
645562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt				    const char * caller );
655562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
668e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheideggerstatic void print_state_atom( struct radeon_state_atom *state )
678e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger{
688e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   int i;
698e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
708e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
718e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
728e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   if (RADEON_DEBUG & DEBUG_VERBOSE)
738e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger      for (i = 0 ; i < state->cmd_size ; i++)
748e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger	 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
758e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
768e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger}
778e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
787a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholtstatic void radeonSaveHwState( radeonContextPtr rmesa )
795562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt{
805562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   struct radeon_state_atom *atom;
817a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   char * dest = rmesa->backup_store.cmd_buf;
825562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
838e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   if (RADEON_DEBUG & DEBUG_STATE)
848e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger      fprintf(stderr, "%s\n", __FUNCTION__);
858e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
867a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->backup_store.cmd_used = 0;
875562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
887a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   foreach( atom, &rmesa->hw.atomlist ) {
897a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      if ( atom->check( rmesa->glCtx ) ) {
907a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 int size = atom->cmd_size * 4;
917a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 memcpy( dest, atom->cmd, size);
927a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 dest += size;
937a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 rmesa->backup_store.cmd_used += size;
948e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger	 if (RADEON_DEBUG & DEBUG_STATE)
958e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger	    print_state_atom( atom );
967a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      }
975562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   }
987a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
997a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ );
1008e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   if (RADEON_DEBUG & DEBUG_STATE)
1018e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger      fprintf(stderr, "Returning to radeonEmitState\n");
1025562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt}
1035562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1045562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt/* At this point we were in FlushCmdBufLocked but we had lost our context, so
1057a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt * we need to unwire our current cmdbuf, hook the one with the saved state in
1067a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt * it, flush it, and then put the current one back.  This is so commands at the
1077a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt * start of a cmdbuf can rely on the state being kept from the previous one.
1085562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt */
1095562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholtstatic void radeonBackUpAndEmitLostStateLocked( radeonContextPtr rmesa )
1105562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt{
1118e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   GLuint nr_released_bufs;
1127a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   struct radeon_store saved_store;
1137a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
1147a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   if (rmesa->backup_store.cmd_used == 0)
1157a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      return;
1167a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
1177a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   if (RADEON_DEBUG & DEBUG_STATE)
1187a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      fprintf(stderr, "Emitting backup state on lost context\n");
1195562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1205562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->lost_context = GL_FALSE;
1215562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1225562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   nr_released_bufs = rmesa->dma.nr_released_bufs;
1237a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   saved_store = rmesa->store;
1247a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->dma.nr_released_bufs = 0;
1257a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->store = rmesa->backup_store;
1267a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
1275562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->dma.nr_released_bufs = nr_released_bufs;
1287a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->store = saved_store;
1295562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt}
1305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* =============================================================
1325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Kernel command buffer handling
1335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
1345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1355562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt/* The state atoms will be emitted in the order they appear in the atom list,
1365562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt * so this step is important.
1375562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt */
1385562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholtvoid radeonSetUpAtomList( radeonContextPtr rmesa )
1395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
1405562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   int i, mtu = rmesa->glCtx->Const.MaxTextureUnits;
1415562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1425562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   make_empty_list(&rmesa->hw.atomlist);
1435562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.atomlist.name = "atom-list";
1445562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1455562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx);
1465562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set);
1475562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin);
1485562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk);
1495562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt);
1505562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl);
1515562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc);
1525562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   for (i = 0; i < mtu; ++i) {
1535562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]);
1545562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]);
15522d1acf2ee25280c3294c2cfded232e612ffac2eFelix Kuehling   }
1565562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs);
1575562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl);
1585562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   for (i = 0; i < 3 + mtu; ++i)
1595562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]);
16022d1acf2ee25280c3294c2cfded232e612ffac2eFelix Kuehling   for (i = 0; i < 8; ++i)
1615562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]);
16222d1acf2ee25280c3294c2cfded232e612ffac2eFelix Kuehling   for (i = 0; i < 6; ++i)
1635562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]);
1645562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye);
1655562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd);
1665562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog);
1675562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt);
1685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
1695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitState( radeonContextPtr rmesa )
1715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
1725562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   struct radeon_state_atom *atom;
1735562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   char *dest;
1745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
1765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
1775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1787a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   if (rmesa->save_on_next_emit) {
1797a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      radeonSaveHwState(rmesa);
1807a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      rmesa->save_on_next_emit = GL_FALSE;
1817a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   }
1827a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
18372e3664996721263858f3096e4a618a406550402Dave Airlie   /* this code used to return here but now it emits zbs */
1845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1855562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   /* To avoid going across the entire set of states multiple times, just check
1865562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt    * for enough space for the case of emitting all state, and inline the
1875562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt    * radeonAllocCmdBuf code here without all the checks.
1885562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt    */
1895562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   radeonEnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size);
1905562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   dest = rmesa->store.cmd_buf + rmesa->store.cmd_used;
1915562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
19272e3664996721263858f3096e4a618a406550402Dave Airlie   /* We always always emit zbs, this is due to a bug found by keithw in
19372e3664996721263858f3096e4a618a406550402Dave Airlie      the hardware and rediscovered after Erics changes by me.
19472e3664996721263858f3096e4a618a406550402Dave Airlie      if you ever touch this code make sure you emit zbs otherwise
19572e3664996721263858f3096e4a618a406550402Dave Airlie      you get tcl lockups on at least M7/7500 class of chips - airlied */
19672e3664996721263858f3096e4a618a406550402Dave Airlie   rmesa->hw.zbs.dirty=1;
19772e3664996721263858f3096e4a618a406550402Dave Airlie
1985562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   if (RADEON_DEBUG & DEBUG_STATE) {
1995562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      foreach(atom, &rmesa->hw.atomlist) {
2005562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 if (atom->dirty || rmesa->hw.all_dirty) {
2015562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    if (atom->check(rmesa->glCtx))
2025562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	       print_state_atom(atom);
2035562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    else
2045562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	       fprintf(stderr, "skip state %s\n", atom->name);
2055562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 }
2065562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      }
2075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
2085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2095562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   foreach(atom, &rmesa->hw.atomlist) {
2105562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      if (rmesa->hw.all_dirty)
2115562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 atom->dirty = GL_TRUE;
2125562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) &&
2135562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	   atom->is_tcl)
2145562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 atom->dirty = GL_FALSE;
2155562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      if (atom->dirty) {
2165562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 if (atom->check(rmesa->glCtx)) {
2175562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    int size = atom->cmd_size * 4;
2185562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    memcpy(dest, atom->cmd, size);
2195562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    dest += size;
2205562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    rmesa->store.cmd_used += size;
2215562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    atom->dirty = GL_FALSE;
2225562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 }
2235562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      }
2245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
2255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2265562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   assert(rmesa->store.cmd_used <= RADEON_CMD_BUF_SZ);
2275562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
2285562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.is_dirty = GL_FALSE;
2295562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.all_dirty = GL_FALSE;
2305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
2315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Fire a section of the retained (indexed_verts) buffer as a regular
2335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * primtive.
2345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
2355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulextern void radeonEmitVbufPrim( radeonContextPtr rmesa,
2365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint vertex_format,
2375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint primitive,
2385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint vertex_nr )
2395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
240ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
2415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
2445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
2465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
2485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__,
2495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->store.cmd_used/4);
2505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2516f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VBUF_BUFSZ,
2526f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt						       __FUNCTION__ );
2535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2546f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd[0].i = 0;
2555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
2565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16);
2575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = rmesa->ioctl.vertex_offset;
2585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = vertex_nr;
2595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = vertex_format;
2605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (primitive |
2615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
2625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
2645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
2655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
2675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n",
2685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
2695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i);
2705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
2725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
2735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16);
2745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = vertex_format;
2755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = (primitive |
2765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
2775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_MAOS_ENABLE |
2795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
2805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
2815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
2845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n",
2855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
2865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, cmd[2].i, cmd[3].i);
2875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
2895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlushElts( radeonContextPtr rmesa )
2925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
2935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start);
2945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int dwords;
2955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2;
2975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2;
2995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
3005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
3025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
3035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( rmesa->dma.flush == radeonFlushElts );
3052c28dd892cfb43445d7e54df8b6a8331192f4e99Brian Paul   rmesa->dma.flush = NULL;
3065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Cope with odd number of elts:
3085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
3095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
3105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
3115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1] |= (dwords - 3) << 16;
3145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
3155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
3165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1] |= (dwords - 3) << 16;
3175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
3185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
319150ed2e43d5541556d282cae728cebeec692e07aDave Airlie
320150ed2e43d5541556d282cae728cebeec692e07aDave Airlie   if (RADEON_DEBUG & DEBUG_SYNC) {
321150ed2e43d5541556d282cae728cebeec692e07aDave Airlie      fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
322150ed2e43d5541556d282cae728cebeec692e07aDave Airlie      radeonFinish( rmesa->glCtx );
323150ed2e43d5541556d282cae728cebeec692e07aDave Airlie   }
3245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulGLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
3285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint vertex_format,
3295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint primitive,
3305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint min_nr )
3315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
332ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
3335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLushort *retval;
3345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
3365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr);
3375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
3395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
3415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3426f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa,
3436f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt						       ELTS_BUFSZ(min_nr),
3446f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt						       __FUNCTION__ );
3455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
3485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM;
3495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = rmesa->ioctl.vertex_offset;
3505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = 0xffff;
3515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = vertex_format;
3525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (primitive |
3535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_IND |
3545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
3555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
3565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   retval = (GLushort *)(cmd+6);
3585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
3595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
3615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX;
3625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = vertex_format;
3635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = (primitive |
3645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_IND |
3655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
3665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_MAOS_ENABLE |
3675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
3685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   retval = (GLushort *)(cmd+4);
3705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
3715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
3735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n",
3745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
3755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, vertex_format, primitive);
3765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(!rmesa->dma.flush);
3785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
3795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.flush = radeonFlushElts;
3805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf;
3825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return retval;
3845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitVertexAOS( radeonContextPtr rmesa,
3895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  GLuint vertex_size,
3905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  GLuint offset )
3915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
3925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_size = vertex_size;
3945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_offset = offset;
3955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
396ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
3975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
3995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
4005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__, vertex_size, offset);
4015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4026f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VERT_AOS_BUFSZ,
4035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
4045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
4065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
4075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16);
4085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = 1;
4095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = vertex_size | (vertex_size << 8);
4105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = offset;
4115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
4125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
4135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitAOS( radeonContextPtr rmesa,
4165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    struct radeon_dma_region **component,
4175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    GLuint nr,
4185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    GLuint offset )
4195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
4205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
4215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( nr == 1 );
4225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( component[0]->aos_size == component[0]->aos_stride );
4235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_size = component[0]->aos_size;
4245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_offset =
4255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (component[0]->aos_start + offset * component[0]->aos_stride * 4);
4265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
427ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
4285562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   int sz = AOS_BUFSZ(nr);
4295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int i;
4305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int *tmp;
4315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
4335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
4345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4366f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sz,
4375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
4385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
4395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
4406f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (((sz / sizeof(int))-3) << 16);
4415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = nr;
4425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   tmp = &cmd[0].i;
4435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd += 3;
4445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for (i = 0 ; i < nr ; i++) {
4465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (i & 1) {
4475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[0].i |= ((component[i]->aos_stride << 24) |
4485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		      (component[i]->aos_size << 16));
4495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[2].i = (component[i]->aos_start +
4505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     offset * component[i]->aos_stride * 4);
4515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd += 3;
4525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
4535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else {
4545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[0].i = ((component[i]->aos_stride << 8) |
4555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     (component[i]->aos_size << 0));
4565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[1].i = (component[i]->aos_start +
4575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     offset * component[i]->aos_stride * 4);
4585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
4595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_VERTS) {
4625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s:\n", __FUNCTION__);
4635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for (i = 0 ; i < sz ; i++)
4645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "   %d: %x\n", i, tmp[i]);
4655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
4675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
4685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* using already shifted color_fmt! */
4705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitBlit( radeonContextPtr rmesa, /* FIXME: which drmMinor is required? */
4715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint color_fmt,
4725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint src_pitch,
4735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint src_offset,
4745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint dst_pitch,
4755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint dst_offset,
4765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLint srcx, GLint srcy,
4775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLint dstx, GLint dsty,
4785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint w, GLuint h )
4795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
480ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
4815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
4835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
4845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
4855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      src_pitch, src_offset, srcx, srcy,
4865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      dst_pitch, dst_offset, dstx, dsty,
4875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      w, h);
4885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (src_pitch & 63) == 0 );
4905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (dst_pitch & 63) == 0 );
4915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (src_offset & 1023) == 0 );
4925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (dst_offset & 1023) == 0 );
4935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( w < (1<<16) );
4945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( h < (1<<16) );
4955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
496ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int),
4975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
4985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
5015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
5025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
5035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
5045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_DST_PITCH_OFFSET_CNTL |
5055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_BRUSH_NONE |
5065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       color_fmt |
5075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_SRC_DATATYPE_COLOR |
5085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_ROP3_S |
5095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_DP_SRC_SOURCE_MEMORY |
5105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_CLR_CMP_CNTL_DIS |
5115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_WR_MSK_DIS );
5125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10);
5145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10);
5155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (srcx << 16) | srcy;
5165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[6].i = (dstx << 16) | dsty; /* dst */
5175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[7].i = (w << 16) | h;
5185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitWait( radeonContextPtr rmesa, GLuint flags )
5225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dri.drmMinor >= 6) {
524ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_cmd_header_t *cmd;
5255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
5275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
528ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int),
5295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						   __FUNCTION__ );
5305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].i = 0;
5315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
5325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].wait.flags = flags;
5335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
5385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    const char * caller )
5395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret, i;
541ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_buffer_t cmd;
5425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5435562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   if (rmesa->lost_context)
5445562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      radeonBackUpAndEmitLostStateLocked(rmesa);
5455562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
5465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL) {
5475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
5485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_VERBOSE)
5505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 )
5515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    fprintf(stderr, "%d: %x\n", i/4,
5525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    *(int *)(&rmesa->store.cmd_buf[i]));
5535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_DMA)
5565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__,
5575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->dma.nr_released_bufs);
5585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_SANITY) {
5615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->state.scissor.enabled)
5625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = radeonSanityCmdBuffer( rmesa,
5635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->state.scissor.numClipRects,
5645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->state.scissor.pClipRects);
5655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else
5665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = radeonSanityCmdBuffer( rmesa,
5675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->numClipRects,
5685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->pClipRects);
5695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (ret) {
5705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "drmSanityCommandWrite: %d\n", ret);
5715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 goto out;
5725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
5735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd.bufsz = rmesa->store.cmd_used;
5775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd.buf = rmesa->store.cmd_buf;
5785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->state.scissor.enabled) {
5805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.nbox = rmesa->state.scissor.numClipRects;
581ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd.boxes = rmesa->state.scissor.pClipRects;
5825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } else {
5835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.nbox = rmesa->numClipRects;
584ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd.boxes = rmesa->pClipRects;
5855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandWrite( rmesa->dri.fd,
5885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  DRM_RADEON_CMDBUF,
5895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  &cmd, sizeof(cmd) );
5905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret)
5925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "drmCommandWrite: %d\n", ret);
5935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
594150ed2e43d5541556d282cae728cebeec692e07aDave Airlie   if (RADEON_DEBUG & DEBUG_SYNC) {
595150ed2e43d5541556d282cae728cebeec692e07aDave Airlie      fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__);
596150ed2e43d5541556d282cae728cebeec692e07aDave Airlie      radeonWaitForIdleLocked( rmesa );
597150ed2e43d5541556d282cae728cebeec692e07aDave Airlie   }
598150ed2e43d5541556d282cae728cebeec692e07aDave Airlie
5995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul out:
6005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.primnr = 0;
6015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.statenr = 0;
6025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.cmd_used = 0;
6035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.nr_released_bufs = 0;
6047a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->save_on_next_emit = 1;
605626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt
6065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return ret;
6075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Note: does not emit any commands to avoid recursion on
6115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * radeonAllocCmdBuf.
6125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
6135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller )
6145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
6165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
6195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = radeonFlushCmdBufLocked( rmesa, caller );
6215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
6235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret) {
625ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      fprintf(stderr, "drm_radeon_cmd_buffer_t: %d (exiting)\n", ret);
6265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(ret);
6275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* =============================================================
6315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Hardware vertex buffer handling
6325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
6335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonRefillCurrentDmaRegion( radeonContextPtr rmesa )
6365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   struct radeon_dma_buffer *dmabuf;
6385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int fd = rmesa->dri.fd;
6395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int index = 0;
6405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int size = 0;
6415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmDMAReq dma;
6425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
6435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
6455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
6465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush) {
6485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
6495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.current.buf)
6525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
6535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.nr_released_bufs > 4)
6555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
6565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.context = rmesa->dri.hwContext;
6585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_count = 0;
6595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_list = NULL;
6605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_sizes = NULL;
6615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.flags = 0;
6625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_count = 1;
6635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_size = RADEON_BUFFER_SIZE;
6645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_list = &index;
6655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_sizes = &size;
6665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.granted_count = 0;
6675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE(rmesa);	/* no need to validate */
6695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmDMA( fd, &dma );
6715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret != 0) {
6735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      /* Free some up this way?
6745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       */
6755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->dma.nr_released_bufs) {
6765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
6775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
6785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_DMA)
6805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "Waiting for buffers\n");
6815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitForIdleLocked( rmesa );
6835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmDMA( fd, &dma );
6845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret != 0 ) {
6865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
6875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "Error: Could not get dma buffer... exiting\n" );
6885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( -1 );
6895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
6905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE(rmesa);
6935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_DMA)
6955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "Allocated buffer %d\n", index);
6965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf = CALLOC_STRUCT( radeon_dma_buffer );
6985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf->buf = &rmesa->radeonScreen->buffers->list[index];
6995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf->refcount = 1;
7005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.buf = dmabuf;
7025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.address = dmabuf->buf->address;
7035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.end = dmabuf->buf->total;
7045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start = 0;
7055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.ptr = 0;
7065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->c_vertexBuffers++;
7085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonReleaseDmaRegion( radeonContextPtr rmesa,
7115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     struct radeon_dma_region *region,
7125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     const char *caller )
7135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
7155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
7165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (!region->buf)
7185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      return;
7195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
7215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
7225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (--region->buf->refcount == 0) {
724ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_cmd_header_t *cmd;
7255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
7275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
7285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		 region->buf->buf->idx);
7295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
730ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sizeof(*cmd),
7315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						     __FUNCTION__ );
7325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
7335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->dma.buf_idx = region->buf->buf->idx;
7345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      FREE(region->buf);
7355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.nr_released_bufs++;
7365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7382c28dd892cfb43445d7e54df8b6a8331192f4e99Brian Paul   region->buf = NULL;
7395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->start = 0;
7405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Allocates a region from rmesa->dma.current.  If there isn't enough
7435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * space in current, grab a new buffer (and discard what was left of current)
7445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
7455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonAllocDmaRegion( radeonContextPtr rmesa,
7465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   struct radeon_dma_region *region,
7475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   int bytes,
7485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   int alignment )
7495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
7515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
7525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
7545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
7555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (region->buf)
7575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonReleaseDmaRegion( rmesa, region, __FUNCTION__ );
7585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   alignment--;
7605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start = rmesa->dma.current.ptr =
7615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (rmesa->dma.current.ptr + alignment) & ~alignment;
7625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
7645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonRefillCurrentDmaRegion( rmesa );
7655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->start = rmesa->dma.current.start;
7675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->ptr = rmesa->dma.current.start;
7685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->end = rmesa->dma.current.start + bytes;
7695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->address = rmesa->dma.current.address;
7705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf = rmesa->dma.current.buf;
7715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf->refcount++;
7725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
7745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start =
7755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
7765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
7795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				struct radeon_dma_region *region,
7805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int numverts,
7815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int vertsize,
7825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int alignment )
7835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonAllocDmaRegion( rmesa, region, vertsize * numverts, alignment );
7855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* ================================================================
7885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * SwapBuffers with client-side throttling
7895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
7905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
79138b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihanestatic u_int32_t radeonGetLastFrame (radeonContextPtr rmesa)
7925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
7945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
79538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane   u_int32_t frame;
7965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dri.screen->drmMinor >= 4) {
798ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_getparam_t gp;
7995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      gp.param = RADEON_PARAM_LAST_FRAME;
801bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      gp.value = (int *)&frame;
8025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
8035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				 &gp, sizeof(gp) );
8045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else
8065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = -EINVAL;
8075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret == -EINVAL ) {
8095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      frame = INREG( RADEON_LAST_FRAME_REG );
8105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = 0;
8115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
813ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
8145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
8155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return frame;
8185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonEmitIrqLocked( radeonContextPtr rmesa )
8215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
822ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_irq_emit_t ie;
8235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
8245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ie.irq_seq = &rmesa->iw.irq_seq;
8265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT,
8275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			      &ie, sizeof(ie) );
8285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
829ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      fprintf( stderr, "%s: drm_radeon_irq_emit_t: %d\n", __FUNCTION__, ret );
8305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
8315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitIrq( radeonContextPtr rmesa )
8365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
8375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
8385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   do {
8405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT,
8415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     &rmesa->iw, sizeof(rmesa->iw) );
8425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } while (ret && (errno == EINTR || errno == EAGAIN));
8435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
8455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
8465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
8475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
8525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
853ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_sarea_t *sarea = rmesa->sarea;
8545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->do_irqs) {
8565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (radeonGetLastFrame(rmesa) < sarea->last_frame) {
8575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (!rmesa->irqsEmitted) {
8585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    while (radeonGetLastFrame (rmesa) < sarea->last_frame)
8595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       ;
8605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
8615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 else {
8625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    UNLOCK_HARDWARE( rmesa );
8635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    radeonWaitIrq( rmesa );
8645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    LOCK_HARDWARE( rmesa );
8655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
8665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->irqsEmitted = 10;
8675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->irqsEmitted) {
8705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 radeonEmitIrqLocked( rmesa );
8715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->irqsEmitted--;
8725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else {
8755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      while (radeonGetLastFrame (rmesa) < sarea->last_frame) {
8765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
8775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (rmesa->do_usleeps)
8785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    DO_USLEEP( 1 );
8795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 LOCK_HARDWARE( rmesa );
8805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Copy the back color buffer to the front color buffer.
8855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
8865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
8875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
8885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa;
8895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint nbox, i, ret;
8905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLboolean   missed_target;
891ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   int64_t ust;
8925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv);
8945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv);
8955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv->driverPrivate);
8965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
8985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
900894844a8d956a0ee5f95836331dc318f49fdb845Brian Paul      fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
9015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
9045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the frame rate -- only allow one pending swap buffers
9075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * request at a time.
9085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
9095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForFrameCompletion( rmesa );
9105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
9125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   nbox = dPriv->numClipRects; /* must be in locked region */
9155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for ( i = 0 ; i < nbox ; ) {
9175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
918ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *box = dPriv->pClipRects;
919ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *b = rmesa->sarea->boxes;
9205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint n = 0;
9215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for ( ; i < nr ; i++ ) {
9235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 *b++ = box[i];
9245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 n++;
9255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
9265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = n;
9275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
9295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
9315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret );
9325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
9335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( 1 );
9345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
9355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_count++;
9395f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick   (*dri_interface->getUST)( & ust );
9405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( missed_target ) {
9415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_count++;
9425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_ust = ust - rmesa->swap_ust;
9435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_ust = ust;
9465562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.all_dirty = GL_TRUE;
9475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
9485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonPageFlip( const __DRIdrawablePrivate *dPriv )
9505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
9515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa;
9525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint ret;
9535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLboolean   missed_target;
9545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv);
9565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv);
9575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv->driverPrivate);
9585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
9605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
9625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
9635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->sarea->pfCurrentPage);
9645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
9675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Need to do this for the perf box placement:
9705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
9715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (dPriv->numClipRects)
9725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   {
973ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *box = dPriv->pClipRects;
974ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *b = rmesa->sarea->boxes;
9755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      b[0] = box[0];
9765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = 1;
9775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the frame rate -- only allow a few pending swap buffers
9805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * request at a time.
9815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
9825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForFrameCompletion( rmesa );
9835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
9855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( missed_target ) {
9865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_count++;
9875f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick      (void) (*dri_interface->getUST)( & rmesa->swap_missed_ust );
9885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
9925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
9965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
9975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit( 1 );
9985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_count++;
10015f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick   (void) (*dri_interface->getUST)( & rmesa->swap_ust );
10025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1003da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul   /* Get ready for drawing next frame.  Update the renderbuffers'
1004da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul    * flippedOffset/Pitch fields so we draw into the right place.
1005da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul    */
1006da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul   driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,
1007da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul                        rmesa->sarea->pfCurrentPage);
1008da84f0b642a65614c2618121869d5cd45ad986f5Brian Paul
1009982e8e4d5c95e9e9040b4b70d7322a2a8a9396d9Brian Paul   radeonUpdateDrawBuffer(rmesa->glCtx);
10105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
10115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* ================================================================
10145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Buffer clear
10155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
10165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_MAX_CLEARS	256
10175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
10195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			 GLint cx, GLint cy, GLint cw, GLint ch )
10205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
10215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
10225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1023ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_sarea_t *sarea = rmesa->sarea;
10245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
102538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane   u_int32_t clear;
10265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLuint flags = 0;
10275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLuint color_mask = 0;
10285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint ret, i;
10295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
10315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s:  all=%d cx=%d cy=%d cw=%d ch=%d\n",
10325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       __FUNCTION__, all, cx, cy, cw, ch );
10335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1035ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger   {
1036ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger      LOCK_HARDWARE( rmesa );
1037ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger      UNLOCK_HARDWARE( rmesa );
1038ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger      if ( dPriv->numClipRects == 0 )
1039ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger	 return;
1040ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger   }
1041ce055c26f08556a46ee8b4b88e5fd15eb4d2acd1Roland Scheidegger
10428e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   radeonFlush( ctx );
10435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1044e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
10455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_FRONT;
10465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
1047e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      mask &= ~BUFFER_BIT_FRONT_LEFT;
10485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1050e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if ( mask & BUFFER_BIT_BACK_LEFT ) {
10515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_BACK;
10525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
1053e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      mask &= ~BUFFER_BIT_BACK_LEFT;
10545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1056e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if ( mask & BUFFER_BIT_DEPTH ) {
1057b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger      flags |= RADEON_DEPTH;
1058e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      mask &= ~BUFFER_BIT_DEPTH;
10595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1061e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) {
10625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_STENCIL;
1063e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      mask &= ~BUFFER_BIT_STENCIL;
10645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask ) {
10675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_FALLBACKS)
10685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
10695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
10705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( !flags )
10735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      return;
10745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1075b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger   if (rmesa->using_hyperz) {
1076b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger      flags |= RADEON_USE_COMP_ZBUF;
1077b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger/*      if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)
1078b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger         flags |= RADEON_USE_HIERZ; */
1079b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger      if (!(rmesa->state.stencil.hwBuffer) ||
1080b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger	 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
1081b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger	    ((rmesa->state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
1082b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger	  flags |= RADEON_CLEAR_FASTZ;
1083b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger      }
1084b31b7836d6e7abf80dd4feacce333d4b1fe6e4abRoland Scheidegger   }
10855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Flip top to bottom */
10875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cx += dPriv->x;
10885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cy  = dPriv->y + dPriv->h - cy - ch;
10895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
10915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the number of clear ioctls we do.
10935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
10945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   while ( 1 ) {
10955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      int ret;
10965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->dri.screen->drmMinor >= 4) {
1098ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	drm_radeon_getparam_t gp;
10995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	gp.param = RADEON_PARAM_LAST_CLEAR;
1101bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl	gp.value = (int *)&clear;
11025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	ret = drmCommandWriteRead( rmesa->dri.fd,
11035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				   DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
11045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      } else
11055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	ret = -EINVAL;
11065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret == -EINVAL ) {
11085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 clear = INREG( RADEON_LAST_CLEAR_REG );
11095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = 0;
11105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
1112ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
11135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit(1);
11145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( RADEON_DEBUG & DEBUG_IOCTL ) {
11165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "%s( %d )\n", __FUNCTION__, (int)clear );
11175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if ( ret ) fprintf( stderr, " ( RADEON_LAST_CLEAR register read directly )\n" );
11185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
11215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 break;
11225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( rmesa->do_usleeps ) {
11255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
11265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 DO_USLEEP( 1 );
11275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 LOCK_HARDWARE( rmesa );
11285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
11305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1131626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt   /* Send current state to the hardware */
1132626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt   radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
1133626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt
11345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for ( i = 0 ; i < dPriv->numClipRects ; ) {
11355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
1136ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *box = dPriv->pClipRects;
1137ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *b = rmesa->sarea->boxes;
1138ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_clear_t clear;
1139ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
11405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint n = 0;
11415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( !all ) {
11435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for ( ; i < nr ; i++ ) {
11445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint x = box[i].x1;
11455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint y = box[i].y1;
11465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint w = box[i].x2 - x;
11475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint h = box[i].y2 - y;
11485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( x < cx ) w -= cx - x, x = cx;
11505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( y < cy ) h -= cy - y, y = cy;
11515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( x + w > cx + cw ) w = cx + cw - x;
11525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( y + h > cy + ch ) h = cy + ch - y;
11535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( w <= 0 ) continue;
11545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( h <= 0 ) continue;
11555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->x1 = x;
11575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->y1 = y;
11585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->x2 = x + w;
11595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->y2 = y + h;
11605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b++;
11615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    n++;
11625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
11635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      } else {
11645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for ( ; i < nr ; i++ ) {
11655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    *b++ = box[i];
11665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    n++;
11675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
11685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = n;
11715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.flags       = flags;
11735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.clear_color = rmesa->state.color.clear;
11745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.clear_depth = rmesa->state.depth.clear;
11755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
11765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.depth_mask  = rmesa->state.stencil.clear;
11775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.depth_boxes = depth_boxes;
11785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      n--;
11805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      b = rmesa->sarea->boxes;
11815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for ( ; n >= 0 ; n-- ) {
1182ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1;
1183ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1;
1184ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2;
1185ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2;
1186ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_DEPTH] =
11875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    (float)rmesa->state.depth.clear;
11885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR,
1191ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl			     &clear, sizeof(drm_radeon_clear_t));
11925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
11945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
11955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
11965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( 1 );
11975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
11995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
12015562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.all_dirty = GL_TRUE;
12025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonWaitForIdleLocked( radeonContextPtr rmesa )
12065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int fd = rmesa->dri.fd;
12085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int to = 0;
12095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int ret, i = 0;
12105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    rmesa->c_drawWaits++;
12125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    do {
12145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul        do {
12155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul            ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE);
12165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul        } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY );
12175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) );
12185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    if ( ret < 0 ) {
12205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	UNLOCK_HARDWARE( rmesa );
12215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	fprintf( stderr, "Error: Radeon timed out... exiting\n" );
12225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	exit( -1 );
12235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    }
12245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForIdle( radeonContextPtr rmesa )
12285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE(rmesa);
12305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForIdleLocked( rmesa );
12315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE(rmesa);
12325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlush( GLcontext *ctx )
12365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
12385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
12405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
12415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
12435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
12445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12455562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   radeonEmitState( rmesa );
12465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1247bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl   if (rmesa->store.cmd_used)
1248bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
12495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Make sure all commands have been sent to the hardware and have
12525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * completed processing.
12535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
12545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFinish( GLcontext *ctx )
12555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
12575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonFlush( ctx );
12585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->do_irqs) {
12605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      LOCK_HARDWARE( rmesa );
12615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonEmitIrqLocked( rmesa );
12625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      UNLOCK_HARDWARE( rmesa );
12635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitIrq( rmesa );
12645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
12655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else
12665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitForIdle( rmesa );
12675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonInitIoctlFuncs( GLcontext *ctx )
12715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Clear = radeonClear;
12735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Finish = radeonFinish;
12745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Flush = radeonFlush;
12755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1277