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\!

This commit is contained in:
Aapo Tahkola 2005-02-16 19:04:32 +00:00
parent 8eeef423e9
commit 41d180c899
5 changed files with 119 additions and 4 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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;i<rmesa->state.aos_count;i++) {
r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__);
}

View File

@ -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 */

View File

@ -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));