diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_render.c | 366 | 
1 files changed, 275 insertions, 91 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 3007d282e4..93c3a63e47 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -63,63 +63,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  * rasterization hardware for rendering.  **********************************************************************/ -static void r300_render_flat_primitive(r300ContextPtr rmesa,  -	GLcontext *ctx, -	int start, -	int end, -	int type) -{ -   TNLcontext *tnl = TNL_CONTEXT(ctx); -   struct vertex_buffer *VB = &tnl->vb; -   GLuint i; -   int k; -   LOCAL_VARS -       	 -   if(end<=start)return; /* do we need to watch for this ? */ -    - - -   start_immediate_packet(end-start, type, 8); - -	for(i=start;i<end;i++){ -		#if 0 -		fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",  -			VEC_ELT(VB->ObjPtr, GLfloat, i)[0], -			VEC_ELT(VB->ObjPtr, GLfloat, i)[1], -			VEC_ELT(VB->ObjPtr, GLfloat, i)[2], -			VEC_ELT(VB->ObjPtr, GLfloat, i)[3], -			 -			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0], -			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1], -			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2], -			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3] -			); -		#endif -		 -		/* coordinates */ -		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[0]); -		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[1]); -		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[2]); -		#if 0 -		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[3]); -		#else -		efloat(2.0); -		#endif -		 -		/* color components */ -		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0]); -		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1]); -		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2]); -		#if 0 -		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]); -		#else -		efloat(0.0); -		#endif -		} - -} - -static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  +static int r300_get_primitive_type(r300ContextPtr rmesa,   	GLcontext *ctx,  	int start,  	int end, @@ -130,7 +74,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,     GLuint i;     int type=-1; -   if(end<=start)return; /* do we need to watch for this ? */ +   if(end<=start)return -1; /* do we need to watch for this ? */  	fprintf(stderr, "[%d-%d]", start, end);  	switch (prim & PRIM_MODE_MASK) { @@ -139,7 +83,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_LINES;  		if(end<start+2){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;  		case GL_LINE_STRIP: @@ -147,15 +91,15 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;  		if(end<start+2){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;  		case GL_LINE_LOOP:     		fprintf(stderr, "LL "); -		return; +		return -1;  		if(end<start+2){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;      		case GL_TRIANGLES: @@ -163,7 +107,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;  		if(end<start+3){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;     		case GL_TRIANGLE_STRIP: @@ -171,7 +115,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;  		if(end<start+3){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;     		case GL_TRIANGLE_FAN: @@ -179,7 +123,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;  		if(end<start+3){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;  		case GL_QUADS: @@ -187,7 +131,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_QUADS;  		if(end<start+4){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;  		case GL_QUAD_STRIP: @@ -195,16 +139,97 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,  	        type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;  		if(end<start+4){  			fprintf(stderr, "Not enough vertices\n"); -			return; /* need enough vertices for Q */ +			return -1; /* need enough vertices for Q */  			}        		break;     		default:     		fprintf(stderr, "Cannot handle primitive %02x ", prim & PRIM_MODE_MASK); -		return; +		return -1;           	break;     		} -   r300_render_flat_primitive(rmesa, ctx, start, end, type); -	 +   return type; +} + + + +/* Immediate implementation - vertex data is sent via command stream */ + +static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0}; + +#define output_vector(v, i) \ +	{ \ +	int _i; \ +	for(_i=0;_i<v->size;_i++){ \ +		efloat(VEC_ELT(v, GLfloat, i)[_i]); \ +		} \ +	for(_i=v->size;_i<4;_i++){ \ +			efloat(default_vector[_i]); \ +			} \ +	} + +static void r300_render_flat_primitive(r300ContextPtr rmesa,  +	GLcontext *ctx, +	int start, +	int end, +	int prim) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   struct vertex_buffer *VB = &tnl->vb; +   GLuint i; +   int k, type; +   LOCAL_VARS +       	 +   type=r300_get_primitive_type(rmesa, ctx, start, end, prim); +   if(type<0)return; + + +   start_immediate_packet(end-start, type, 8); + +	for(i=start;i<end;i++){ +		#if 0 +		fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",  +			VEC_ELT(VB->ObjPtr, GLfloat, i)[0], +			VEC_ELT(VB->ObjPtr, GLfloat, i)[1], +			VEC_ELT(VB->ObjPtr, GLfloat, i)[2], +			VEC_ELT(VB->ObjPtr, GLfloat, i)[3], +			 +			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0], +			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1], +			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2], +			VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3] +			); +		#endif +		 +		 +		/* coordinates */ +		#if 1 +		output_vector(VB->ObjPtr, i); +		#else +		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[0]); +		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[1]); +		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[2]); +		#if 0 +		efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[3]); +		#else +		efloat(2.0); +		#endif +		#endif +		 +		/* color components */ +		#if 1 +		output_vector(VB->ColorPtr[0], i); +		#else +		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0]); +		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1]); +		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2]); +		#if 0 +		efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]); +		#else +		efloat(0.0); +		#endif +		#endif +		} +  }  static GLboolean r300_run_flat_render(GLcontext *ctx, @@ -214,7 +239,6 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,     TNLcontext *tnl = TNL_CONTEXT(ctx);     struct vertex_buffer *VB = &tnl->vb;     GLuint i; -   ADAPTOR adaptor;     AOS_DATA vb_arrays[2];     LOCAL_VARS @@ -231,6 +255,7 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,     vb_arrays[0].offset=0; /* Not used */     vb_arrays[0].format=AOS_FORMAT_FLOAT;     vb_arrays[0].ncomponents=4; +   vb_arrays[0].reg=REG_COORDS;      /* color */     vb_arrays[1].element_size=4; @@ -238,46 +263,205 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,     vb_arrays[1].offset=0; /* Not used */     vb_arrays[1].format=AOS_FORMAT_FLOAT_COLOR;     vb_arrays[1].ncomponents=4; +   vb_arrays[1].reg=REG_COLOR0; -   adaptor=TWO_PIPE_ADAPTOR; +   r300EmitState(rmesa); -   adaptor.color_offset[0]=rmesa->radeon.radeonScreen->backOffset+rmesa->radeon.radeonScreen->fbLocation; -   adaptor.color_pitch[0]=(rmesa->radeon.radeonScreen->backPitch) | (0xc0<<16); +   /* needed before starting 3d operation .. */ +   reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0); +	e32(0x0000000a); +    +   reg_start(0x4f18,0); +	e32(0x00000003); +	 +	 +   reg_start(0x20b0,0); +	e32(0x0000043f); +  +   program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE); -   adaptor.depth_offset=rmesa->radeon.radeonScreen->depthOffset; -   adaptor.depth_pitch=rmesa->radeon.radeonScreen->depthPitch | (0x2 << 16); +   #if 0 /* Turn on for smooth color on teeth.. why ??.. */ +   set_cull_cntl(PASS_PREFIX 0); +   #endif +   reg_start(R300_RE_OCCLUSION_CNTL, 0); +	     e32(R300_OCCLUSION_ON); +	      +//   set_quad0(PASS_PREFIX 1.0,1.0,1.0,1.0); +     set_init21(PASS_PREFIX 0.0,1.0); -   init_3d(PASS_PREFIX &adaptor); -   init_flat_primitive(PASS_PREFIX &adaptor); +   /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */ +   setup_AOS(PASS_PREFIX vb_arrays, 2); +    +   for(i=0; i < VB->PrimitiveCount; i++){ +       GLuint prim = VB->Primitive[i].mode; +       GLuint start = VB->Primitive[i].start; +       GLuint length = VB->Primitive[i].count; +	r300_render_flat_primitive(rmesa, ctx, start, start + length, prim); +   	} +	 +   end_3d(PASS_PREFIX_VOID); -   set_scissors(PASS_PREFIX 0, 0, 2647, 1941); +   fprintf(stderr, "\n"); +   return GL_FALSE; +} + +/* vertex buffer implementation */ + +/* We use the start part of GART texture buffer for vertices */ -   set_cliprect(PASS_PREFIX 0, 0, 0, 2647,1941); -   set_cliprect(PASS_PREFIX 1, 0, 0, 2647,1941); -   set_cliprect(PASS_PREFIX 2, 0, 0, 2647,1941); -   set_cliprect(PASS_PREFIX 3, 0, 0, 2647,1941); +#define R300_MAX_AOS_ARRAYS		16 + +static void upload_vertex_buffer(r300ContextPtr rmesa,  +	GLcontext *ctx, AOS_DATA *array, int *n_arrays) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   struct vertex_buffer *VB = &tnl->vb; +   int offset=0, idx=0; +   int i,j; +   radeonScreenPtr rsp=rmesa->radeon.radeonScreen; +   /* Not the most efficient implementation, but, for now, I just want something that +      works */ +      /* to do - make single memcpy per column (is it possible ?) */ +      /* to do - use dirty flags to avoid redundant copies */ +#define UPLOAD_VECTOR(v, r, f)\ +	{ \ +	 /* Is the data dirty ? */ \ +	if (v->flags & ((1<<v->size)-1)) { \ +		fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); \ +		if(v->size*4==v->stride){\ +			/* fast path */  \ +			memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \ +			} else { \ +			for(i=0;i<VB->Count;i++){ \ +				/* copy one vertex at a time*/ \ +				memcpy(rsp->gartTextures.map+offset, VEC_ELT(v, GLfloat, i), v->size*4); \ +				} \ +			} \ +		/* v->flags &= ~((1<<v->size)-1);*/ \ +		} \ +	array[idx].element_size=v->size; \ +	array[idx].stride=v->size; \ +	array[idx].format=(f); \ +	array[idx].ncomponents=v->size; \ +	array[idx].offset=rsp->gartTextures.handle+offset; \ +	array[idx].reg=r; \ +	offset+=v->size*4*VB->Count; \ +	idx++; \ +	/* Fill in the rest with the components of default_vector */\ +	/* \ +	if(v->size<4){ \ +		array[idx].element_size=4-v->size; \ +		array[idx].stride=0; \ +		array[idx].format=(f); \ +		array[idx].ncomponents=4-v->size; \ +		array[idx].offset=rsp->gartTextures.handle+v->size*4;\ +		array[idx].reg=r; \ +		idx++; \ +		} \ +	*/\ +	} +	 +/* Put a copy of default vector */ +memcpy(rsp->gartTextures.map, default_vector, 16); +offset+=16; +		 +UPLOAD_VECTOR(VB->ObjPtr, REG_COORDS, AOS_FORMAT_FLOAT); +UPLOAD_VECTOR(VB->ColorPtr[0], REG_COLOR0, AOS_FORMAT_FLOAT_COLOR); + +*n_arrays=idx; +if(idx>=R300_MAX_AOS_ARRAYS){ +	fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n"); +	exit(-1); +	} +} + +static void r300_render_vb_flat_primitive(r300ContextPtr rmesa,  +	GLcontext *ctx, +	int start, +	int end, +	int prim) +{ +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   struct vertex_buffer *VB = &tnl->vb; +   GLuint i; +   int k, type, n_arrays; +   LOCAL_VARS +       	 +   if(end<=start)return; /* do we need to watch for this ? */ +    +   type=r300_get_primitive_type(rmesa, ctx, start, end, prim); +   if(type<0)return; + +   fire_AOS(PASS_PREFIX end-start, type); +} + +static VERTEX_SHADER_FRAGMENT default_vector_vsf={ +	length: 4, +	body: {  +		f: {0.0, 0.0, 0.0, 1.0} +		} +	}; + +static GLboolean r300_run_vb_flat_render(GLcontext *ctx, +				 struct tnl_pipeline_stage *stage) +{ +   r300ContextPtr rmesa = R300_CONTEXT(ctx); +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   struct vertex_buffer *VB = &tnl->vb; +   int i, j, n_arrays; +   AOS_DATA vb_arrays[R300_MAX_AOS_ARRAYS]; +   AOS_DATA vb_arrays2[R300_MAX_AOS_ARRAYS]; +   LOCAL_VARS +	 +	if (RADEON_DEBUG == DEBUG_PRIMS) +		fprintf(stderr, "%s\n", __FUNCTION__); + +   /* setup array of structures data */ + +   upload_vertex_buffer(rmesa, ctx, vb_arrays, &n_arrays); +   fprintf(stderr, "Using %d AOS arrays\n", n_arrays); +    +   r300EmitState(rmesa); +    +   reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0); +	e32(0x0000000a); +    +   reg_start(0x4f18,0); +	e32(0x00000003); +    +   reg_start(0x20b0,0); +	e32(0x0000043f); +  +   program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE); +       +   //upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_UNKNOWN1, &default_vector_vsf);     reg_start(R300_RE_OCCLUSION_CNTL, 0);  	     e32(R300_OCCLUSION_ON); - +	          set_quad0(PASS_PREFIX 1.0,1.0,1.0,1.0);     set_init21(PASS_PREFIX 0.0,1.0); - -   /* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */ -   setup_AOS(PASS_PREFIX vb_arrays, 2);     for(i=0; i < VB->PrimitiveCount; i++){         GLuint prim = VB->Primitive[i].mode;         GLuint start = VB->Primitive[i].start;         GLuint length = VB->Primitive[i].count; -	r300_dispatch_flat_primitive(rmesa, ctx, start, start + length, prim); +        +        /* copy arrays */ +        memcpy(vb_arrays2, vb_arrays, sizeof(AOS_DATA)*n_arrays); +	for(j=0;j<n_arrays;j++){ +		vb_arrays2[j].offset+=vb_arrays2[j].stride*start; +		} +		 +        setup_AOS(PASS_PREFIX vb_arrays2, n_arrays); +        +	r300_render_vb_flat_primitive(rmesa, ctx, start, start + length, prim);     	}     end_3d(PASS_PREFIX_VOID); -   start_packet3(RADEON_CP_PACKET3_NOP, 0); -   e32(0x0); -    +   /* Flush state - we are done drawing.. */ +   r300Flush(ctx);     fprintf(stderr, "\n");     return GL_FALSE;  }  | 
