summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon/radeon_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c137
1 files changed, 90 insertions, 47 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index b5b4fed8fa..9f901d2c0a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -895,7 +895,7 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he
ctx->Driver.Viewport = old_viewport;
}
-static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state)
+static void radeon_print_state_atom_prekmm(radeonContextPtr radeon, struct radeon_state_atom *state)
{
int i, j, reg;
int dwords = (*state->check) (radeon->glCtx, state);
@@ -904,6 +904,9 @@ static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state
fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
if (RADEON_DEBUG & DEBUG_VERBOSE) {
+ if (dwords > state->cmd_size)
+ dwords = state->cmd_size;
+
for (i = 0; i < dwords;) {
cmd = *((drm_r300_cmd_header_t *) &state->cmd[i]);
reg = (cmd.packet0.reghi << 8) | cmd.packet0.reglo;
@@ -920,16 +923,27 @@ static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state
}
}
-static void radeon_print_state_atom_kmm(radeonContextPtr radeon, struct radeon_state_atom *state)
+static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state)
{
int i, j, reg, count;
- int dwords = (*state->check) (radeon->glCtx, state);
+ int dwords;
uint32_t packet0;
+ if (! (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) )
+ return;
+
+ if (!radeon->radeonScreen->kernel_mm) {
+ radeon_print_state_atom_prekmm(radeon, state);
+ return;
+ }
+
+ dwords = (*state->check) (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;) {
+ if (dwords > state->cmd_size)
+ dwords = state->cmd_size;
+ for (i = 0; i < state->cmd_size;) {
packet0 = state->cmd[i];
reg = (packet0 & 0x1FFF) << 2;
count = ((packet0 & 0x3FFF0000) >> 16) + 1;
@@ -946,40 +960,71 @@ static void radeon_print_state_atom_kmm(radeonContextPtr radeon, struct radeon_s
}
}
-static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty)
+/**
+ * Count total size for next state emit.
+ **/
+GLuint radeonCountStateEmitSize(radeonContextPtr radeon)
{
- BATCH_LOCALS(radeon);
struct radeon_state_atom *atom;
+ int dwords = 0;
+ /* check if we are going to emit full state */
+ if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) {
+ if (!radeon->hw.is_dirty)
+ return dwords;
+ foreach(atom, &radeon->hw.atomlist) {
+ if (atom->dirty)
+ dwords += atom->check(radeon->glCtx, atom);
+ }
+ } else {
+ foreach(atom, &radeon->hw.atomlist) {
+ dwords += atom->check(radeon->glCtx, atom);
+ }
+ }
+ return dwords;
+}
+
+static INLINE void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state_atom *atom)
+{
+ BATCH_LOCALS(radeon);
int dwords;
+ dwords = (*atom->check) (radeon->glCtx, atom);
+ if (dwords) {
+
+ radeon_print_state_atom(radeon, atom);
+
+ if (atom->emit) {
+ (*atom->emit)(radeon->glCtx, atom);
+ } else {
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(atom->cmd, dwords);
+ END_BATCH();
+ }
+ } else {
+ if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
+ fprintf(stderr, " skip state %s\n",
+ atom->name);
+ }
+ }
+ atom->dirty = GL_FALSE;
+
+}
+
+static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean emitAll)
+{
+ struct radeon_state_atom *atom;
+
if (radeon->vtbl.pre_emit_atoms)
radeon->vtbl.pre_emit_atoms(radeon);
/* Emit actual atoms */
- foreach(atom, &radeon->hw.atomlist) {
- if ((atom->dirty || radeon->hw.all_dirty) == dirty) {
- dwords = (*atom->check) (radeon->glCtx, atom);
- if (dwords) {
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- if (radeon->radeonScreen->kernel_mm)
- radeon_print_state_atom_kmm(radeon, atom);
- else
- radeon_print_state_atom(radeon, atom);
- }
- if (atom->emit) {
- (*atom->emit)(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);
- }
- }
+ if (radeon->hw.all_dirty || emitAll) {
+ foreach(atom, &radeon->hw.atomlist)
+ radeon_emit_atom( radeon, atom );
+ } else {
+ foreach(atom, &radeon->hw.atomlist) {
+ if ( atom->dirty )
+ radeon_emit_atom( radeon, atom );
}
}
@@ -1009,26 +1054,21 @@ void radeonEmitState(radeonContextPtr radeon)
if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->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, and inline the
- * radeonAllocCmdBuf code here without all the checks.
- */
- rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__);
-
if (!radeon->cmdbuf.cs->cdw) {
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "Begin reemit state\n");
+ radeonEmitAtoms(radeon, GL_TRUE);
+ } else {
+
+ if (RADEON_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "Begin dirty state\n");
+
radeonEmitAtoms(radeon, GL_FALSE);
}
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Begin dirty state\n");
-
- radeonEmitAtoms(radeon, GL_TRUE);
radeon->hw.is_dirty = GL_FALSE;
radeon->hw.all_dirty = GL_FALSE;
-
}
@@ -1172,12 +1212,16 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
*
* \param dwords The number of dwords we need to be free on the command buffer
*/
-void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
+GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
{
- if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size ||
- radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
- rcommonFlushCmdBuf(rmesa, caller);
- }
+ if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
+ || radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
+ /* If we try to flush empty buffer there is too big rendering operation. */
+ assert(rmesa->cmdbuf.cs->cdw);
+ rcommonFlushCmdBuf(rmesa, caller);
+ return GL_TRUE;
+ }
+ return GL_FALSE;
}
void rcommonInitCmdBuf(radeonContextPtr rmesa)
@@ -1252,7 +1296,6 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,
const char *function,
int line)
{
- rcommonEnsureCmdBufSpace(rmesa, n, function);
if (!rmesa->cmdbuf.cs->cdw && dostate) {
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "Reemit state after flush (from %s)\n", function);