diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index eb76a1ca05a..0c72aa06704 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -661,7 +661,8 @@ struct r300_state { int aos_count; GLuint *Elts; - + struct r300_dma_region elt_ao; + GLuint render_inputs; /* actual render inputs that R300 was configured for. They are the same as tnl->render_inputs for fixed pipeline */ diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index 65ed7ff0ec6..cba482f0fb4 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -21,6 +21,7 @@ #define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 #define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 #define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CP_PACKET3_INDX_BUFFER 0xC0003300 #define RADEON_CP_PACKET3_3D_DRAW_VBUF_2 0xC0003400 #define RADEON_CP_PACKET3_3D_DRAW_IMMD_2 0xC0003500 #define RADEON_CP_PACKET3_3D_DRAW_INDX_2 0xC0003600 diff --git a/src/mesa/drivers/dri/r300/r300_maos.c b/src/mesa/drivers/dri/r300/r300_maos.c index e4ea676119f..2f112d4bb21 100644 --- a/src/mesa/drivers/dri/r300/r300_maos.c +++ b/src/mesa/drivers/dri/r300/r300_maos.c @@ -209,7 +209,58 @@ static void emit_vector(GLcontext * ctx, } } - + +void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + radeonScreenPtr rsp=rmesa->radeon.radeonScreen; + unsigned short int *hw_elts; + int i; + int inc_found=0; + int dec_found=0; + + hw_elts=malloc(ec*sizeof(unsigned short int)); + + for(i=0; i < oec; i++) + hw_elts[i]=(unsigned short int)elts[i]; + + /* Work around magic_1 problem by filling rest of the data with last idx */ + for(; i < ec; i++) + hw_elts[i]=(unsigned short int)elts[oec-1]; + + memcpy(rsp->gartTextures.map, hw_elts, ec*sizeof(unsigned short int)); + //memset(((char *)rsp->gartTextures.map)+ec*sizeof(unsigned short int), 0, 1024); + /*emit_vector(ctx, &rmesa->state.elt_ao, + (char *)hw_elts, + 2, + 2, ec);*/ + /* + // some debug code... + inc_found=1; + for(i=1; i < oec; i++) + if(hw_elts[i-1] != hw_elts[i]+1){ + inc_found=0; + break; + } + + dec_found=1; + for(i=1; i < oec; i++) + if(hw_elts[i-1] != hw_elts[i]-1){ + dec_found=0; + } + + fprintf(stderr, "elts:"); + for(i=0; i < oec; i++) + fprintf(stderr, "%d\n", hw_elts[i]); + fprintf(stderr, "\n"); + + if(inc_found==0 && dec_found==0){ + fprintf(stderr, "error found\n"); + exit(-1); + } + */ +} + /* Emit vertex data to GART memory (unless immediate mode) * Route inputs to the vertex processor */ @@ -479,6 +530,7 @@ void r300ReleaseArrays(GLcontext * ctx) r300ContextPtr rmesa = R300_CONTEXT(ctx); int i; + //r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_ao, __FUNCTION__); for (i=0;istate.aos_count;i++) { r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__); } diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 883d9b944c5..d44d149bffa 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1308,6 +1308,10 @@ I am fairly certain that they are correct unless stated otherwise in comments. // Note that if the total number of arrays is odd, the third dword of // the last block is omitted. #define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 + +#define R300_PACKET3_INDX_BUFFER 0x00003300 +#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 + //END #endif /* _R300_REG_H */ diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index b66fa3fbd0e..4e90ea2152a 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -253,6 +253,8 @@ void dump_inputs(GLcontext *ctx, int render_inputs) { int k; fprintf(stderr, "inputs:"); + fprintf(stderr, "%08x ", render_inputs); + if(render_inputs & _TNL_BIT_POS) fprintf(stderr, "_TNL_BIT_POS "); if(render_inputs & _TNL_BIT_NORMAL) @@ -512,6 +514,44 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx, } /* vertex buffer implementation */ +void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec); + +# define R300_EB_UNK1_SHIFT 24 +# define R300_EB_UNK1 (0x80<<24) +# define R300_EB_UNK2 0x0810 + +unsigned long get_num_elts(unsigned long count) +{ + unsigned long magic_1; + + /* round up elt count so that magic_1 is 0 (divisable by 4)*/ + return (count+3) & (~3); + //return count - (count % 4); +} + +static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type) +{ + LOCAL_VARS + unsigned long magic_1; + unsigned char magic1_tbl[4]={ 0, 6, 4, 2 }; + + magic_1 = magic1_tbl[vertex_count % 4]; + + if(magic_1 != 0){ + WARN_ONCE("Dont know how to handle this yet!\n"); + return ; + } + + check_space(6); + + start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0); + e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type); + + start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2); + e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2); + e32(addr); + e32(((vertex_count+1) / 2) + magic_1); +} static void r300_render_vb_primitive(r300ContextPtr rmesa, GLcontext *ctx, @@ -520,15 +560,27 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa, int prim) { int type, num_verts; + radeonScreenPtr rsp=rmesa->radeon.radeonScreen; LOCAL_VARS + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; type=r300_get_primitive_type(rmesa, ctx, prim); num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim); if(type<0 || num_verts <= 0)return; - - fire_AOS(PASS_PREFIX num_verts, type); + if(rmesa->state.Elts){ + unsigned long elt_count; + + WARN_ONCE("Rendering with elts\n"); + + elt_count=get_num_elts(num_verts); + //emit_elts(ctx, rmesa->state.Elts, VB->Count, get_num_elts(VB->Count)); + emit_elts(ctx, rmesa->state.Elts+start, num_verts, elt_count); + fire_EB(PASS_PREFIX rsp->gartTextures.handle/*rmesa->state.elt_ao.aos_offset*/, elt_count, type); + }else + fire_AOS(PASS_PREFIX num_verts, type); } static GLboolean r300_run_vb_render(GLcontext *ctx, @@ -546,6 +598,11 @@ static GLboolean r300_run_vb_render(GLcontext *ctx, r300ReleaseArrays(ctx); r300EmitArrays(ctx, GL_FALSE); + //dump_inputs(ctx, rmesa->state.render_inputs); +#if 0 /* Cant do this here yet due to magic_1 */ + if(rmesa->state.Elts) + emit_elts(ctx, rmesa->state.Elts, /*600*/VB->Count, get_num_elts(/*600*/VB->Count)); +#endif // LOCK_HARDWARE(&(rmesa->radeon));