X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fr200%2Fr200_cmdbuf.c;h=c1d51e87001621c10e4649db8833c94f462c774b;hb=3177b4e2cf7d2fff7428cb6057bebbe60ff5cc6c;hp=26812d50b628e44f59f0637d43d23af356bce634;hpb=aaaf38d37215aa1536ff34ec370ecfc04111af22;p=mesa.git diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index 26812d50b62..c1d51e87001 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -1,4 +1,3 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c,v 1.1 2002/10/30 12:51:51 alanh Exp $ */ /* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. @@ -58,120 +57,156 @@ static void print_state_atom( struct r200_state_atom *state ) } -static void r200_emit_state_list( r200ContextPtr rmesa, - struct r200_state_atom *list ) +/* The state atoms will be emitted in the order they appear in the atom list, + * so this step is important. + */ +void r200SetUpAtomList( r200ContextPtr rmesa ) { - struct r200_state_atom *state, *tmp; - char *dest; - int i, size, mtu; - - size = 0; - foreach_s( state, tmp, list ) { - if (state->check( rmesa->glCtx, state->idx )) { -/* dest = r200AllocCmdBuf( 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 (R200_DEBUG & DEBUG_STATE) - print_state_atom( state ); - } - else if (R200_DEBUG & DEBUG_STATE) - fprintf(stderr, "skip state %s\n", state->name); - } - - if (!size) - return; + int i, mtu; - dest = r200AllocCmdBuf( rmesa, size * 4, __FUNCTION__); mtu = 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 (vtx); - EMIT_ATOM (vap); - EMIT_ATOM (vte); - EMIT_ATOM (msc); - EMIT_ATOM (cst); - EMIT_ATOM (zbs); - EMIT_ATOM (tcl); - EMIT_ATOM (msl); - EMIT_ATOM (tcg); - EMIT_ATOM (grd); - EMIT_ATOM (fog); - EMIT_ATOM (tam); - EMIT_ATOM (tf); - for (i = 0; i < mtu; ++i) { - EMIT_ATOM (tex[i]); - } - for (i = 0; i < mtu; ++i) { - EMIT_ATOM (cube[i]); - } - for (i = 0; i < 3 + mtu; ++i) - EMIT_ATOM (mat[i]); - EMIT_ATOM (eye); - EMIT_ATOM (glt); - for (i = 0; i < 2; ++i) { - EMIT_ATOM (mtl[i]); - } - for (i = 0; i < 8; ++i) - EMIT_ATOM (lit[i]); + make_empty_list(&rmesa->hw.atomlist); + rmesa->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.vtx ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vap ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vte ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.msc ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.cst ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.zbs ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tcl ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.msl ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tcg ); + 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.tam ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tf ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.atf ); + for (i = 0; i < mtu; ++i) + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tex[i] ); + for (i = 0; i < mtu; ++i) + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.cube[i] ); for (i = 0; i < 6; ++i) - EMIT_ATOM (ucp[i]); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pix[i] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.afs[0] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.afs[1] ); + for (i = 0; i < 8; ++i) + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lit[i] ); + for (i = 0; i < 3 + mtu; ++i) + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mat[i] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.eye ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.glt ); + for (i = 0; i < 2; ++i) + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mtl[i] ); for (i = 0; i < 6; ++i) - EMIT_ATOM (pix[i]); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ucp[i] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.spr ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ptp ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.prf ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pvs ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[0] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[1] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpi[0] ); + insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpi[1] ); +} + +static void r200SaveHwState( r200ContextPtr rmesa ) +{ + struct r200_state_atom *atom; + char * dest = rmesa->backup_store.cmd_buf; -#undef EMIT_ATOM + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s\n", __FUNCTION__); -} + rmesa->backup_store.cmd_used = 0; + + foreach( atom, &rmesa->hw.atomlist ) { + if ( atom->check( rmesa->glCtx, atom->idx ) ) { + int size = atom->cmd_size * 4; + memcpy( dest, atom->cmd, size); + dest += size; + rmesa->backup_store.cmd_used += size; + if (R200_DEBUG & DEBUG_STATE) + print_state_atom( atom ); + } + } + assert( rmesa->backup_store.cmd_used <= R200_CMD_BUF_SZ ); + if (R200_DEBUG & DEBUG_STATE) + fprintf(stderr, "Returning to r200EmitState\n"); +} void r200EmitState( r200ContextPtr rmesa ) { - struct r200_state_atom *state, *tmp; + char *dest; + int mtu; + struct r200_state_atom *atom; if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) fprintf(stderr, "%s\n", __FUNCTION__); - /* Somewhat overkill: - */ - if ( rmesa->lost_context) { - if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS|DEBUG_IOCTL)) - fprintf(stderr, "%s - lost context\n", __FUNCTION__); + if (rmesa->save_on_next_emit) { + r200SaveHwState(rmesa); + rmesa->save_on_next_emit = GL_FALSE; + } - foreach_s( state, tmp, &(rmesa->hw.clean) ) - move_to_tail(&(rmesa->hw.dirty), state ); + if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty) + return; + + mtu = rmesa->glCtx->Const.MaxTextureUnits; - rmesa->lost_context = 0; + /* 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 + * r200AllocCmdBuf code here without all the checks. + */ + r200EnsureCmdBufSpace( rmesa, rmesa->hw.max_state_size ); + + /* we need to calculate dest after EnsureCmdBufSpace + as we may flush the buffer - airlied */ + dest = rmesa->store.cmd_buf + rmesa->store.cmd_used; + if (R200_DEBUG & DEBUG_STATE) { + foreach( atom, &rmesa->hw.atomlist ) { + if ( atom->dirty || rmesa->hw.all_dirty ) { + if ( atom->check( rmesa->glCtx, atom->idx ) ) + print_state_atom( atom ); + else + fprintf(stderr, "skip state %s\n", atom->name); + } + } } -/* else { - move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] );*/ - /* odd bug? -- isosurf, cycle between reflect & lit */ -/* }*/ - r200_emit_state_list( rmesa, &rmesa->hw.dirty ); -} + foreach( atom, &rmesa->hw.atomlist ) { + if ( rmesa->hw.all_dirty ) + atom->dirty = GL_TRUE; + if ( atom->dirty ) { + if ( atom->check( rmesa->glCtx, atom->idx ) ) { + int size = atom->cmd_size * 4; + memcpy( dest, atom->cmd, size); + dest += size; + rmesa->store.cmd_used += size; + atom->dirty = GL_FALSE; + } + } + } + assert( rmesa->store.cmd_used <= R200_CMD_BUF_SZ ); + rmesa->hw.is_dirty = GL_FALSE; + rmesa->hw.all_dirty = GL_FALSE; +} /* Fire a section of the retained (indexed_verts) buffer as a regular * primtive. */ -extern void r200EmitVbufPrim( r200ContextPtr rmesa, - GLuint primitive, - GLuint vertex_nr ) +void r200EmitVbufPrim( r200ContextPtr rmesa, + GLuint primitive, + GLuint vertex_nr ) { drm_radeon_cmd_header_t *cmd; @@ -183,7 +218,7 @@ extern void r200EmitVbufPrim( r200ContextPtr rmesa, fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__, rmesa->store.cmd_used/4, primitive, vertex_nr); - cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 3 * sizeof(*cmd), + cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, VBUF_BUFSZ, __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; @@ -205,7 +240,7 @@ void r200FlushElts( r200ContextPtr rmesa ) fprintf(stderr, "%s\n", __FUNCTION__); assert( rmesa->dma.flush == r200FlushElts ); - rmesa->dma.flush = 0; + rmesa->dma.flush = NULL; /* Cope with odd number of elts: */ @@ -236,8 +271,7 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, r200EmitState( rmesa ); - cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, - 12 + min_nr*2, + cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, ELTS_BUFSZ(min_nr), __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; @@ -275,7 +309,7 @@ void r200EmitVertexAOS( r200ContextPtr rmesa, fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", __FUNCTION__, vertex_size, offset); - cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 5 * sizeof(int), + cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, VERT_AOS_BUFSZ, __FUNCTION__ ); cmd[0].header.cmd_type = RADEON_CMD_PACKET3; @@ -292,18 +326,17 @@ void r200EmitAOS( r200ContextPtr rmesa, GLuint offset ) { drm_radeon_cmd_header_t *cmd; - int sz = 3 + ((nr/2)*3) + ((nr&1)*2); + int sz = AOS_BUFSZ(nr); int i; int *tmp; if (R200_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s nr arrays: %d\n", __FUNCTION__, nr); - cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, sz * sizeof(int), - __FUNCTION__ ); + cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, sz, __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3; - cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | ((sz-3) << 16); + cmd[1].i = R200_CP_CMD_3D_LOAD_VBPNTR | (((sz / sizeof(int)) - 3) << 16); cmd[2].i = nr; tmp = &cmd[0].i; cmd += 3; @@ -383,15 +416,13 @@ void r200EmitBlit( r200ContextPtr rmesa, void r200EmitWait( r200ContextPtr rmesa, GLuint flags ) { - if (rmesa->dri.drmMinor >= 6) { - drm_radeon_cmd_header_t *cmd; - - assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); - - cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 1 * sizeof(int), - __FUNCTION__ ); - cmd[0].i = 0; - cmd[0].wait.cmd_type = RADEON_CMD_WAIT; - cmd[0].wait.flags = flags; - } + drm_radeon_cmd_header_t *cmd; + + assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); + + cmd = (drm_radeon_cmd_header_t *)r200AllocCmdBuf( rmesa, 1 * sizeof(int), + __FUNCTION__ ); + cmd[0].i = 0; + cmd[0].wait.cmd_type = RADEON_CMD_WAIT; + cmd[0].wait.flags = flags; }