radeon_ioctl.c revision 8e3926575264d31b3caacb9cbb606f8f2914f57d
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
555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#include "vblank.h"
565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_TIMEOUT             512
585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_IDLE_RETRY           16
595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForIdle( radeonContextPtr rmesa );
625562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholtstatic int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
635562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt				    const char * caller );
645562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
658e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheideggerstatic void print_state_atom( struct radeon_state_atom *state )
668e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger{
678e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   int i;
688e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
698e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size);
708e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
718e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   if (RADEON_DEBUG & DEBUG_VERBOSE)
728e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger      for (i = 0 ; i < state->cmd_size ; i++)
738e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger	 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]);
748e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
758e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger}
768e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
777a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholtstatic void radeonSaveHwState( radeonContextPtr rmesa )
785562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt{
795562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   struct radeon_state_atom *atom;
807a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   char * dest = rmesa->backup_store.cmd_buf;
815562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
828e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   if (RADEON_DEBUG & DEBUG_STATE)
838e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger      fprintf(stderr, "%s\n", __FUNCTION__);
848e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger
857a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->backup_store.cmd_used = 0;
865562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
877a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   foreach( atom, &rmesa->hw.atomlist ) {
887a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      if ( atom->check( rmesa->glCtx ) ) {
897a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 int size = atom->cmd_size * 4;
907a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 memcpy( dest, atom->cmd, size);
917a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 dest += size;
927a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt	 rmesa->backup_store.cmd_used += size;
938e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger	 if (RADEON_DEBUG & DEBUG_STATE)
948e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger	    print_state_atom( atom );
957a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      }
965562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   }
977a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
987a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ );
998e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   if (RADEON_DEBUG & DEBUG_STATE)
1008e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger      fprintf(stderr, "Returning to radeonEmitState\n");
1015562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt}
1025562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1035562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt/* At this point we were in FlushCmdBufLocked but we had lost our context, so
1047a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt * we need to unwire our current cmdbuf, hook the one with the saved state in
1057a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt * it, flush it, and then put the current one back.  This is so commands at the
1067a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt * start of a cmdbuf can rely on the state being kept from the previous one.
1075562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt */
1085562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholtstatic void radeonBackUpAndEmitLostStateLocked( radeonContextPtr rmesa )
1095562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt{
1108e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   GLuint nr_released_bufs;
1117a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   struct radeon_store saved_store;
1127a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
1137a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   if (rmesa->backup_store.cmd_used == 0)
1147a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      return;
1157a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
1167a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   if (RADEON_DEBUG & DEBUG_STATE)
1177a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      fprintf(stderr, "Emitting backup state on lost context\n");
1185562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1195562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->lost_context = GL_FALSE;
1205562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1215562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   nr_released_bufs = rmesa->dma.nr_released_bufs;
1227a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   saved_store = rmesa->store;
1237a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->dma.nr_released_bufs = 0;
1247a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->store = rmesa->backup_store;
1257a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
1265562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->dma.nr_released_bufs = nr_released_bufs;
1277a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->store = saved_store;
1285562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt}
1295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* =============================================================
1315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Kernel command buffer handling
1325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
1335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1345562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt/* The state atoms will be emitted in the order they appear in the atom list,
1355562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt * so this step is important.
1365562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt */
1375562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholtvoid radeonSetUpAtomList( radeonContextPtr rmesa )
1385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
1395562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   int i, mtu = rmesa->glCtx->Const.MaxTextureUnits;
1405562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1415562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   make_empty_list(&rmesa->hw.atomlist);
1425562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.atomlist.name = "atom-list";
1435562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
1445562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx);
1455562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set);
1465562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin);
1475562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk);
1485562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt);
1495562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl);
1505562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc);
1515562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   for (i = 0; i < mtu; ++i) {
1525562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]);
1535562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt       insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]);
15422d1acf2ee25280c3294c2cfded232e612ffac2eFelix Kuehling   }
1555562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs);
1565562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl);
1575562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   for (i = 0; i < 3 + mtu; ++i)
1585562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]);
15922d1acf2ee25280c3294c2cfded232e612ffac2eFelix Kuehling   for (i = 0; i < 8; ++i)
1605562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]);
16122d1acf2ee25280c3294c2cfded232e612ffac2eFelix Kuehling   for (i = 0; i < 6; ++i)
1625562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]);
1635562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye);
1645562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd);
1655562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog);
1665562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt);
1675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
1685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitState( radeonContextPtr rmesa )
1705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
1715562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   struct radeon_state_atom *atom;
1725562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   char *dest;
1735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
1755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
1765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1777a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   if (rmesa->save_on_next_emit) {
1787a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      radeonSaveHwState(rmesa);
1797a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt      rmesa->save_on_next_emit = GL_FALSE;
1807a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   }
1817a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt
1825562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty)
1835562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      return;
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
1925562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   if (RADEON_DEBUG & DEBUG_STATE) {
1935562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      foreach(atom, &rmesa->hw.atomlist) {
1945562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 if (atom->dirty || rmesa->hw.all_dirty) {
1955562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    if (atom->check(rmesa->glCtx))
1965562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	       print_state_atom(atom);
1975562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    else
1985562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	       fprintf(stderr, "skip state %s\n", atom->name);
1995562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 }
2005562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      }
2015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
2025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2035562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   foreach(atom, &rmesa->hw.atomlist) {
2045562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      if (rmesa->hw.all_dirty)
2055562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 atom->dirty = GL_TRUE;
2065562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      if (!(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) &&
2075562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	   atom->is_tcl)
2085562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 atom->dirty = GL_FALSE;
2095562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      if (atom->dirty) {
2105562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 if (atom->check(rmesa->glCtx)) {
2115562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    int size = atom->cmd_size * 4;
2125562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    memcpy(dest, atom->cmd, size);
2135562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    dest += size;
2145562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    rmesa->store.cmd_used += size;
2155562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	    atom->dirty = GL_FALSE;
2165562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt	 }
2175562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      }
2185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
2195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2205562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   assert(rmesa->store.cmd_used <= RADEON_CMD_BUF_SZ);
2215562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
2225562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.is_dirty = GL_FALSE;
2235562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.all_dirty = GL_FALSE;
2245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
2255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Fire a section of the retained (indexed_verts) buffer as a regular
2275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * primtive.
2285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
2295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulextern void radeonEmitVbufPrim( radeonContextPtr rmesa,
2305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint vertex_format,
2315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint primitive,
2325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				GLuint vertex_nr )
2335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
234ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
2355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
2385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
2405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
2425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__,
2435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->store.cmd_used/4);
2445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2456f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VBUF_BUFSZ,
2466f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt						       __FUNCTION__ );
2475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2486f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd[0].i = 0;
2495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
2505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16);
2515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = rmesa->ioctl.vertex_offset;
2525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = vertex_nr;
2535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = vertex_format;
2545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (primitive |
2555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
2565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
2585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
2595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
2615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n",
2625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
2635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i);
2645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
2665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
2675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16);
2685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = vertex_format;
2695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = (primitive |
2705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
2715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
2725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_MAOS_ENABLE |
2735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
2745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
2755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
2785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n",
2795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
2805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, cmd[2].i, cmd[3].i);
2815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
2835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlushElts( radeonContextPtr rmesa )
2865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
2875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start);
2885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int dwords;
2895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
2905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2;
2915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
2925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2;
2935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
2945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
2965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
2975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
2985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( rmesa->dma.flush == radeonFlushElts );
2995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.flush = 0;
3005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Cope with odd number of elts:
3025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
3035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
3045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
3055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1] |= (dwords - 3) << 16;
3085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
3095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
3105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1] |= (dwords - 3) << 16;
3115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
3125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
3135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian PaulGLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa,
3175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint vertex_format,
3185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint primitive,
3195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    GLuint min_nr )
3205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
321ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
3225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLushort *retval;
3235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
3255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr);
3265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
3285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonEmitState( rmesa );
3305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3316f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa,
3326f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt						       ELTS_BUFSZ(min_nr),
3336f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt						       __FUNCTION__ );
3345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
3375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM;
3385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = rmesa->ioctl.vertex_offset;
3395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = 0xffff;
3405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = vertex_format;
3415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (primitive |
3425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_PRIM_WALK_IND |
3435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
3445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
3455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   retval = (GLushort *)(cmd+6);
3475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
3485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP;
3505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX;
3515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = vertex_format;
3525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].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_MAOS_ENABLE |
3565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
3575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   retval = (GLushort *)(cmd+4);
3595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
3605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_PRIMS)
3625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n",
3635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
3645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      cmd[1].i, vertex_format, primitive);
3655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(!rmesa->dma.flush);
3675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
3685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.flush = radeonFlushElts;
3695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf;
3715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return retval;
3735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
3745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitVertexAOS( radeonContextPtr rmesa,
3785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  GLuint vertex_size,
3795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  GLuint offset )
3805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
3815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
3825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_size = vertex_size;
3835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_offset = offset;
3845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
385ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
3865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
3885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
3895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__, vertex_size, offset);
3905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3916f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VERT_AOS_BUFSZ,
3925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
3935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
3945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
3955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
3965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16);
3975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = 1;
3985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = vertex_size | (vertex_size << 8);
3995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = offset;
4005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
4015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
4025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitAOS( radeonContextPtr rmesa,
4055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    struct radeon_dma_region **component,
4065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    GLuint nr,
4075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    GLuint offset )
4085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
4095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#if RADEON_OLD_PACKETS
4105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( nr == 1 );
4115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( component[0]->aos_size == component[0]->aos_stride );
4125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_size = component[0]->aos_size;
4135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->ioctl.vertex_offset =
4145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (component[0]->aos_start + offset * component[0]->aos_stride * 4);
4155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#else
416ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
4175562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   int sz = AOS_BUFSZ(nr);
4185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int i;
4195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int *tmp;
4205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
4225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
4235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4256f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sz,
4265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
4275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
4285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
4296f3cc6a5226fd4b5d44cca91e2f76216ecaff831Eric Anholt   cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (((sz / sizeof(int))-3) << 16);
4305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = nr;
4315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   tmp = &cmd[0].i;
4325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd += 3;
4335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for (i = 0 ; i < nr ; i++) {
4355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (i & 1) {
4365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[0].i |= ((component[i]->aos_stride << 24) |
4375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		      (component[i]->aos_size << 16));
4385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[2].i = (component[i]->aos_start +
4395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     offset * component[i]->aos_stride * 4);
4405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd += 3;
4415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
4425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else {
4435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[0].i = ((component[i]->aos_stride << 8) |
4445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     (component[i]->aos_size << 0));
4455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 cmd[1].i = (component[i]->aos_start +
4465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		     offset * component[i]->aos_stride * 4);
4475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
4485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_VERTS) {
4515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s:\n", __FUNCTION__);
4525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for (i = 0 ; i < sz ; i++)
4535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "   %d: %x\n", i, tmp[i]);
4545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
4555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#endif
4565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
4575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* using already shifted color_fmt! */
4595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitBlit( radeonContextPtr rmesa, /* FIXME: which drmMinor is required? */
4605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint color_fmt,
4615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint src_pitch,
4625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint src_offset,
4635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint dst_pitch,
4645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint dst_offset,
4655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLint srcx, GLint srcy,
4665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLint dstx, GLint dsty,
4675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		   GLuint w, GLuint h )
4685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
469ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_header_t *cmd;
4705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
4725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
4735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      __FUNCTION__,
4745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      src_pitch, src_offset, srcx, srcy,
4755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      dst_pitch, dst_offset, dstx, dsty,
4765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      w, h);
4775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (src_pitch & 63) == 0 );
4795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (dst_pitch & 63) == 0 );
4805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (src_offset & 1023) == 0 );
4815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( (dst_offset & 1023) == 0 );
4825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( w < (1<<16) );
4835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert( h < (1<<16) );
4845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
485ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int),
4865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						  __FUNCTION__ );
4875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
4895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].i = 0;
4905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
4915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
4925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
4935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_DST_PITCH_OFFSET_CNTL |
4945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_BRUSH_NONE |
4955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       color_fmt |
4965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_SRC_DATATYPE_COLOR |
4975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_ROP3_S |
4985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_DP_SRC_SOURCE_MEMORY |
4995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_CLR_CMP_CNTL_DIS |
5005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       RADEON_GMC_WR_MSK_DIS );
5015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10);
5035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10);
5045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[5].i = (srcx << 16) | srcy;
5055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[6].i = (dstx << 16) | dsty; /* dst */
5065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd[7].i = (w << 16) | h;
5075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonEmitWait( radeonContextPtr rmesa, GLuint flags )
5115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dri.drmMinor >= 6) {
513ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_cmd_header_t *cmd;
5145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
5165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
517ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int),
5185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						   __FUNCTION__ );
5195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].i = 0;
5205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
5215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd[0].wait.flags = flags;
5225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
5275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				    const char * caller )
5285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret, i;
530ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_cmd_buffer_t cmd;
5315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5325562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   if (rmesa->lost_context)
5335562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt      radeonBackUpAndEmitLostStateLocked(rmesa);
5345562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt
5355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL) {
5365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
5375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_VERBOSE)
5395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 )
5405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    fprintf(stderr, "%d: %x\n", i/4,
5415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		    *(int *)(&rmesa->store.cmd_buf[i]));
5425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_DMA)
5455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__,
5465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->dma.nr_released_bufs);
5475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_SANITY) {
5505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->state.scissor.enabled)
5515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = radeonSanityCmdBuffer( rmesa,
5525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->state.scissor.numClipRects,
5535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->state.scissor.pClipRects);
5545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      else
5555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = radeonSanityCmdBuffer( rmesa,
5565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->numClipRects,
5575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				      rmesa->pClipRects);
5585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (ret) {
5595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "drmSanityCommandWrite: %d\n", ret);
5605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 goto out;
5615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
5625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd.bufsz = rmesa->store.cmd_used;
5665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cmd.buf = rmesa->store.cmd_buf;
5675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->state.scissor.enabled) {
5695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.nbox = rmesa->state.scissor.numClipRects;
570ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd.boxes = rmesa->state.scissor.pClipRects;
5715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } else {
5725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd.nbox = rmesa->numClipRects;
573ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd.boxes = rmesa->pClipRects;
5745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
5755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandWrite( rmesa->dri.fd,
5775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  DRM_RADEON_CMDBUF,
5785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			  &cmd, sizeof(cmd) );
5795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret)
5815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "drmCommandWrite: %d\n", ret);
5825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul out:
5845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.primnr = 0;
5855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.statenr = 0;
5865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->store.cmd_used = 0;
5875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.nr_released_bufs = 0;
5887a086dc05e665a78f7e9d069aa4fc70e844b8988Eric Anholt   rmesa->save_on_next_emit = 1;
589626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt
5905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return ret;
5915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
5925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
5945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Note: does not emit any commands to avoid recursion on
5955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * radeonAllocCmdBuf.
5965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
5975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller )
5985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
5995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
6005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
6035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = radeonFlushCmdBufLocked( rmesa, caller );
6055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
6075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret) {
609ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      fprintf(stderr, "drm_radeon_cmd_buffer_t: %d (exiting)\n", ret);
6105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(ret);
6115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* =============================================================
6155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Hardware vertex buffer handling
6165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
6175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonRefillCurrentDmaRegion( radeonContextPtr rmesa )
6205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   struct radeon_dma_buffer *dmabuf;
6225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int fd = rmesa->dri.fd;
6235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int index = 0;
6245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int size = 0;
6255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   drmDMAReq dma;
6265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
6275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
6295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
6305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush) {
6325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
6335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.current.buf)
6365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
6375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.nr_released_bufs > 4)
6395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
6405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.context = rmesa->dri.hwContext;
6425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_count = 0;
6435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_list = NULL;
6445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.send_sizes = NULL;
6455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.flags = 0;
6465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_count = 1;
6475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_size = RADEON_BUFFER_SIZE;
6485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_list = &index;
6495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.request_sizes = &size;
6505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dma.granted_count = 0;
6515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE(rmesa);	/* no need to validate */
6535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmDMA( fd, &dma );
6555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (ret != 0) {
6575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      /* Free some up this way?
6585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul       */
6595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->dma.nr_released_bufs) {
6605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
6615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
6625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_DMA)
6645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "Waiting for buffers\n");
6655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitForIdleLocked( rmesa );
6675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmDMA( fd, &dma );
6685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret != 0 ) {
6705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
6715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "Error: Could not get dma buffer... exiting\n" );
6725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( -1 );
6735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
6745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
6755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE(rmesa);
6775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_DMA)
6795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "Allocated buffer %d\n", index);
6805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf = CALLOC_STRUCT( radeon_dma_buffer );
6825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf->buf = &rmesa->radeonScreen->buffers->list[index];
6835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   dmabuf->refcount = 1;
6845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.buf = dmabuf;
6865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.address = dmabuf->buf->address;
6875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.end = dmabuf->buf->total;
6885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start = 0;
6895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.ptr = 0;
6905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->c_vertexBuffers++;
6925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
6935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
6945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonReleaseDmaRegion( radeonContextPtr rmesa,
6955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     struct radeon_dma_region *region,
6965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     const char *caller )
6975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
6985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
6995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
7005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (!region->buf)
7025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      return;
7035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
7055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
7065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (--region->buf->refcount == 0) {
708ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_cmd_header_t *cmd;
7095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
7115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__,
7125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul		 region->buf->buf->idx);
7135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
714ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sizeof(*cmd),
7155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul						     __FUNCTION__ );
7165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
7175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      cmd->dma.buf_idx = region->buf->buf->idx;
7185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      FREE(region->buf);
7195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.nr_released_bufs++;
7205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf = 0;
7235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->start = 0;
7245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Allocates a region from rmesa->dma.current.  If there isn't enough
7275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * space in current, grab a new buffer (and discard what was left of current)
7285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
7295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonAllocDmaRegion( radeonContextPtr rmesa,
7305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   struct radeon_dma_region *region,
7315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   int bytes,
7325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			   int alignment )
7335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
7355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
7365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
7385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
7395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (region->buf)
7415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonReleaseDmaRegion( rmesa, region, __FUNCTION__ );
7425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   alignment--;
7445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start = rmesa->dma.current.ptr =
7455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (rmesa->dma.current.ptr + alignment) & ~alignment;
7465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end )
7485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonRefillCurrentDmaRegion( rmesa );
7495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->start = rmesa->dma.current.start;
7515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->ptr = rmesa->dma.current.start;
7525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->end = rmesa->dma.current.start + bytes;
7535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->address = rmesa->dma.current.address;
7545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf = rmesa->dma.current.buf;
7555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   region->buf->refcount++;
7565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
7585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->dma.current.start =
7595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
7605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
7635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				struct radeon_dma_region *region,
7645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int numverts,
7655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int vertsize,
7665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				int alignment )
7675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonAllocDmaRegion( rmesa, region, vertsize * numverts, alignment );
7695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
7705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* ================================================================
7725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * SwapBuffers with client-side throttling
7735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
7745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7756af3dca18a2315ea431b5ea868913093d2111491Ian Romanickstatic uint32_t radeonGetLastFrame (radeonContextPtr rmesa)
7765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
7775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
7785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
7796af3dca18a2315ea431b5ea868913093d2111491Ian Romanick   uint32_t frame;
7805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dri.screen->drmMinor >= 4) {
782ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_getparam_t gp;
7835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      gp.param = RADEON_PARAM_LAST_FRAME;
785bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      gp.value = (int *)&frame;
7865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
7875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				 &gp, sizeof(gp) );
7885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else
7905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = -EINVAL;
7915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
7925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret == -EINVAL ) {
7935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      frame = INREG( RADEON_LAST_FRAME_REG );
7945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = 0;
7955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
7965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
797ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
7985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
7995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   return frame;
8025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonEmitIrqLocked( radeonContextPtr rmesa )
8055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
806ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_irq_emit_t ie;
8075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
8085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ie.irq_seq = &rmesa->iw.irq_seq;
8105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_IRQ_EMIT,
8115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			      &ie, sizeof(ie) );
8125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
813ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      fprintf( stderr, "%s: drm_radeon_irq_emit_t: %d\n", __FUNCTION__, ret );
8145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
8155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitIrq( radeonContextPtr rmesa )
8205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
8215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   int ret;
8225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   do {
8245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_IRQ_WAIT,
8255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			     &rmesa->iw, sizeof(rmesa->iw) );
8265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } while (ret && (errno == EINTR || errno == EAGAIN));
8275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
8295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
8305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit(1);
8315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
8365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
837ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_sarea_t *sarea = rmesa->sarea;
8385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->do_irqs) {
8405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (radeonGetLastFrame(rmesa) < sarea->last_frame) {
8415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (!rmesa->irqsEmitted) {
8425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    while (radeonGetLastFrame (rmesa) < sarea->last_frame)
8435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       ;
8445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
8455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 else {
8465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    UNLOCK_HARDWARE( rmesa );
8475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    radeonWaitIrq( rmesa );
8485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    LOCK_HARDWARE( rmesa );
8495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
8505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->irqsEmitted = 10;
8515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->irqsEmitted) {
8545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 radeonEmitIrqLocked( rmesa );
8555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->irqsEmitted--;
8565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else {
8595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      while (radeonGetLastFrame (rmesa) < sarea->last_frame) {
8605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
8615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if (rmesa->do_usleeps)
8625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    DO_USLEEP( 1 );
8635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 LOCK_HARDWARE( rmesa );
8645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
8655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
8675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Copy the back color buffer to the front color buffer.
8695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
8705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
8715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
8725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa;
8735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint nbox, i, ret;
8745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLboolean   missed_target;
875ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   int64_t ust;
8765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv);
8785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv);
8795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv->driverPrivate);
8805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
8825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
884894844a8d956a0ee5f95836331dc318f49fdb845Brian Paul      fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
8855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
8865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
8885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
8895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the frame rate -- only allow one pending swap buffers
8915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * request at a time.
8925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
8935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForFrameCompletion( rmesa );
8945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
8955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
8965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
8975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
8985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   nbox = dPriv->numClipRects; /* must be in locked region */
8995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for ( i = 0 ; i < nbox ; ) {
9015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
902ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *box = dPriv->pClipRects;
903ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *b = rmesa->sarea->boxes;
9045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint n = 0;
9055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for ( ; i < nr ; i++ ) {
9075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 *b++ = box[i];
9085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 n++;
9095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
9105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = n;
9115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
9135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
9155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret );
9165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
9175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( 1 );
9185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
9195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_count++;
9235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   (*rmesa->get_ust)( & ust );
9245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( missed_target ) {
9255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_count++;
9265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_ust = ust - rmesa->swap_ust;
9275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_ust = ust;
9305562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.all_dirty = GL_TRUE;
9315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
9325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonPageFlip( const __DRIdrawablePrivate *dPriv )
9345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
9355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa;
9365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint ret;
9375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLboolean   missed_target;
9385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv);
9405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv);
9415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   assert(dPriv->driContextPriv->driverPrivate);
9425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
9445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
9465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
9475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	      rmesa->sarea->pfCurrentPage);
9485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_FIREVERTICES( rmesa );
9515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Need to do this for the perf box placement:
9545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
9555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (dPriv->numClipRects)
9565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   {
957ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *box = dPriv->pClipRects;
958ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *b = rmesa->sarea->boxes;
9595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      b[0] = box[0];
9605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = 1;
9615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the frame rate -- only allow a few pending swap buffers
9645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    * request at a time.
9655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
9665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForFrameCompletion( rmesa );
9675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
9695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( missed_target ) {
9705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->swap_missed_count++;
9715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      (void) (*rmesa->get_ust)( & rmesa->swap_missed_ust );
9725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9735df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
9745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
9765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
9785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( ret ) {
9805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
9815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      exit( 1 );
9825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->swap_count++;
9855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   (void) (*rmesa->get_ust)( & rmesa->swap_ust );
9865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( rmesa->sarea->pfCurrentPage == 1 ) {
9885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
9895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawPitch  = rmesa->radeonScreen->frontPitch;
9905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   } else {
9915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
9925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 rmesa->state.color.drawPitch  = rmesa->radeonScreen->backPitch;
9935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
9945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
9955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   RADEON_STATECHANGE( rmesa, ctx );
99699ef0a03292e7dc6aa2465aaaa620f394d2c286bAlan Hourihane   rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
99799ef0a03292e7dc6aa2465aaaa620f394d2c286bAlan Hourihane					   + rmesa->radeonScreen->fbLocation;
9985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
9995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
10005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* ================================================================
10035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * Buffer clear
10045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
10055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul#define RADEON_MAX_CLEARS	256
10065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
10085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul			 GLint cx, GLint cy, GLint cw, GLint ch )
10095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
10105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
10115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
1012ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl   drm_radeon_sarea_t *sarea = rmesa->sarea;
10135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
10146af3dca18a2315ea431b5ea868913093d2111491Ian Romanick   uint32_t clear;
10155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLuint flags = 0;
10165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLuint color_mask = 0;
10175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   GLint ret, i;
10185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
10205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf( stderr, "%s:  all=%d cx=%d cy=%d cw=%d ch=%d\n",
10215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	       __FUNCTION__, all, cx, cy, cw, ch );
10225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10248e3926575264d31b3caacb9cbb606f8f2914f57dRoland Scheidegger   radeonFlush( ctx );
10255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask & DD_FRONT_LEFT_BIT ) {
10275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_FRONT;
10285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
10295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_FRONT_LEFT_BIT;
10305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask & DD_BACK_LEFT_BIT ) {
10335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_BACK;
10345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
10355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_BACK_LEFT_BIT;
10365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask & DD_DEPTH_BIT ) {
10395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ctx->Depth.Mask ) flags |= RADEON_DEPTH; /* FIXME: ??? */
10405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_DEPTH_BIT;
10415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) {
10445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      flags |= RADEON_STENCIL;
10455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      mask &= ~DD_STENCIL_BIT;
10465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( mask ) {
10495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (RADEON_DEBUG & DEBUG_FALLBACKS)
10505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
10515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
10525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
10535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10545df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if ( !flags )
10555df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      return;
10565df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10575df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10585df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Flip top to bottom */
10595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cx += dPriv->x;
10605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   cy  = dPriv->y + dPriv->h - cy - ch;
10615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE( rmesa );
10635df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   /* Throttle the number of clear ioctls we do.
10655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    */
10665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   while ( 1 ) {
10675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      int ret;
10685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if (rmesa->dri.screen->drmMinor >= 4) {
1070ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	drm_radeon_getparam_t gp;
10715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	gp.param = RADEON_PARAM_LAST_CLEAR;
1073bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl	gp.value = (int *)&clear;
10745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	ret = drmCommandWriteRead( rmesa->dri.fd,
10755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul				   DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
10765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      } else
10775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	ret = -EINVAL;
10785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret == -EINVAL ) {
10805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 clear = INREG( RADEON_LAST_CLEAR_REG );
10815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 ret = 0;
10825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
1084ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
10855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit(1);
10865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( RADEON_DEBUG & DEBUG_IOCTL ) {
10885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "%s( %d )\n", __FUNCTION__, (int)clear );
10895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 if ( ret ) fprintf( stderr, " ( RADEON_LAST_CLEAR register read directly )\n" );
10905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
10935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 break;
10945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
10955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
10965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( rmesa->do_usleeps ) {
10975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
10985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 DO_USLEEP( 1 );
10995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 LOCK_HARDWARE( rmesa );
11005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
11025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1103626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt   /* Send current state to the hardware */
1104626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt   radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
1105626f825bcc91a3068e2e1c68e7467b42826c51eaEric Anholt
11065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   for ( i = 0 ; i < dPriv->numClipRects ; ) {
11075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
1108ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *box = dPriv->pClipRects;
1109ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_clip_rect_t *b = rmesa->sarea->boxes;
1110ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_clear_t clear;
1111ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl      drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
11125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      GLint n = 0;
11135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( !all ) {
11155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for ( ; i < nr ; i++ ) {
11165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint x = box[i].x1;
11175df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint y = box[i].y1;
11185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint w = box[i].x2 - x;
11195df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    GLint h = box[i].y2 - y;
11205df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( x < cx ) w -= cx - x, x = cx;
11225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( y < cy ) h -= cy - y, y = cy;
11235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( x + w > cx + cw ) w = cx + cw - x;
11245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( y + h > cy + ch ) h = cy + ch - y;
11255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( w <= 0 ) continue;
11265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    if ( h <= 0 ) continue;
11275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->x1 = x;
11295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->y1 = y;
11305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->x2 = x + w;
11315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b->y2 = y + h;
11325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    b++;
11335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    n++;
11345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
11355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      } else {
11365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 for ( ; i < nr ; i++ ) {
11375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    *b++ = box[i];
11385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    n++;
11395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 }
11405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->sarea->nbox = n;
11435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.flags       = flags;
11455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.clear_color = rmesa->state.color.clear;
11465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.clear_depth = rmesa->state.depth.clear;
11475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
11485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.depth_mask  = rmesa->state.stencil.clear;
11495df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      clear.depth_boxes = depth_boxes;
11505df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11515df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      n--;
11525df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      b = rmesa->sarea->boxes;
11535df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      for ( ; n >= 0 ; n-- ) {
1154ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1;
1155ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1;
1156ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2;
1157ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2;
1158ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl	 depth_boxes[n].f[CLEAR_DEPTH] =
11595df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	    (float)rmesa->state.depth.clear;
11605df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11615df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11625df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR,
1163ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0Jon Smirl			     &clear, sizeof(drm_radeon_clear_t));
11645df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11655df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      if ( ret ) {
11665df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 UNLOCK_HARDWARE( rmesa );
11675df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
11685df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	 exit( 1 );
11695df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      }
11705df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
11715df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11725df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE( rmesa );
11735562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   rmesa->hw.all_dirty = GL_TRUE;
11745df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11755df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11765df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11775df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonWaitForIdleLocked( radeonContextPtr rmesa )
11785df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
11795df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int fd = rmesa->dri.fd;
11805df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int to = 0;
11815df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    int ret, i = 0;
11825df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11835df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    rmesa->c_drawWaits++;
11845df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11855df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    do {
11865df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul        do {
11875df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul            ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE);
11885df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul        } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY );
11895df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) );
11905df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11915df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    if ( ret < 0 ) {
11925df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	UNLOCK_HARDWARE( rmesa );
11935df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	fprintf( stderr, "Error: Radeon timed out... exiting\n" );
11945df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul	exit( -1 );
11955df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    }
11965df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
11975df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11985df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
11995df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulstatic void radeonWaitForIdle( radeonContextPtr rmesa )
12005df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12015df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   LOCK_HARDWARE(rmesa);
12025df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonWaitForIdleLocked( rmesa );
12035df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   UNLOCK_HARDWARE(rmesa);
12045df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12055df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12065df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12075df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFlush( GLcontext *ctx )
12085df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12095df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
12105df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12115df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (RADEON_DEBUG & DEBUG_IOCTL)
12125df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      fprintf(stderr, "%s\n", __FUNCTION__);
12135df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12145df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->dma.flush)
12155df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      rmesa->dma.flush( rmesa );
12165df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12175562fe653cf88454bbf2c50f77a8b56b0dafe01bEric Anholt   radeonEmitState( rmesa );
12185df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1219bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl   if (rmesa->store.cmd_used)
1220bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl      radeonFlushCmdBuf( rmesa, __FUNCTION__ );
12215df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12225df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12235df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul/* Make sure all commands have been sent to the hardware and have
12245df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul * completed processing.
12255df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul */
12265df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonFinish( GLcontext *ctx )
12275df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12285df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
12295df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   radeonFlush( ctx );
12305df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12315df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   if (rmesa->do_irqs) {
12325df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      LOCK_HARDWARE( rmesa );
12335df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonEmitIrqLocked( rmesa );
12345df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      UNLOCK_HARDWARE( rmesa );
12355df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitIrq( rmesa );
12365df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   }
12375df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul   else
12385df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul      radeonWaitForIdle( rmesa );
12395df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12405df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12415df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
12425df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paulvoid radeonInitIoctlFuncs( GLcontext *ctx )
12435df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul{
12445df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Clear = radeonClear;
12455df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Finish = radeonFinish;
12465df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul    ctx->Driver.Flush = radeonFlush;
12475df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul}
12485df82c82bd53db90eb72c5aad4dd20cf6f1116b1Brian Paul
1249