-static void r300PrintStateAtom(r300ContextPtr r300,
- struct radeon_state_atom *state)
-{
- int i;
- int dwords = (*state->check) (r300->radeon.glCtx, state);
-
- fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
-
- if (RADEON_DEBUG & DEBUG_VERBOSE) {
- for (i = 0; i < dwords; i++) {
- fprintf(stderr, " %s[%d]: %08x\n",
- state->name, i, state->cmd[i]);
- }
- }
-}
-
-/**
- * Emit all atoms with a dirty field equal to dirty.
- *
- * The caller must have ensured that there is enough space in the command
- * buffer.
- */
-static INLINE void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
-{
- BATCH_LOCALS(&r300->radeon);
- struct radeon_state_atom *atom;
- int dwords;
-
- cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
- BEGIN_BATCH_NO_AUTOSTATE(2);
- OUT_BATCH(cmdpacket0(r300->radeon.radeonScreen, R300_TX_INVALTAGS, 1));
- OUT_BATCH(R300_TX_FLUSH);
- END_BATCH();
- end_3d(r300);
-
- /* Emit actual atoms */
- foreach(atom, &r300->hw.atomlist) {
- if ((atom->dirty || r300->hw.all_dirty) == dirty) {
- dwords = (*atom->check) (r300->radeon.glCtx, atom);
- if (dwords) {
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- r300PrintStateAtom(r300, atom);
- }
- if (atom->emit) {
- (*atom->emit)(r300->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();
-}
-
-/**
- * Copy dirty hardware state atoms into the command buffer.
- *
- * We also copy out clean state if we're at the start of a buffer. That makes
- * it easy to recover from lost contexts.
- */
-void r300EmitState(r300ContextPtr r300)
-{
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS))
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (r300->radeon.cmdbuf.cs->cdw && !r300->hw.is_dirty && !r300->hw.all_dirty)
- return;
-
- /* To avoid going across the entire set of states multiple times, just check
- * for enough space for the case of emitting all state.
- */
- rcommonEnsureCmdBufSpace(&r300->radeon, r300->hw.max_state_size, __FUNCTION__);
-
- if (!r300->radeon.cmdbuf.cs->cdw) {
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Begin reemit state\n");
-
- r300EmitAtoms(r300, GL_FALSE);
- }
-
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Begin dirty state\n");
-
- r300EmitAtoms(r300, GL_TRUE);
- r300->hw.is_dirty = GL_FALSE;
- r300->hw.all_dirty = GL_FALSE;
-}
-