diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/drivers/dri/r300/Makefile | 1 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_cmdbuf.c | 15 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.c | 14 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.h | 5 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_ioctl.c | 2 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_render.c | 189 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/r300/r300_state.c | 158 | 
7 files changed, 360 insertions, 24 deletions
| diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 19e95c2322..1306dede7f 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -30,6 +30,7 @@ DRIVER_SOURCES = \  		 r300_ioctl.c \  		 r300_cmdbuf.c \  		 r300_state.c \ +		 r300_render.c \  		 \  		 r200_context.c \  		 r200_ioctl.c \ diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 7bf2df5a8e..580c5145a7 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -50,6 +50,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "r300_cmdbuf.h" +// Set this to 1 for extremely verbose debugging of command buffers +#define DEBUG_CMDBUF		0 + +  /**   * Send the current command buffer via ioctl to the hardware.   */ @@ -69,7 +73,7 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char* caller)  		fprintf(stderr, "%s from %s - %i cliprects\n",  			__FUNCTION__, caller, r300->radeon.numClipRects); -		if (RADEON_DEBUG & DEBUG_VERBOSE) +		if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_VERBOSE)  			for (i = start; i < r300->cmdbuf.count_used; ++i)  				fprintf(stderr, "%d: %08x\n", i,  					r300->cmdbuf.cmd_buf[i]); @@ -140,7 +144,7 @@ static __inline__ void r300DoEmitState(r300ContextPtr r300, GLboolean dirty)  	dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used; -	if (RADEON_DEBUG & DEBUG_STATE) { +	if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {  		foreach(atom, &r300->hw.atomlist) {  			if ((atom->dirty || r300->hw.all_dirty) == dirty) {  				int dwords = (*atom->check)(r300, atom); @@ -324,8 +328,10 @@ void r300InitCmdBuf(r300ContextPtr r300)  		r300->hw.unk4288.cmd[0] = cmducs(0x4288, 5);  	ALLOC_STATE( unk42A0, always, 2, "unk42A0", 0 );  		r300->hw.unk42A0.cmd[0] = cmducs(0x42A0, 1); -	ALLOC_STATE( unk42B4, always, 3, "unk42B4", 0 ); -		r300->hw.unk42B4.cmd[0] = cmducs(0x42B4, 2); +	ALLOC_STATE( unk42B4, always, 2, "unk42B4", 0 ); +		r300->hw.unk42B4.cmd[0] = cmducs(0x42B4, 1); +	ALLOC_STATE( cul, always, R300_CUL_CMDSIZE, "cul", 0 ); +		r300->hw.cul.cmd[R300_CUL_CMD_0] = cmducs(R300_RE_CULL_CNTL, 1);  	ALLOC_STATE( unk42C0, always, 3, "unk42C0", 0 );  		r300->hw.unk42C0.cmd[0] = cmducs(0x42C0, 2);  	ALLOC_STATE( rc, always, R300_RC_CMDSIZE, "rc", 0 ); @@ -428,6 +434,7 @@ void r300InitCmdBuf(r300ContextPtr r300)  	insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4288);  	insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42A0);  	insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42B4); +	insert_at_tail(&r300->hw.atomlist, &r300->hw.cul);  	insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42C0);  	insert_at_tail(&r300->hw.atomlist, &r300->hw.rc);  	insert_at_tail(&r300->hw.atomlist, &r300->hw.ri); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 6e98bd1e72..9831dc60a4 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -100,15 +100,13 @@ static const char *const card_extensions[] = {  	NULL  }; -#if 0 -extern const struct tnl_pipeline_stage _r300_render_stage; -extern const struct tnl_pipeline_stage _r300_tcl_stage; +extern struct tnl_pipeline_stage _r300_render_stage;  static const struct tnl_pipeline_stage *r300_pipeline[] = {  	/* Try and go straight to t&l  	 */ -	&_r300_tcl_stage, +//	&_r300_tcl_stage,  	/* Catch any t&l fallbacks  	 */ @@ -136,7 +134,7 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = {  	&_tnl_render_stage,	/* FALLBACK  */  	0,  }; -#endif +  /* Create the device specific rendering context.   */ @@ -217,13 +215,10 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,  	_swsetup_CreateContext(ctx);  	_ae_create_context(ctx); -#if 0  	/* Install the customized pipeline:  	 */  	_tnl_destroy_pipeline(ctx); -	_tnl_install_pipeline(ctx, r200_pipeline); -	ctx->Driver.FlushVertices = r200FlushVertices; -#endif +	_tnl_install_pipeline(ctx, r300_pipeline);  	/* Try and keep materials and vertices separate:  	 */ @@ -245,7 +240,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,  	/* plug in a few more device driver functions */  	/* XXX these should really go right after _mesa_init_driver_functions() */  	r200InitPixelFuncs(ctx); -	r200InitTnlFuncs(ctx);  	r200InitSwtcl(ctx);  #endif  	TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index ada6e4a5a2..d80bcc689f 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -126,6 +126,10 @@ struct r300_state_atom {  #define R300_PS_POINTSIZE	1  #define R300_PS_CMDSIZE		2 +#define R300_CUL_CMD_0		0 +#define R300_CUL_CULL		1 +#define R300_CUL_CMDSIZE	2 +  #define R300_RC_CMD_0		0  #define R300_RC_CNTL_0		1  #define R300_RC_CNTL_1		2 @@ -247,6 +251,7 @@ struct r300_hw_state {  	struct r300_state_atom unk4288; /* (4288) */  	struct r300_state_atom unk42A0; /* (42A0) */  	struct r300_state_atom unk42B4; /* (42B4) */ +	struct r300_state_atom cul;	/* cull cntl (42B8) */  	struct r300_state_atom unk42C0; /* (42C0) */  	struct r300_state_atom rc;	/* rs control (4300) */  	struct r300_state_atom ri;	/* rs interpolators (4310) */ diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index f6a3d8140c..63a7d540e4 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -171,7 +171,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)  	R300_STATECHANGE(r300, zc);  	if (flags & CLEARBUFFER_DEPTH) {  		r300->hw.zc.cmd[R300_ZC_CNTL_0] = 0x6; // test and write -		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_RB3D_Z_TEST_ALWAYS; +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_ALWAYS;  /*  		R300_STATECHANGE(r300, zb);  		r300->hw.zb.cmd[R300_ZB_OFFSET] = diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c new file mode 100644 index 0000000000..3f9a63fb0d --- /dev/null +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -0,0 +1,189 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + *   Nicolai Haehnle <prefect_@gmx.net> + */ + +#include "glheader.h" +#include "state.h" +#include "imports.h" +#include "enums.h" +#include "macros.h" +#include "context.h" +#include "dd.h" +#include "simple_list.h" + +#include "api_arrayelt.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" + +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "r300_context.h" +#include "r300_ioctl.h" +#include "r300_state.h" +#include "r300_reg.h" +#include "r300_program.h" + + +/********************************************************************** +*                     Hardware rasterization +* +* When we fell back to software TCL, we still try to use the +* rasterization hardware for rendering. +**********************************************************************/ + + +/** + * Called by the pipeline manager to render a batch of primitives. + * We can return true to pass on to the next stage (i.e. software + * rasterization) or false to indicate that the pipeline has finished + * after we render something. + */ +static GLboolean r300_run_render(GLcontext *ctx, +				 struct tnl_pipeline_stage *stage) +{ +	if (RADEON_DEBUG == DEBUG_PRIMS) +		fprintf(stderr, "%s\n", __FUNCTION__); + +	return GL_TRUE; + +#if 0 +   mgaContextPtr mmesa = MGA_CONTEXT(ctx); +   TNLcontext *tnl = TNL_CONTEXT(ctx); +   struct vertex_buffer *VB = &tnl->vb; +   GLuint i; + +   /* Don't handle clipping or indexed vertices or vertex manipulations. +    */ +   if (mmesa->RenderIndex != 0 || +       !mga_validate_render( ctx, VB )) { +      return GL_TRUE; +   } + +   tnl->Driver.Render.Start( ctx ); +   mmesa->SetupNewInputs = ~0; + +   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; + +      if (!length) +	 continue; + +      mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length, +						   prim); +   } + +   tnl->Driver.Render.Finish( ctx ); + +   return GL_FALSE;		/* finished the pipe */ +#endif +} + + +/** + * Called by the pipeline manager once before rendering. + * We check the GL state here to + *  a) decide whether we can do the current state in hardware and + *  b) update hardware registers + */ +#define FALLBACK_IF(expr) \ +do {										\ +	if (expr) {								\ +		if (RADEON_DEBUG & DEBUG_FALLBACKS)				\ +			fprintf(stderr, "%s: fallback:%s\n",			\ +				__FUNCTION__, #expr);				\ +		stage->active = GL_FALSE;					\ +		return;								\ +	}									\ +} while(0) + +static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage) +{ +	r300ContextPtr r300 = R300_CONTEXT(ctx); +	int i; + +	if (RADEON_DEBUG & DEBUG_STATE) +		fprintf(stderr, "%s\n", __FUNCTION__); + +	/* We only support rendering in hardware for now */ +	if (ctx->RenderMode != GL_RENDER) { +		stage->active = GL_FALSE; +		return; +	} + +	// I failed to figure out how dither works in hardware, +	// let's just ignore it for now +	//FALLBACK_IF(ctx->Color.DitherFlag); + +	/* I'm almost certain I forgot something here */ +	FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST +	FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND +	FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG +	FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH +	FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE +	FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH +	if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) +		FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV +	FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT +	FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE +	FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL +	FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH +	FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE +	FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST +	FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB + +	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) +		FALLBACK_IF(ctx->Texture.Unit[i].Enabled); + +	stage->active = GL_FALSE; +} + + +static void dtr(struct tnl_pipeline_stage *stage) +{ +	(void)stage; +} + +const struct tnl_pipeline_stage _r300_render_stage = { +	"r300 hw rasterize", +	_NEW_ALL,		/* re-check (always re-check for now) */ +	0,			/* re-run (always runs) */ +	GL_TRUE,		/* active */ +	0, 0,			/* inputs (set in check_render), outputs */ +	0, 0,			/* changed_inputs, private */ +	dtr,			/* destructor */ +	r300_check_render,	/* check */ +	r300_run_render		/* run */ +}; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index df71995b5e..48f01643aa 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -59,16 +59,66 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  /** + * Update our tracked culling state based on Mesa's state. + */ +static void r300UpdateCulling(GLcontext* ctx) +{ +	r300ContextPtr r300 = R300_CONTEXT(ctx); +	uint32_t val = 0; + +	R300_STATECHANGE(r300, cul); +	if (ctx->Polygon.CullFlag) { +		if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) +			val = R300_CULL_FRONT|R300_CULL_BACK; +		else if (ctx->Polygon.CullFaceMode == GL_FRONT) +			val = R300_CULL_FRONT; +		else +			val = R300_CULL_BACK; + +		if (ctx->Polygon.FrontFace == GL_CW) +			val |= R300_FRONT_FACE_CW; +		else +			val |= R300_FRONT_FACE_CCW; +	} + +	r300->hw.cul.cmd[R300_CUL_CULL] = val; +} + + +/**   * Handle glEnable()/glDisable(). + * + * \note Mesa already filters redundant calls to glEnable/glDisable.   */  static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)  { +	r300ContextPtr r300 = R300_CONTEXT(ctx); +	uint32_t newval; +  	if (RADEON_DEBUG & DEBUG_STATE)  		fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,  			_mesa_lookup_enum_by_nr(cap),  			state ? "GL_TRUE" : "GL_FALSE");  	switch (cap) { +	case GL_DEPTH_TEST: +		R300_STATECHANGE(r300, zc); + +		if (state) { +			if (ctx->Depth.Mask) +				newval = R300_RB3D_Z_TEST_AND_WRITE; +			else +				newval = R300_RB3D_Z_TEST; +		} else +			newval = 0; + +		r300->hw.zc.cmd[R300_ZC_CNTL_0] = newval; +		break; + +	case GL_CULL_FACE: +		r300UpdateCulling(ctx); +		break; +  	default:  		radeonEnable(ctx, cap, state);  		return; @@ -77,6 +127,90 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)  /** + * Change the culling mode. + * + * \note Mesa already filters redundant calls to this function. + */ +static void r300CullFace(GLcontext* ctx, GLenum mode) +{ +	(void)mode; + +	r300UpdateCulling(ctx); +} + + +/** + * Change the polygon orientation. + * + * \note Mesa already filters redundant calls to this function. + */ +static void r300FrontFace(GLcontext* ctx, GLenum mode) +{ +	(void)mode; + +	r300UpdateCulling(ctx); +} + + +/** + * Change the depth testing function. + * + * \note Mesa already filters redundant calls to this function. + */ +static void r300DepthFunc(GLcontext* ctx, GLenum func) +{ +	r300ContextPtr r300 = R300_CONTEXT(ctx); + +	R300_STATECHANGE(r300, zc); + +	switch(func) { +	case GL_NEVER: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEVER; +		break; +	case GL_LESS: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LESS; +		break; +	case GL_EQUAL: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_EQUAL; +		break; +	case GL_LEQUAL: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LEQUAL; +		break; +	case GL_GREATER: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GREATER; +		break; +	case GL_NOTEQUAL: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEQUAL; +		break; +	case GL_GEQUAL: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GEQUAL; +		break; +	case GL_ALWAYS: +		r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_ALWAYS; +		break; +	} +} + + +/** + * Enable/Disable depth writing. + * + * \note Mesa already filters redundant calls to this function. + */ +static void r300DepthMask(GLcontext* ctx, GLboolean mask) +{ +	r300ContextPtr r300 = R300_CONTEXT(ctx); + +	if (!ctx->Depth.Test) +		return; + +	R300_STATECHANGE(r300, zc); +	r300->hw.zc.cmd[R300_ZC_CNTL_0] = mask +		? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST; +} + + +/**   * Handle glColorMask()   */  static void r300ColorMask(GLcontext* ctx, @@ -141,11 +275,17 @@ void r300ResetHwState(r300ContextPtr r300)  			r300PackFloat32(v[MAT_TZ]);  	} -	r300->hw.cmk.cmd[R300_CMK_COLORMASK] = -		(ctx->Color.ColorMask[BCOMP] ? R300_COLORMASK0_B : 0) | -		(ctx->Color.ColorMask[GCOMP] ? R300_COLORMASK0_G : 0) | -		(ctx->Color.ColorMask[RCOMP] ? R300_COLORMASK0_R : 0) | -		(ctx->Color.ColorMask[ACOMP] ? R300_COLORMASK0_A : 0); +	r300ColorMask(ctx, +		ctx->Color.ColorMask[RCOMP], +		ctx->Color.ColorMask[GCOMP], +		ctx->Color.ColorMask[BCOMP], +		ctx->Color.ColorMask[ACOMP]); + +	r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); +	r300DepthMask(ctx, ctx->Depth.Mask); +	r300DepthFunc(ctx, ctx->Depth.Func); + +	r300UpdateCulling(ctx);  //BEGIN: TODO  	r300->hw.unk2080.cmd[1] = 0x0030045A; @@ -233,7 +373,6 @@ void r300ResetHwState(r300ContextPtr r300)  	r300->hw.unk42A0.cmd[1] = 0x00000000;  	r300->hw.unk42B4.cmd[1] = 0x00000000; -	r300->hw.unk42B4.cmd[2] = 0x00000000;  	r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;  	r300->hw.unk42C0.cmd[2] = 0x00000000; @@ -312,9 +451,6 @@ void r300ResetHwState(r300ContextPtr r300)  	r300->hw.unk4E88.cmd[1] = 0; -	r300->hw.zc.cmd[R300_ZC_CNTL_0] = 0; -	r300->hw.zc.cmd[R300_ZC_CNTL_1] = 0; -  	r300->hw.unk4F08.cmd[1] = 0x00FFFF00;  	r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format? @@ -383,5 +519,9 @@ void r300InitStateFuncs(struct dd_function_table* functions)  	functions->UpdateState = r300InvalidateState;  	functions->Enable = r300Enable;  	functions->ColorMask = r300ColorMask; +	functions->DepthFunc = r300DepthFunc; +	functions->DepthMask = r300DepthMask; +	functions->CullFace = r300CullFace; +	functions->FrontFace = r300FrontFace;  } | 
