#include "swrast/swrast.h"
#include "radeon_context.h"
-#include "common_cmdbuf.h"
-#include "radeon_cs.h"
+#include "radeon_common.h"
#include "radeon_state.h"
#include "radeon_ioctl.h"
#include "radeon_tcl.h"
#define RADEON_TIMEOUT 512
#define RADEON_IDLE_RETRY 16
-#define DEBUG_CMDBUF 1
-
-static void radeonSaveHwState( r100ContextPtr rmesa )
-{
- struct radeon_state_atom *atom;
- char * dest = rmesa->backup_store.cmd_buf;
-
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- rmesa->backup_store.cmd_used = 0;
-
- foreach( atom, &rmesa->hw.atomlist ) {
- if ( atom->check( rmesa->radeon.glCtx, 0 ) ) {
- int size = atom->cmd_size * 4;
- memcpy( dest, atom->cmd, size);
- dest += size;
- rmesa->backup_store.cmd_used += size;
- if (RADEON_DEBUG & DEBUG_STATE)
- radeon_print_state_atom( atom );
- }
- }
-
- assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ );
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Returning to radeonEmitState\n");
-}
-
-/* At this point we were in FlushCmdBufLocked but we had lost our context, so
- * we need to unwire our current cmdbuf, hook the one with the saved state in
- * it, flush it, and then put the current one back. This is so commands at the
- * start of a cmdbuf can rely on the state being kept from the previous one.
- */
-static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa )
-{
- GLuint nr_released_bufs;
- struct radeon_store saved_store;
-
- if (rmesa->backup_store.cmd_used == 0)
- return;
-
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Emitting backup state on lost context\n");
-
- rmesa->radeon.lost_context = GL_FALSE;
-
- nr_released_bufs = rmesa->radeon.dma.nr_released_bufs;
- saved_store = rmesa->store;
- rmesa->radeon.dma.nr_released_bufs = 0;
- rmesa->store = rmesa->backup_store;
- rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ );
- rmesa->radeon.dma.nr_released_bufs = nr_released_bufs;
- rmesa->store = saved_store;
-}
/* =============================================================
* Kernel command buffer handling
{
int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits;
- make_empty_list(&rmesa->hw.atomlist);
- rmesa->hw.atomlist.name = "atom-list";
+ make_empty_list(&rmesa->radeon.hw.atomlist);
+ rmesa->radeon.hw.atomlist.name = "atom-list";
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
for (i = 0; i < mtu; ++i) {
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.cube[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
}
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
for (i = 0; i < 3 + mtu; ++i)
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
for (i = 0; i < 8; ++i)
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
for (i = 0; i < 6; ++i)
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog);
- insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt);
-}
-
-static INLINE void radeonEmitAtoms(r100ContextPtr r100, GLboolean dirty)
-{
- BATCH_LOCALS(&r100->radeon);
- struct radeon_state_atom *atom;
- int dwords;
-
- /* Emit actual atoms */
- foreach(atom, &r100->hw.atomlist) {
- if ((atom->dirty || r100->hw.all_dirty) == dirty) {
- dwords = (*atom->check) (r100->radeon.glCtx, atom);
- if (dwords) {
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- radeon_print_state_atom(atom);
- }
- if (atom->emit) {
- (*atom->emit)(r100->radeon.glCtx, atom);
- } else {
- BEGIN_BATCH_NO_AUTOSTATE(dwords);
- OUT_BATCH_TABLE(atom->cmd, dwords);
- END_BATCH();
- }
- atom->dirty = GL_FALSE;
- } else {
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- fprintf(stderr, " skip state %s\n",
- atom->name);
- }
- }
- }
- }
-
- COMMIT_BATCH();
-}
-
-void radeonEmitState( r100ContextPtr rmesa )
-{
- if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->save_on_next_emit) {
- radeonSaveHwState(rmesa);
- rmesa->save_on_next_emit = GL_FALSE;
- }
-
- if (rmesa->radeon.cmdbuf.cs->cdw)
- return;
-
- /* this code used to return here but now it emits zbs */
-
- /* To avoid going across the entire set of states multiple times, just check
- * for enough space for the case of emitting all state, and inline the
- * radeonAllocCmdBuf code here without all the checks.
- */
- rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->hw.max_state_size, __FUNCTION__);
-
- /* We always always emit zbs, this is due to a bug found by keithw in
- the hardware and rediscovered after Erics changes by me.
- if you ever touch this code make sure you emit zbs otherwise
- you get tcl lockups on at least M7/7500 class of chips - airlied */
- rmesa->hw.zbs.dirty=1;
-
- if (!rmesa->radeon.cmdbuf.cs->cdw) {
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Begin reemit state\n");
-
- radeonEmitAtoms(rmesa, GL_FALSE);
- }
-
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Begin dirty state\n");
-
- radeonEmitAtoms(rmesa, GL_TRUE);
- rmesa->hw.is_dirty = GL_FALSE;
- rmesa->hw.all_dirty = GL_FALSE;
-
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
}
/* Fire a section of the retained (indexed_verts) buffer as a regular
assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
- radeonEmitState( rmesa );
-
- // if (RADEON_DEBUG & DEBUG_IOCTL)
- // fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__,
- // rmesa->store.cmd_used/4);
-
+ radeonEmitState(&rmesa->radeon);
#if RADEON_OLD_PACKETS
- BEGIN_BATCH(6);
+ BEGIN_BATCH(8);
OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
OUT_BATCH(vertex_nr);
#endif
}
-static void radeonFireEB(r100ContextPtr rmesa, int vertex_count, int vertex_format, int type)
-{
- BATCH_LOCALS(&rmesa->radeon);
-
- if (vertex_count > 0) {
- BEGIN_BATCH(8);
- OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_DRAW_INDX, 0);
- OUT_BATCH(vertex_format);
- OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_IND |
- ((vertex_count + 0) << 16) |
- type);
-
- assert(0); // RADEON HAS NO INDX_BUFFERs
-#if 0
-
-
- if (!rmesa->radeon.radeonScreen->kernel_mm) {
- OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2);
- OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810);
- OUT_BATCH_RELOC(rmesa->tcl.elt_dma_offset,
- rmesa->tcl.elt_dma_bo,
- rmesa->tcl.elt_dma_offset,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
- OUT_BATCH(vertex_count/2);
- } else {
- OUT_BATCH_PACKET3(R200_CP_CMD_INDX_BUFFER, 2);
- OUT_BATCH((0x80 << 24) | (0 << 16) | 0x810);
- OUT_BATCH(rmesa->tcl.elt_dma_offset);
- OUT_BATCH(vertex_count/2);
- radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
- rmesa->tcl.elt_dma_bo,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
- }
-#endif
- END_BATCH();
- }
-}
-
void radeonFlushElts( GLcontext *ctx )
{
- r100ContextPtr rmesa = R100_CONTEXT(ctx);
- BATCH_LOCALS(&rmesa->radeon);
- int dwords;
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
+ BATCH_LOCALS(&rmesa->radeon);
+ int nr;
uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
- int nr = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw) * 2;
+ int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert( rmesa->radeon.dma.flush == radeonFlushElts );
rmesa->radeon.dma.flush = NULL;
-
- /* Cope with odd number of elts:
- */
- // rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2;
- // dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4;
- dwords = nr / 2;
+ nr = rmesa->tcl.elt_used;
rmesa->radeon.cmdbuf.cs->cdw += dwords;
cmd[1] |= (dwords + 3) << 16;
cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
#else
- cmd[1] |= (dwords) << 16;
+ cmd[1] |= (dwords + 2) << 16;
cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
#endif
- fprintf(stderr,"nr is %d cmd1 is %08x\n", nr, cmd[1]);
-
rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
END_BATCH();
GLuint min_nr )
{
GLushort *retval;
+ int align_min_nr;
BATCH_LOCALS(&rmesa->radeon);
+
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
- radeonEmitState( rmesa );
+ radeonEmitState(&rmesa->radeon);
rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
+ /* round up min_nr to align the state */
+ align_min_nr = (min_nr + 1) & ~1;
+
#if RADEON_OLD_PACKETS
- BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(min_nr)/4);
+ BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
OUT_BATCH(0xffff);
RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
#else
- BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(min_nr)/4);
+ BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4);
OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0);
OUT_BATCH(vertex_format);
OUT_BATCH(primitive |
rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw;
- rmesa->tcl.elt_used = min_nr * 2;
+ rmesa->tcl.elt_used = min_nr;
retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
- fprintf(stderr," %d elt start %d offset %d\n", min_nr, rmesa->tcl.elt_cmd_start, rmesa->tcl.elt_cmd_offset);
-
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s: header prim %x \n",
__FUNCTION__, primitive);
{
#if RADEON_OLD_PACKETS
assert( nr == 1 );
- // assert( rmesa->radeon.aos[0]->aos_size == component[0]->aos_stride );
- // rmesa->ioctl.vertex_offset =
- // (component[0]->aos_start + offset * component[0]->aos_stride * 4);
rmesa->ioctl.bo = rmesa->tcl.aos[0].bo;
rmesa->ioctl.vertex_offset =
(rmesa->tcl.aos[0].offset + offset * rmesa->tcl.aos[0].stride * 4);
#endif
}
-
-#if 0
-/* using already shifted color_fmt! */
-void radeonEmitBlit( r100ContextPtr rmesa, /* FIXME: which drmMinor is required? */
- GLuint color_fmt,
- GLuint src_pitch,
- GLuint src_offset,
- GLuint dst_pitch,
- GLuint dst_offset,
- GLint srcx, GLint srcy,
- GLint dstx, GLint dsty,
- GLuint w, GLuint h )
-{
- drm_radeon_cmd_header_t *cmd;
-
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n",
- __FUNCTION__,
- src_pitch, src_offset, srcx, srcy,
- dst_pitch, dst_offset, dstx, dsty,
- w, h);
-
- assert( (src_pitch & 63) == 0 );
- assert( (dst_pitch & 63) == 0 );
- assert( (src_offset & 1023) == 0 );
- assert( (dst_offset & 1023) == 0 );
- assert( w < (1<<16) );
- assert( h < (1<<16) );
-
- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int),
- __FUNCTION__ );
-
-
- cmd[0].i = 0;
- cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
- cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
- cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- color_fmt |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_S |
- RADEON_DP_SRC_SOURCE_MEMORY |
- RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS );
-
- cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10);
- cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10);
- cmd[5].i = (srcx << 16) | srcy;
- cmd[6].i = (dstx << 16) | dsty; /* dst */
- cmd[7].i = (w << 16) | h;
-}
-
-
-void radeonEmitWait( r100ContextPtr rmesa, GLuint flags )
-{
- drm_radeon_cmd_header_t *cmd;
-
- assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) );
-
- cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int),
- __FUNCTION__ );
- cmd[0].i = 0;
- cmd[0].wait.cmd_type = RADEON_CMD_WAIT;
- cmd[0].wait.flags = flags;
-}
-#endif
-
/* ================================================================
* Buffer clear
*/
}
UNLOCK_HARDWARE( &rmesa->radeon );
- rmesa->hw.all_dirty = GL_TRUE;
-}
-
-void radeonFlush( GLcontext *ctx )
-{
- r100ContextPtr rmesa = R100_CONTEXT( ctx );
-
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->radeon.dma.flush)
- rmesa->radeon.dma.flush( ctx );
-
- radeonEmitState( rmesa );
-
- if (rmesa->radeon.cmdbuf.cs->cdw)
- rcommonFlushCmdBuf( &rmesa->radeon, __FUNCTION__ );
+ rmesa->radeon.hw.all_dirty = GL_TRUE;
}
-/* Make sure all commands have been sent to the hardware and have
- * completed processing.
- */
-void radeonFinish( GLcontext *ctx )
-{
- radeonFlush( ctx );
- radeon_common_finish(ctx);
-}
-
-
void radeonInitIoctlFuncs( GLcontext *ctx )
{
ctx->Driver.Clear = radeonClear;