From 41d180c899c9008edadc6ff4538fc33e9793259c Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Wed, 16 Feb 2005 19:04:32 +0000 Subject: [PATCH] Support for idx buffers. Leaving it on by default as it doesnt seem to cause any lock ups nor other issues. Tests with one object using elts should pass. Introducing more than one object will cause indices to mix up as far as i can see. DRM update is needed for this code to work\! --- src/mesa/drivers/dri/r300/r300_context.h | 3 +- src/mesa/drivers/dri/r300/r300_emit.h | 1 + src/mesa/drivers/dri/r300/r300_maos.c | 54 ++++++++++++++++++++- src/mesa/drivers/dri/r300/r300_reg.h | 4 ++ src/mesa/drivers/dri/r300/r300_render.c | 61 +++++++++++++++++++++++- 5 files changed, 119 insertions(+), 4 deletions(-) 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)); -- 2.30.2