diff options
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_common.c')
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_common.c | 150 |
1 files changed, 103 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..8f34fbf6bc 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,84 @@ 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; + GLuint dwords = 0; + /* check if we are going to emit full state */ + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE) + fprintf(stderr, "%s\n", __func__); + + if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) { + if (!radeon->hw.is_dirty) + return dwords; + foreach(atom, &radeon->hw.atomlist) { + if (atom->dirty) { + const GLuint atom_size = atom->check(radeon->glCtx, atom); + dwords += atom_size; + if (DEBUG_CMDBUF && atom_size) { + radeon_print_state_atom(radeon, atom); + } + } + } + } else { + foreach(atom, &radeon->hw.atomlist) { + const GLuint atom_size = atom->check(radeon->glCtx, atom); + dwords += atom_size; + if (DEBUG_CMDBUF && atom_size) { + radeon_print_state_atom(radeon, 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 +1067,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 +1225,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 +1309,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); |