| @@ -60,6 +60,7 @@ typedef struct r300_context *r300ContextPtr; | |||
| I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble | |||
| with other compilers ... GLUE! | |||
| */ | |||
| #if 1 | |||
| #define WARN_ONCE(a, ...) { \ | |||
| static int warn##__LINE__=1; \ | |||
| if(warn##__LINE__){ \ | |||
| @@ -71,6 +72,9 @@ typedef struct r300_context *r300ContextPtr; | |||
| warn##__LINE__=0;\ | |||
| } \ | |||
| } | |||
| #else | |||
| #define WARN_ONCE(a, ...) {} | |||
| #endif | |||
| typedef GLuint uint32_t; | |||
| typedef GLubyte uint8_t; | |||
| @@ -663,7 +667,7 @@ struct r300_state { | |||
| int aos_count; | |||
| GLuint *Elts; | |||
| struct r300_dma_region elt_ao; | |||
| struct r300_dma_region elt_dma; | |||
| GLuint render_inputs; /* actual render inputs that R300 was configured for. | |||
| They are the same as tnl->render_inputs for fixed pipeline */ | |||
| @@ -210,82 +210,22 @@ static void emit_vector(GLcontext * ctx, | |||
| } | |||
| void emit_elts(GLcontext * ctx, GLuint *elts, | |||
| unsigned long n_elts, unsigned long n_fake_elts, int align) | |||
| void r300EmitElts(GLcontext * ctx, GLuint *elts, unsigned long n_elts) | |||
| { | |||
| r300ContextPtr rmesa = R300_CONTEXT(ctx); | |||
| radeonScreenPtr rsp=rmesa->radeon.radeonScreen; | |||
| unsigned short int *hw_elts; | |||
| struct r300_dma_region *rvb=&rmesa->state.elt_dma; | |||
| unsigned short int *out; | |||
| int i; | |||
| int inc_found=0; | |||
| int dec_found=0; | |||
| unsigned long *dst; | |||
| unsigned long magic_tbl2[6]= { 0x3f51eb85, 0x3e99999a, 0x3f1eb852, 0x3e6b851f, 0x3f2b851f, 0x3eb33333 }; | |||
| if(n_elts == 1){ | |||
| fprintf(stderr, "Dont know how to handle this\n"); | |||
| exit(-1); | |||
| } | |||
| hw_elts=malloc(n_fake_elts*sizeof(unsigned short int)); | |||
| r300AllocDmaRegion(rmesa, rvb, (n_elts+1)*2 , 0x20); | |||
| out = (unsigned short int *)(rvb->address + rvb->start); | |||
| 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 < 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); | |||
| //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:"); | |||
| 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");*/ | |||
| out[i]=(unsigned short int)elts[i]; | |||
| if(n_elts & 1) | |||
| out[i]=0; | |||
| } | |||
| /* Emit vertex data to GART memory (unless immediate mode) | |||
| @@ -558,7 +498,7 @@ void r300ReleaseArrays(GLcontext * ctx) | |||
| r300ContextPtr rmesa = R300_CONTEXT(ctx); | |||
| int i; | |||
| //r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_ao, __FUNCTION__); | |||
| r300ReleaseDmaRegion(rmesa, &rmesa->state.elt_dma, __FUNCTION__); | |||
| for (i=0;i<rmesa->state.aos_count;i++) { | |||
| r300ReleaseDmaRegion(rmesa, &rmesa->state.aos[i], __FUNCTION__); | |||
| } | |||
| @@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| #include "r300_context.h" | |||
| extern void r300EmitElts(GLcontext * ctx, GLuint *elts, unsigned long n_elts); | |||
| extern void r300EmitArrays(GLcontext * ctx, GLboolean immd); | |||
| extern void r300ReleaseArrays(GLcontext * ctx); | |||
| @@ -1310,6 +1310,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
| #define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 | |||
| #define R300_PACKET3_INDX_BUFFER 0x00003300 | |||
| # define R300_EB_UNK1_SHIFT 24 | |||
| # define R300_EB_UNK1 (0x80<<24) | |||
| # define R300_EB_UNK2 0x0810 | |||
| #define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 | |||
| //END | |||
| @@ -460,55 +460,24 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx, | |||
| } | |||
| /* vertex buffer implementation */ | |||
| 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) | |||
| { | |||
| #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; | |||
| 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 | |||
| unsigned long addr_a; | |||
| addr_a = addr & 0x1c; | |||
| check_space(6); | |||
| start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0); | |||
| /* TODO: Check if R300_VAP_VF_CNTL__INDEX_SIZE_32bit works. */ | |||
| 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); /* This still fails once in a while */ | |||
| e32(R300_EB_UNK1 | (addr_a << 16) | R300_EB_UNK2); | |||
| e32(addr & 0xffffffe3); | |||
| e32((vertex_count+1)/2 + addr_a/4); | |||
| } | |||
| static void r300_render_vb_primitive(r300ContextPtr rmesa, | |||
| @@ -530,19 +499,24 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa, | |||
| if(type<0 || num_verts <= 0)return; | |||
| if(rmesa->state.Elts){ | |||
| unsigned long elt_count; | |||
| WARN_ONCE("Rendering with elts\n"); | |||
| r300EmitAOS(rmesa, rmesa->state.aos_count, 0); | |||
| #if 1 | |||
| start_index32_packet(num_verts, type); | |||
| for(i=0; i < num_verts; i++) | |||
| e32(rmesa->state.Elts[start+i]); /* start ? */ | |||
| #else | |||
| 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, get_align(elt_count)); | |||
| fire_EB(PASS_PREFIX rsp->gartTextures.handle/*rmesa->state.elt_ao.aos_offset*/, elt_count, type); | |||
| WARN_ONCE("Rendering with elt buffers\n"); | |||
| if(num_verts == 1){ | |||
| start_index32_packet(num_verts, type); | |||
| e32(rmesa->state.Elts[start]); | |||
| return; | |||
| } | |||
| if(num_verts > 65535){ /* not implemented yet */ | |||
| return; | |||
| } | |||
| r300EmitElts(ctx, rmesa->state.Elts+start, num_verts); | |||
| fire_EB(PASS_PREFIX GET_START(&(rmesa->state.elt_dma)), num_verts, type); | |||
| #endif | |||
| }else{ | |||
| r300EmitAOS(rmesa, rmesa->state.aos_count, start); | |||
| @@ -566,10 +540,6 @@ 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)); | |||
| @@ -1606,6 +1606,7 @@ void r300GenerateSimpleVertexShader(r300ContextPtr r300) | |||
| void r300SetupVertexShader(r300ContextPtr rmesa) | |||
| { | |||
| GLcontext* ctx = rmesa->radeon.glCtx; | |||
| LOCAL_VARS | |||
| if(rmesa->current_vp != NULL){ | |||
| r300SetupVertexProgram(rmesa); | |||