magic_1 handling...
authorAapo Tahkola <aet@rasterburn.org>
Thu, 17 Feb 2005 18:02:28 +0000 (18:02 +0000)
committerAapo Tahkola <aet@rasterburn.org>
Thu, 17 Feb 2005 18:02:28 +0000 (18:02 +0000)
src/mesa/drivers/dri/r300/r300_maos.c
src/mesa/drivers/dri/r300/r300_render.c

index 2f112d4..20a804d 100644 (file)
@@ -210,7 +210,8 @@ static void emit_vector(GLcontext * ctx,
 
 }
 
-void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec)
+void emit_elts(GLcontext * ctx, GLuint *elts,
+               unsigned long n_elts, unsigned long n_fake_elts, int align)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
        radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
@@ -218,17 +219,43 @@ void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec)
        int i;
        int inc_found=0;
        int dec_found=0;
+       unsigned long *dst;
+       unsigned long magic_tbl2[6]= { 0x3f51eb85, 0x3e99999a, 0x3f1eb852, 0x3e6b851f, 0x3f2b851f, 0x3eb33333 };
        
-       hw_elts=malloc(ec*sizeof(unsigned short int));
+       if(n_elts == 1){
+               fprintf(stderr, "Dont know how to handle this\n");
+               exit(-1);
+       }
        
-       for(i=0; i < oec; i++)
+       hw_elts=malloc(n_fake_elts*sizeof(unsigned short int));
+       
+       for(i=0; i < n_elts; 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];
+       for(; i < n_fake_elts; i++)
+               hw_elts[i]=(unsigned short int)elts[n_elts-1];
+       
+       dst=rsp->gartTextures.map;
+       
+       /* Buffer underrun in fgl causes these patterns to appear.
+          Filling these shouldnt be needed in real life. */
+       for(i=0; i < align; i++)
+               if(dst[i] = magic_tbl2[6-align+i])
+       
+       //memset(dst, 0, align*sizeof(unsigned long));
+       /*for(i=0; i < align; i++)
+               dst[i]=rand()%(~0);*/
+       
+       dst=&dst[align];
+                       
+       memcpy(dst, hw_elts, n_fake_elts*sizeof(unsigned short int));
+       dst=((char *)dst)+n_fake_elts*sizeof(unsigned short int);
+       
+       /*for(i=0; i < 1024/4; i++)
+               dst[i]=rand()%(~0);*/
+       //memset(dst, 0, 1024);
        
-       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,
@@ -250,15 +277,15 @@ void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec)
                }
                
        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);
        }
        */
+       /*for(i=0; i < n_elts; i++)
+               fprintf(stderr, "%d ", hw_elts[i]);
+               fprintf(stderr, "\n");*/
 }
                
 /* Emit vertex data to GART memory (unless immediate mode)
index 8264fce..d26d4c0 100644 (file)
@@ -516,34 +516,45 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx,
 }
 
 /* vertex buffer implementation */
-void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec);
+void emit_elts(GLcontext * ctx, GLuint *elts,
+               unsigned long n_elts, unsigned long n_fake_elts, int align);
 
 #    define R300_EB_UNK1_SHIFT 24
 #    define R300_EB_UNK1 (0x80<<24)
 #    define R300_EB_UNK2 0x0810
 
+//#define PLAY_WITH_MAGIC_1
+
 unsigned long get_num_elts(unsigned long count)
 {
-       unsigned long magic_1;
-       
+#ifdef PLAY_WITH_MAGIC_1
+       return count;
+#else  
        /* round up elt count so that magic_1 is 0 (divisable by 4)*/
        return (count+3) & (~3);
        //return count - (count % 4);
+#endif
+}
+
+int get_align(int vertex_count)
+{
+       unsigned char magic1_tbl[4]={ 0, 6, 4, 2 };
+
+       return magic1_tbl[vertex_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];
 
+       magic_1 = get_align(vertex_count);
+#ifndef PLAY_WITH_MAGIC_1
        if(magic_1 != 0){
                WARN_ONCE("Dont know how to handle this yet!\n");
                return ;
        }
-       
+#endif 
        check_space(6);
        
        start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
@@ -552,7 +563,7 @@ static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int 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);
+       e32(((vertex_count+1) / 2) + magic_1); /* This still fails once in a while */
 }
 
 static void r300_render_vb_primitive(r300ContextPtr rmesa, 
@@ -579,7 +590,7 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa,
        
        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);
+       emit_elts(ctx, rmesa->state.Elts+start, num_verts, elt_count, get_align(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);
@@ -622,9 +633,10 @@ static GLboolean r300_run_vb_render(GLcontext *ctx,
                GLuint prim = VB->Primitive[i].mode;
                GLuint start = VB->Primitive[i].start;
                GLuint length = VB->Primitive[i].count;
-
-               r300EmitAOS(rmesa, rmesa->state.aos_count, start);   
-
+               if(rmesa->state.Elts)
+                       r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
+               else
+                       r300EmitAOS(rmesa, rmesa->state.aos_count, start);
                r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
        }