* Gareth Hughes <gareth@valinux.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
+
#include <sched.h>
-#include <errno.h>
+#include <errno.h>
#include "glheader.h"
#include "imports.h"
{
struct radeon_state_atom *state, *tmp;
char *dest;
-
- /* From Felix Kuhling: similar to some other lockups, glaxium will
- * lock with what we believe to be a normal command stream, but
- * sprinkling some magic waits arounds allows it to run
- * uninterrupted. This has a slight effect on q3 framerates, but
- * it might now be possible to remove the zbs hack, below.
- *
- * Felix reports that this can be narrowed down to just
- * tcl,tex0,tex1 state, but that's pretty much every statechange,
- * so let's just put the wait in always (unless Felix wants to
- * narrow it down further...)
+ int i, size, texunits;
+
+ /* It appears that some permutations of state atoms lock up the
+ * chip. Therefore we make sure that state atoms are emitted in a
+ * fixed order. First mark all dirty state atoms and then go
+ * through all state atoms in a well defined order and emit only
+ * the marked ones.
+ * FIXME: This requires knowledge of which state atoms exist.
+ * FIXME: Is the zbs hack below still needed?
*/
- if (1) {
- drmRadeonCmdHeader *cmd;
- cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd),
- __FUNCTION__ );
- cmd->wait.cmd_type = RADEON_CMD_WAIT;
- cmd->wait.flags = RADEON_WAIT_3D;
- }
-
+ size = 0;
foreach_s( state, tmp, list ) {
if (state->check( rmesa->glCtx )) {
- dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
- memcpy( dest, state->cmd, state->cmd_size * 4);
+ size += state->cmd_size;
+ state->dirty = GL_TRUE;
move_to_head( &(rmesa->hw.clean), state );
if (RADEON_DEBUG & DEBUG_STATE)
print_state_atom( state );
else if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "skip state %s\n", state->name);
}
+ /* short cut */
+ if (!size)
+ return;
+
+ dest = radeonAllocCmdBuf( rmesa, size * 4, __FUNCTION__);
+ texunits = rmesa->glCtx->Const.MaxTextureUnits;
+
+#define EMIT_ATOM(ATOM) \
+do { \
+ if (rmesa->hw.ATOM.dirty) { \
+ rmesa->hw.ATOM.dirty = GL_FALSE; \
+ memcpy( dest, rmesa->hw.ATOM.cmd, rmesa->hw.ATOM.cmd_size * 4); \
+ dest += rmesa->hw.ATOM.cmd_size * 4; \
+ } \
+} while (0)
+
+ EMIT_ATOM (ctx);
+ EMIT_ATOM (set);
+ EMIT_ATOM (lin);
+ EMIT_ATOM (msk);
+ EMIT_ATOM (vpt);
+ EMIT_ATOM (tcl);
+ EMIT_ATOM (msc);
+ for (i = 0; i < texunits; ++i) {
+ EMIT_ATOM (tex[i]);
+ EMIT_ATOM (txr[i]);
+ }
+ EMIT_ATOM (zbs);
+ EMIT_ATOM (mtl);
+ for (i = 0; i < 3 + texunits; ++i)
+ EMIT_ATOM (mat[i]);
+ for (i = 0; i < 8; ++i)
+ EMIT_ATOM (lit[i]);
+ for (i = 0; i < 6; ++i)
+ EMIT_ATOM (ucp[i]);
+ EMIT_ATOM (eye);
+ EMIT_ATOM (grd);
+ EMIT_ATOM (fog);
+ EMIT_ATOM (glt);
+
+#undef EMIT_ATOM
}
drmRadeonCmdHeader *cmd;
- assert(rmesa->dri.drmMinor >= 3);
assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
radeonEmitState( rmesa );
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr);
- assert(rmesa->dri.drmMinor >= 3);
assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
radeonEmitState( rmesa );
rmesa->ioctl.vertex_offset = offset;
#else
drmRadeonCmdHeader *cmd;
- assert(rmesa->dri.drmMinor >= 3);
if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
- assert(rmesa->dri.drmMinor >= 3);
cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sz * sizeof(int),
__FUNCTION__ );
int ret;
- assert (rmesa->dri.drmMinor >= 3);
-
LOCK_HARDWARE( rmesa );
ret = radeonFlushCmdBufLocked( rmesa, caller );
rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
rmesa->dma.current.start =
rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
-
- if ( rmesa->dri.drmMinor < 3 )
- radeonRefillCurrentDmaRegion( rmesa );
}
void radeonAllocDmaRegionVerts( radeonContextPtr rmesa,
drmRadeonGetParam gp;
gp.param = RADEON_PARAM_LAST_FRAME;
- gp.value = &frame;
+ gp.value = (int *)&frame;
ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
&gp, sizeof(gp) );
}
radeonContextPtr rmesa;
GLint nbox, i, ret;
GLboolean missed_target;
- uint64_t ust;
+ uint64_t ust;
assert(dPriv);
assert(dPriv->driContextPriv);
}
RADEON_STATECHANGE( rmesa, ctx );
- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset;
+ rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
+ + rmesa->radeonScreen->fbLocation;
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
}
drmRadeonGetParam gp;
gp.param = RADEON_PARAM_LAST_CLEAR;
- gp.value = &clear;
+ gp.value = (int *)&clear;
ret = drmCommandWriteRead( rmesa->dri.fd,
DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
} else
if (rmesa->dma.flush)
rmesa->dma.flush( rmesa );
- if (rmesa->dri.drmMinor >= 3) {
- if (!is_empty_list(&rmesa->hw.dirty))
- radeonEmitState( rmesa );
+ if (!is_empty_list(&rmesa->hw.dirty))
+ radeonEmitState( rmesa );
- if (rmesa->store.cmd_used)
- radeonFlushCmdBuf( rmesa, __FUNCTION__ );
- }
+ if (rmesa->store.cmd_used)
+ radeonFlushCmdBuf( rmesa, __FUNCTION__ );
}
/* Make sure all commands have been sent to the hardware and have