diff options
| author | Dave Airlie <airlied@redhat.com> | 2009-03-23 18:27:49 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2009-03-23 18:54:06 +1000 | 
| commit | 8c7e30fb950c83f5e9e29e60735e999ac608145a (patch) | |
| tree | a82ebbc69cd0a814bad66c864113f0941c1c5cb8 /src | |
| parent | c607a664dd005c001afda1fff1a68d41925fa86e (diff) | |
raedon/r200/r300: mega-FBO commits.
Re work depth issues.
Do a lot more FBO abstactions
fixup depth/stencil buffer interactions
Diffstat (limited to 'src')
21 files changed, 605 insertions, 685 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index bf06c419d1..6fd0575898 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -72,6 +72,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #define need_GL_EXT_blend_func_separate  #define need_GL_NV_vertex_program  #define need_GL_ARB_point_parameters +#define need_GL_EXT_framebuffer_object  #include "extension_helper.h"  #define DRIVER_DATE	"20060602" @@ -124,6 +125,7 @@ const struct dri_extension card_extensions[] =      { "GL_EXT_blend_minmax",               GL_EXT_blend_minmax_functions },      { "GL_EXT_blend_subtract",             NULL },      { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions }, +    { "GL_EXT_packed_depth_stencil",	   NULL},      { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },      { "GL_EXT_stencil_wrap",               NULL },      { "GL_EXT_texture_edge_clamp",         NULL }, @@ -165,6 +167,11 @@ const struct dri_extension point_extensions[] = {      { NULL,                                NULL }  }; +const struct dri_extension mm_extensions[] = { +  { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, +  { NULL, NULL } +}; +  extern const struct tnl_pipeline_stage _r200_render_stage;  extern const struct tnl_pipeline_stage _r200_tcl_stage; @@ -418,6 +425,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,     _math_matrix_set_identity( &rmesa->tmpmat );     driInitExtensions( ctx, card_extensions, GL_TRUE ); + +   if (rmesa->radeon.radeonScreen->kernel_mm) +     driInitExtensions(ctx, mm_extensions, GL_FALSE);     if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {       /* yuv textures don't work with some chips - R200 / rv280 okay so far  	others get the bit ordering right but don't actually do YUV-RGB conversion */ diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index f7bad2a241..fcbe725d6f 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -621,21 +621,6 @@ struct r200_context {     GLboolean texmicrotile;    struct ati_fragment_shader *afs_loaded; - -  struct { -      struct gl_fragment_program *bitmap_fp; -      struct gl_vertex_program *passthrough_vp; - -      struct gl_fragment_program *saved_fp; -      GLboolean saved_fp_enable; -      struct gl_vertex_program *saved_vp; -      GLboolean saved_vp_enable; - -      GLint saved_vp_x, saved_vp_y; -      GLsizei saved_vp_width, saved_vp_height; -      GLenum saved_matrix_mode; -   } meta; -  };  #define R200_CONTEXT(ctx)		((r200ContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 96ed49665b..ccb56202f6 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -41,19 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "main/context.h"  #include "swrast/swrast.h" -#include "main/blend.h" -#include "main/bufferobj.h" -#include "main/buffers.h" -#include "main/depth.h" -#include "main/shaders.h" -#include "main/texstate.h" -#include "main/varray.h" -#include "glapi/dispatch.h" -#include "swrast/swrast.h" -#include "main/stencil.h" -#include "main/matrix.h" -#include "main/attrib.h" -#include "main/enable.h" +  #include "radeon_common.h"  #include "radeon_lock.h" @@ -70,217 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #define R200_TIMEOUT             512  #define R200_IDLE_RETRY           16 -static void -r200_meta_set_passthrough_transform(r200ContextPtr r200) -{ -   GLcontext *ctx = r200->radeon.glCtx; - -   r200->meta.saved_vp_x = ctx->Viewport.X; -   r200->meta.saved_vp_y = ctx->Viewport.Y; -   r200->meta.saved_vp_width = ctx->Viewport.Width; -   r200->meta.saved_vp_height = ctx->Viewport.Height; -   r200->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - -   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -} - -static void -r200_meta_restore_transform(r200ContextPtr r200) -{ -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PopMatrix(); -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PopMatrix(); - -   _mesa_MatrixMode(r200->meta.saved_matrix_mode); - -   _mesa_Viewport(r200->meta.saved_vp_x, r200->meta.saved_vp_y, -		  r200->meta.saved_vp_width, r200->meta.saved_vp_height); -} - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering.  The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ -static void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) -{ -   r200ContextPtr rmesa = R200_CONTEXT(ctx); -   GLfloat vertices[4][3]; -   GLfloat color[4][4]; -   GLfloat dst_z; -   struct gl_framebuffer *fb = ctx->DrawBuffer; -   int i; -   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; -   GLboolean saved_shader_program = 0; -   unsigned int saved_active_texture; -    -   assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT | -		    BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); - -   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | -		    GL_CURRENT_BIT | -		    GL_DEPTH_BUFFER_BIT | -		    GL_ENABLE_BIT | -		    GL_STENCIL_BUFFER_BIT | -		    GL_TRANSFORM_BIT | -		    GL_CURRENT_BIT); -   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); -   saved_active_texture = ctx->Texture.CurrentUnit; -   -  /* Disable existing GL state we don't want to apply to a clear. */ -   _mesa_Disable(GL_ALPHA_TEST); -   _mesa_Disable(GL_BLEND); -   _mesa_Disable(GL_CULL_FACE); -   _mesa_Disable(GL_FOG); -   _mesa_Disable(GL_POLYGON_SMOOTH); -   _mesa_Disable(GL_POLYGON_STIPPLE); -   _mesa_Disable(GL_POLYGON_OFFSET_FILL); -   _mesa_Disable(GL_LIGHTING); -   _mesa_Disable(GL_CLIP_PLANE0); -   _mesa_Disable(GL_CLIP_PLANE1); -   _mesa_Disable(GL_CLIP_PLANE2); -   _mesa_Disable(GL_CLIP_PLANE3); -   _mesa_Disable(GL_CLIP_PLANE4); -   _mesa_Disable(GL_CLIP_PLANE5); -   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { -      saved_fp_enable = GL_TRUE; -      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { -      saved_vp_enable = GL_TRUE; -      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { -      saved_shader_program = ctx->Shader.CurrentProgram->Name; -      _mesa_UseProgramObjectARB(0); -   } -    -   if (ctx->Texture._EnabledUnits != 0) { -      int i; -       -      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { -	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); -	 _mesa_Disable(GL_TEXTURE_1D); -	 _mesa_Disable(GL_TEXTURE_2D); -	 _mesa_Disable(GL_TEXTURE_3D); -	 if (ctx->Extensions.ARB_texture_cube_map) -	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); -	 if (ctx->Extensions.NV_texture_rectangle) -	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); -	 if (ctx->Extensions.MESA_texture_array) { -	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); -	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); -	 } -      } -   } -   -   r200_meta_set_passthrough_transform(rmesa); -    -   for (i = 0; i < 4; i++) { -      color[i][0] = ctx->Color.ClearColor[0]; -      color[i][1] = ctx->Color.ClearColor[1]; -      color[i][2] = ctx->Color.ClearColor[2]; -      color[i][3] = ctx->Color.ClearColor[3]; -   } - -   /* convert clear Z from [0,1] to NDC coord in [-1,1] */ -   dst_z = -1.0 + 2.0 * ctx->Depth.Clear; -    -   /* Prepare the vertices, which are the same regardless of which buffer we're -    * drawing to. -    */ -   vertices[0][0] = fb->_Xmin; -   vertices[0][1] = fb->_Ymin; -   vertices[0][2] = dst_z; -   vertices[1][0] = fb->_Xmax; -   vertices[1][1] = fb->_Ymin; -   vertices[1][2] = dst_z; -   vertices[2][0] = fb->_Xmax; -   vertices[2][1] = fb->_Ymax; -   vertices[2][2] = dst_z; -   vertices[3][0] = fb->_Xmin; -   vertices[3][1] = fb->_Ymax; -   vertices[3][2] = dst_z; - -   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); -   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); -   _mesa_Enable(GL_COLOR_ARRAY); -   _mesa_Enable(GL_VERTEX_ARRAY); - -   while (mask != 0) { -      GLuint this_mask = 0; - -      if (mask & BUFFER_BIT_BACK_LEFT) -	 this_mask = BUFFER_BIT_BACK_LEFT; -      else if (mask & BUFFER_BIT_FRONT_LEFT) -	 this_mask = BUFFER_BIT_FRONT_LEFT; - -      /* Clear depth/stencil in the same pass as color. */ -      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - -      /* Select the current color buffer and use the color write mask if -       * we have one, otherwise don't write any color channels. -       */ -      if (this_mask & BUFFER_BIT_FRONT_LEFT) -	 _mesa_DrawBuffer(GL_FRONT_LEFT); -      else if (this_mask & BUFFER_BIT_BACK_LEFT) -	 _mesa_DrawBuffer(GL_BACK_LEFT); -      else -	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - -      /* Control writing of the depth clear value to depth. */ -      if (this_mask & BUFFER_BIT_DEPTH) { -	 _mesa_DepthFunc(GL_ALWAYS); -	 _mesa_Enable(GL_DEPTH_TEST); -      } else { -	 _mesa_Disable(GL_DEPTH_TEST); -	 _mesa_DepthMask(GL_FALSE); -      } - -      /* Control writing of the stencil clear value to stencil. */ -      if (this_mask & BUFFER_BIT_STENCIL) { -	 _mesa_Enable(GL_STENCIL_TEST); -	 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); -	 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, -				   ctx->Stencil.WriteMask[0]); -      } else { -	 _mesa_Disable(GL_STENCIL_TEST); -      } - -      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); - -      mask &= ~this_mask; -   } - -   r200_meta_restore_transform(rmesa); - -   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); -   if (saved_fp_enable) -      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -   if (saved_vp_enable) -      _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - -   if (saved_shader_program) -      _mesa_UseProgramObjectARB(saved_shader_program); - -   _mesa_PopClientAttrib(); -   _mesa_PopAttrib(); -} - -  static void r200UserClear(GLcontext *ctx, GLuint mask)  {     radeon_clear_tris(ctx, mask); @@ -449,7 +226,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )        mask &= ~BUFFER_BIT_DEPTH;     } -   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) { +   if ( (mask & BUFFER_BIT_STENCIL) ) {        flags |= RADEON_STENCIL;        mask &= ~BUFFER_BIT_STENCIL;     } @@ -467,8 +244,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )        flags |= RADEON_USE_COMP_ZBUF;  /*      if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200)  	 flags |= RADEON_USE_HIERZ; */ -      if (!(rmesa->radeon.state.stencil.hwBuffer) || -	 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && +      if (!((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&  	    ((rmesa->radeon.state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) {  	  flags |= RADEON_CLEAR_FASTZ;        } diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 74824b8d24..ca4dee8a5b 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -740,7 +740,8 @@ static void r200PolygonOffset( GLcontext *ctx,  			       GLfloat factor, GLfloat units )  {     r200ContextPtr rmesa = R200_CONTEXT(ctx); -   float_ui32_type constant =  { units * rmesa->radeon.state.depth.scale }; +   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; +   float_ui32_type constant =  { units * depthScale };     float_ui32_type factoru = { factor };  /*    factor *= 2; */ @@ -1611,6 +1612,7 @@ void r200UpdateWindow( GLcontext *ctx )     GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;     const GLfloat *v = ctx->Viewport._WindowMap.m;     const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0); +   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;     GLfloat y_scale, y_bias;     if (render_to_fbo) { @@ -1625,8 +1627,8 @@ void r200UpdateWindow( GLcontext *ctx )     float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };     float_ui32_type sy = { v[MAT_SY] * y_scale };     float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y }; -   float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale }; -   float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale }; +   float_ui32_type sz = { v[MAT_SZ] * depthScale }; +   float_ui32_type tz = { v[MAT_TZ] * depthScale };     R200_STATECHANGE( rmesa, vpt ); @@ -2014,15 +2016,24 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )        break;     case GL_STENCIL_TEST: -      if ( rmesa->radeon.state.stencil.hwBuffer ) { -	 R200_STATECHANGE( rmesa, ctx ); -	 if ( state ) { -	    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE; +      { +	 GLboolean hw_stencil = GL_FALSE; +	 if (ctx->DrawBuffer) { +	    struct radeon_renderbuffer *rrbStencil +	       = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); +	    hw_stencil = (rrbStencil && rrbStencil->bo); +	 } + +	 if (hw_stencil) { +	    R200_STATECHANGE( rmesa, ctx ); +	    if ( state ) { +	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE; +	    } else { +	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; +	    }  	 } else { -	    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE; +	    FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );  	 } -      } else { -	 FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );        }        break; diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index a71f33ca3b..30326c2960 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -674,21 +674,15 @@ void r200InitState( r200ContextPtr rmesa )     switch ( ctx->Visual.depthBits ) {     case 16:        rmesa->radeon.state.depth.clear = 0x0000ffff; -      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff;        rmesa->radeon.state.stencil.clear = 0x00000000;        break;     case 24:     default:        rmesa->radeon.state.depth.clear = 0x00ffffff; -      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff;        rmesa->radeon.state.stencil.clear = 0xffff0000;        break;     } -   /* Only have hw stencil when depth buffer is 24 bits deep */ -   rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && -				     ctx->Visual.depthBits == 24 ); -     rmesa->radeon.Fallback = 0;     rmesa->radeon.hw.max_state_size = 0; diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index cf0557d6a2..c6bd69ed14 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -113,7 +113,7 @@ const struct dri_extension card_extensions[] = {    {"GL_EXT_blend_func_separate",	GL_EXT_blend_func_separate_functions},    {"GL_EXT_blend_minmax",		GL_EXT_blend_minmax_functions},    {"GL_EXT_blend_subtract",		NULL}, -   { "GL_EXT_framebuffer_object",       GL_EXT_framebuffer_object_functions }, +  {"GL_EXT_packed_depth_stencil",	NULL},    {"GL_EXT_fog_coord",			GL_EXT_fog_coord_functions },    {"GL_EXT_gpu_program_parameters",     GL_EXT_gpu_program_parameters_functions},    {"GL_EXT_secondary_color", 		GL_EXT_secondary_color_functions}, @@ -141,6 +141,11 @@ const struct dri_extension card_extensions[] = {  }; +const struct dri_extension mm_extensions[] = { +  { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, +  { NULL, NULL } +}; +  /**   * The GL 2.0 functions are needed to make display lists work with   * functions added by GL_ATI_separate_stencil. @@ -421,6 +426,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,  	ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;  	driInitExtensions(ctx, card_extensions, GL_TRUE); +	if (r300->radeon.radeonScreen->kernel_mm) +	  driInitExtensions(ctx, mm_extensions, GL_FALSE);  	if (driQueryOptionb  	    (&r300->radeon.optionCache, "disable_stencil_two_side")) diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index d4acbd7e99..71661eef19 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -66,6 +66,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #define CLEARBUFFER_DEPTH	0x2  #define CLEARBUFFER_STENCIL	0x4 +static void r300EmitClearState(GLcontext * ctx); + +static void r300UserClear(GLcontext *ctx, GLuint mask) +{ +	radeon_clear_tris(ctx, mask); +} +  static void r300ClearBuffer(r300ContextPtr r300, int flags,  			    struct radeon_renderbuffer *rrb,  			    struct radeon_renderbuffer *rrbd) @@ -534,6 +541,47 @@ static void r300EmitClearState(GLcontext * ctx)  	}  } +static void r300KernelClear(GLcontext *ctx, GLuint flags) +{	  	 +	r300ContextPtr r300 = R300_CONTEXT(ctx); +	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; +	struct radeon_framebuffer *rfb = dPriv->driverPrivate; +	struct radeon_renderbuffer *rrb; +	struct radeon_renderbuffer *rrbd; +	int bits = 0; + +	/* Make sure it fits there. */ +	rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); +	if (flags || bits) +		r300EmitClearState(ctx); +	rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); +	if (rrbd && (flags & BUFFER_BIT_DEPTH)) +		bits |= CLEARBUFFER_DEPTH; + +	if (flags & BUFFER_BIT_COLOR0) { +		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0); +		r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL); +		bits = 0; +	} +		 +	if (flags & BUFFER_BIT_FRONT_LEFT) { +		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); +		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); +		bits = 0; +	} + +	if (flags & BUFFER_BIT_BACK_LEFT) { +		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); +		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); +		bits = 0; +	} + +	if (bits) +		r300ClearBuffer(r300, bits, NULL, rrbd); + +	COMMIT_BATCH(); +} +  /**   * Buffer clear   */ @@ -541,16 +589,15 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)  {  	r300ContextPtr r300 = R300_CONTEXT(ctx);  	__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; -	struct radeon_framebuffer *rfb = dPriv->driverPrivate; -	struct radeon_renderbuffer *rrb; -	struct radeon_renderbuffer *rrbd; -	int flags = 0; -	int bits = 0; +	const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); +	GLbitfield swrast_mask = 0, tri_mask = 0; +	int i; +	struct gl_framebuffer *fb = ctx->DrawBuffer;  	if (RADEON_DEBUG & DEBUG_IOCTL)  		fprintf(stderr, "r300Clear\n"); -	{ +	if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {  		LOCK_HARDWARE(&r300->radeon);  		UNLOCK_HARDWARE(&r300->radeon);  		if (dPriv->numClipRects == 0) @@ -563,68 +610,52 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)  	 */  	R300_NEWPRIM(r300); -	if (mask & BUFFER_BIT_FRONT_LEFT) { -		flags |= BUFFER_BIT_FRONT_LEFT; -		mask &= ~BUFFER_BIT_FRONT_LEFT; -	} +	if (colorMask == ~0) +	  tri_mask |= (mask & BUFFER_BITS_COLOR); -	if (mask & BUFFER_BIT_BACK_LEFT) { -		flags |= BUFFER_BIT_BACK_LEFT; -		mask &= ~BUFFER_BIT_BACK_LEFT; -	} -	if (mask & BUFFER_BIT_DEPTH) { -		bits |= CLEARBUFFER_DEPTH; -		mask &= ~BUFFER_BIT_DEPTH; +	/* HW stencil */ +	if (mask & BUFFER_BIT_STENCIL) { +		tri_mask |= BUFFER_BIT_STENCIL;  	} -	if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) { -		bits |= CLEARBUFFER_STENCIL; -		mask &= ~BUFFER_BIT_STENCIL; +	/* HW depth */ +	if (mask & BUFFER_BIT_DEPTH) { +    	  tri_mask |= BUFFER_BIT_DEPTH;  	} -	if (mask & BUFFER_BIT_COLOR0) { -		flags |= BUFFER_BIT_COLOR0; -		mask &= ~BUFFER_BIT_COLOR0; -	} +	/* If we're doing a tri pass for depth/stencil, include a likely color +	 * buffer with it. +	 */ -	if (mask) { -		if (RADEON_DEBUG & DEBUG_FALLBACKS) -			fprintf(stderr, "%s: swrast clear, mask: %x\n", -				__FUNCTION__, mask); -		_swrast_Clear(ctx, mask); +	for (i = 0; i < BUFFER_COUNT; i++) { +	  GLuint bufBit = 1 << i; +	  if ((tri_mask) & bufBit) { +	    if (!fb->Attachment[i].Renderbuffer->ClassID) { +	      tri_mask &= ~bufBit; +	      swrast_mask |= bufBit; +	    } +	  }  	} -	/* Make sure it fits there. */ -	rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); -	if (flags || bits) -		r300EmitClearState(ctx); -	rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; +	/* SW fallback clearing */ +	swrast_mask = mask & ~tri_mask; -	if (flags & BUFFER_BIT_COLOR0) { -		rrb = (void *)rfb->base.Attachment[BUFFER_COLOR0].Renderbuffer; -		r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL); -		bits = 0; -	} -		 -	if (flags & BUFFER_BIT_FRONT_LEFT) { -		rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; -		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); -		bits = 0; +	if (tri_mask) { +		if (r300->radeon.radeonScreen->kernel_mm) +			r300UserClear(ctx, tri_mask); +		else +			r300KernelClear(ctx, tri_mask);  	} - -	if (flags & BUFFER_BIT_BACK_LEFT) { -		rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; -		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); -		bits = 0; +	if (swrast_mask) { +		if (RADEON_DEBUG & DEBUG_FALLBACKS) +			fprintf(stderr, "%s: swrast clear, mask: %x\n", +				__FUNCTION__, swrast_mask); +		_swrast_Clear(ctx, swrast_mask);  	} - -	if (bits) -		r300ClearBuffer(r300, bits, NULL, rrbd); - -	COMMIT_BATCH();  } +  void r300InitIoctlFuncs(struct dd_function_table *functions)  {  	functions->Clear = r300Clear; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 02f29a0a2f..f49b43c207 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -587,8 +587,14 @@ static void r300SetDepthState(GLcontext * ctx)  static void r300SetStencilState(GLcontext * ctx, GLboolean state)  {  	r300ContextPtr r300 = R300_CONTEXT(ctx); +	GLboolean hw_stencil = GL_FALSE; +	if (ctx->DrawBuffer) { +		struct radeon_renderbuffer *rrbStencil +			= radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); +		hw_stencil = (rrbStencil && rrbStencil->bo); +	} -	if (r300->radeon.state.stencil.hwBuffer) { +	if (hw_stencil) {  		R300_STATECHANGE(r300, zs);  		if (state) {  			r300->hw.zs.cmd[R300_ZS_CNTL_0] |= @@ -933,7 +939,8 @@ static void r300UpdateWindow(GLcontext * ctx)  	GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;  	GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;  	const GLfloat *v = ctx->Viewport._WindowMap.m; -	const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0); +	const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; +	const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0);  	GLfloat y_scale, y_bias;  	if (render_to_fbo) { @@ -948,8 +955,8 @@ static void r300UpdateWindow(GLcontext * ctx)  	GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;  	GLfloat sy = v[MAT_SY] * y_scale;  	GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y; -	GLfloat sz = v[MAT_SZ] * rmesa->radeon.state.depth.scale; -	GLfloat tz = v[MAT_TZ] * rmesa->radeon.state.depth.scale; +	GLfloat sz = v[MAT_SZ] * depthScale; +	GLfloat tz = v[MAT_TZ] * depthScale;  	R300_STATECHANGE(rmesa, vpt); @@ -2032,7 +2039,7 @@ static void r300ResetHwState(r300ContextPtr r300)  		fprintf(stderr, "%s\n", __FUNCTION__);  	radeon_firevertices(&r300->radeon); -	r300UpdateWindow(ctx); +	//r300UpdateWindow(ctx);  	r300ColorMask(ctx,  		      ctx->Color.ColorMask[RCOMP], @@ -2207,16 +2214,6 @@ static void r300ResetHwState(r300ContextPtr r300)  	r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000;  	r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; -	rrb = r300->radeon.state.depth.rrb; -	if (rrb && rrb->bo && (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)) { -		/* XXX: Turn off when clearing buffers ? */ -		r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; - -		if (ctx->Visual.depthBits == 24) -			r300->hw.zb.cmd[R300_ZB_PITCH] |= -			    R300_DEPTHMICROTILE_TILED; -	} -  	r300->hw.zb_depthclearvalue.cmd[1] = 0;  	r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE; @@ -2530,10 +2527,6 @@ void r300InitState(r300ContextPtr r300)  	GLcontext *ctx = r300->radeon.glCtx;  	GLuint depth_fmt; -	/* Only have hw stencil when depth buffer is 24 bits deep */ -	r300->radeon.state.stencil.hwBuffer = (ctx->Visual.stencilBits > 0 && -					       ctx->Visual.depthBits == 24); -  	memset(&(r300->state.texture), 0, sizeof(r300->state.texture));  	r300ResetHwState(r300); diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h index f80f0f7b22..42607df967 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h +++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h @@ -36,7 +36,10 @@ struct drm_radeon_gem_info {  #endif - +uint32_t radeon_gem_bo_name(struct radeon_bo *dummy) +{ +  return 0; +}  static inline void *radeon_bo_manager_gem_ctor(int fd)  { diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 4fd54c06c3..9f646c4386 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -58,6 +58,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "tnl/t_pipeline.h"  #include "swrast_setup/swrast_setup.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/shaders.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "glapi/dispatch.h" +#include "swrast/swrast.h" +#include "main/stencil.h" +#include "main/matrix.h" +#include "main/attrib.h" +#include "main/enable.h" +#include "main/viewport.h" +  #include "dri_util.h"  #include "vblank.h" @@ -658,18 +673,20 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)  		/* none */  	if (fb->Name == 0) {  		if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { -			rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; +			rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);  			radeon->front_cliprects = GL_TRUE;  		} else { -			rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; +			rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);  			radeon->front_cliprects = GL_FALSE;  		}  	} else {  		/* user FBO in theory */  		struct radeon_renderbuffer *rrb; -		rrb = (void *)fb->_ColorDrawBuffers[0]; -		offset = rrb->draw_offset; -		rrbColor = rrb; +		rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]); +		if (rrb) { +			offset = rrb->draw_offset; +			rrbColor = rrb; +		}  		radeon->constant_cliprect = GL_TRUE;  	} @@ -679,9 +696,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)  		radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); -  	if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { -		rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; +		rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);  		if (rrbDepth && rrbDepth->bo) {  			radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);  		} else { @@ -692,16 +708,11 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)  		rrbDepth = NULL;  	} -	/* TODO stencil things */  	if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { -		rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; +		rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);  		if (rrbStencil && rrbStencil->bo) {  			radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);  			/* need to re-compute stencil hw state */ -			if (ctx->Driver.Enable != NULL) -				ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); -			else -				ctx->NewState |= _NEW_STENCIL;  			if (!rrbDepth)  				rrbDepth = rrbStencil;  		} else { @@ -727,27 +738,28 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)  	 * Update depth test state  	 */  	if (ctx->Driver.Enable) { -		if (ctx->Depth.Test && fb->Visual.depthBits > 0) { -			ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); -		} else { -			ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); -		} +		ctx->Driver.Enable(ctx, GL_DEPTH_TEST, +				   (ctx->Depth.Test && fb->Visual.depthBits > 0)); +		ctx->Driver.Enable(ctx, GL_STENCIL_TEST, +				   (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));  	} else { -		ctx->NewState |= _NEW_DEPTH; +		ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);  	}  	radeon->state.depth.rrb = rrbDepth; -  	radeon->state.color.rrb = rrbColor;  	radeon->state.color.draw_offset = offset; +#if 0  	/* update viewport since it depends on window size */  	if (ctx->Driver.Viewport) {  		ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,  				     ctx->Viewport.Width, ctx->Viewport.Height);  	} else { -		ctx->NewState |= _NEW_VIEWPORT; +	  	} +#endif +	ctx->NewState |= _NEW_VIEWPORT;  	/* Set state we know depends on drawable parameters:  	 */ @@ -755,6 +767,19 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)  		ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,  				    ctx->Scissor.Width, ctx->Scissor.Height);  	radeon->NewGLState |= _NEW_SCISSOR; + +	if (ctx->Driver.DepthRange) +		ctx->Driver.DepthRange(ctx, +				       ctx->Viewport.Near, +				       ctx->Viewport.Far); + +	/* Update culling direction which changes depending on the +	 * orientation of the buffer: +	 */ +	if (ctx->Driver.FrontFace) +		ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); +	else +		ctx->NewState |= _NEW_POLYGON;  }  /** @@ -802,10 +827,6 @@ void radeonUpdatePageFlipping(radeonContextPtr radeon)  void radeon_window_moved(radeonContextPtr radeon)  { -	GLcontext *ctx = radeon->glCtx; -	__DRIdrawablePrivate *dPriv = radeon->dri.drawable; -	struct radeon_framebuffer *rfb = dPriv->driverPrivate; -  	if (!radeon->radeonScreen->driScreen->dri2.enabled) {  		radeonUpdatePageFlipping(radeon);  	} @@ -949,8 +970,14 @@ void radeonFinish(GLcontext * ctx)  	if (radeon->radeonScreen->kernel_mm) {  		for (i = 0; i < fb->_NumColorDrawBuffers; i++) {  			struct radeon_renderbuffer *rrb; -			rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i]; -			if (rrb->bo) +			rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]); +			if (rrb && rrb->bo) +				radeon_bo_wait(rrb->bo); +		} +		{ +			struct radeon_renderbuffer *rrb; +			rrb = radeon_get_depthbuffer(radeon); +			if (rrb && rrb->bo)  				radeon_bo_wait(rrb->bo);  		}  	} else if (radeon->do_irqs) { @@ -1108,3 +1135,219 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n, +static void +radeon_meta_set_passthrough_transform(radeonContextPtr radeon) +{ +   GLcontext *ctx = radeon->glCtx; + +   radeon->meta.saved_vp_x = ctx->Viewport.X; +   radeon->meta.saved_vp_y = ctx->Viewport.Y; +   radeon->meta.saved_vp_width = ctx->Viewport.Width; +   radeon->meta.saved_vp_height = ctx->Viewport.Height; +   radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; + +   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + +   _mesa_MatrixMode(GL_PROJECTION); +   _mesa_PushMatrix(); +   _mesa_LoadIdentity(); +   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + +   _mesa_MatrixMode(GL_MODELVIEW); +   _mesa_PushMatrix(); +   _mesa_LoadIdentity(); +} + +static void +radeon_meta_restore_transform(radeonContextPtr radeon) +{ +   _mesa_MatrixMode(GL_PROJECTION); +   _mesa_PopMatrix(); +   _mesa_MatrixMode(GL_MODELVIEW); +   _mesa_PopMatrix(); + +   _mesa_MatrixMode(radeon->meta.saved_matrix_mode); + +   _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, +		  radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); +} + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering.  The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ + + +void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) +{ +   radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +   GLfloat vertices[4][3]; +   GLfloat color[4][4]; +   GLfloat dst_z; +   struct gl_framebuffer *fb = ctx->DrawBuffer; +   int i; +   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; +   GLboolean saved_shader_program = 0; +   unsigned int saved_active_texture; + +   assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | +		    BUFFER_BIT_STENCIL)) == 0);    + +   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | +		    GL_CURRENT_BIT | +		    GL_DEPTH_BUFFER_BIT | +		    GL_ENABLE_BIT | +		    GL_STENCIL_BUFFER_BIT | +		    GL_TRANSFORM_BIT | +		    GL_CURRENT_BIT); +   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); +   saved_active_texture = ctx->Texture.CurrentUnit; +   +  /* Disable existing GL state we don't want to apply to a clear. */ +   _mesa_Disable(GL_ALPHA_TEST); +   _mesa_Disable(GL_BLEND); +   _mesa_Disable(GL_CULL_FACE); +   _mesa_Disable(GL_FOG); +   _mesa_Disable(GL_POLYGON_SMOOTH); +   _mesa_Disable(GL_POLYGON_STIPPLE); +   _mesa_Disable(GL_POLYGON_OFFSET_FILL); +   _mesa_Disable(GL_LIGHTING); +   _mesa_Disable(GL_CLIP_PLANE0); +   _mesa_Disable(GL_CLIP_PLANE1); +   _mesa_Disable(GL_CLIP_PLANE2); +   _mesa_Disable(GL_CLIP_PLANE3); +   _mesa_Disable(GL_CLIP_PLANE4); +   _mesa_Disable(GL_CLIP_PLANE5); +   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { +      saved_fp_enable = GL_TRUE; +      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); +   } +   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { +      saved_vp_enable = GL_TRUE; +      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); +   } +   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { +      saved_shader_program = ctx->Shader.CurrentProgram->Name; +      _mesa_UseProgramObjectARB(0); +   } +    +   if (ctx->Texture._EnabledUnits != 0) { +      int i; +       +      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { +	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); +	 _mesa_Disable(GL_TEXTURE_1D); +	 _mesa_Disable(GL_TEXTURE_2D); +	 _mesa_Disable(GL_TEXTURE_3D); +	 if (ctx->Extensions.ARB_texture_cube_map) +	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); +	 if (ctx->Extensions.NV_texture_rectangle) +	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); +	 if (ctx->Extensions.MESA_texture_array) { +	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); +	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); +	 } +      } +   } +   +   radeon_meta_set_passthrough_transform(rmesa); +    +   for (i = 0; i < 4; i++) { +      color[i][0] = ctx->Color.ClearColor[0]; +      color[i][1] = ctx->Color.ClearColor[1]; +      color[i][2] = ctx->Color.ClearColor[2]; +      color[i][3] = ctx->Color.ClearColor[3]; +   } + +   /* convert clear Z from [0,1] to NDC coord in [-1,1] */ + +   dst_z = -1.0 + 2.0 * ctx->Depth.Clear; +   /* Prepare the vertices, which are the same regardless of which buffer we're +    * drawing to. +    */ +   vertices[0][0] = fb->_Xmin; +   vertices[0][1] = fb->_Ymin; +   vertices[0][2] = dst_z; +   vertices[1][0] = fb->_Xmax; +   vertices[1][1] = fb->_Ymin; +   vertices[1][2] = dst_z; +   vertices[2][0] = fb->_Xmax; +   vertices[2][1] = fb->_Ymax; +   vertices[2][2] = dst_z; +   vertices[3][0] = fb->_Xmin; +   vertices[3][1] = fb->_Ymax; +   vertices[3][2] = dst_z; + +   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); +   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); +   _mesa_Enable(GL_COLOR_ARRAY); +   _mesa_Enable(GL_VERTEX_ARRAY); + +   while (mask != 0) { +      GLuint this_mask = 0; +      GLuint color_bit; + +      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); +      if (color_bit != 0) +	 this_mask |= (1 << (color_bit - 1)); + +      /* Clear depth/stencil in the same pass as color. */ +      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); + +      /* Select the current color buffer and use the color write mask if +       * we have one, otherwise don't write any color channels. +       */ +      if (this_mask & BUFFER_BIT_FRONT_LEFT) +	 _mesa_DrawBuffer(GL_FRONT_LEFT); +      else if (this_mask & BUFFER_BIT_BACK_LEFT) +	 _mesa_DrawBuffer(GL_BACK_LEFT); +      else if (color_bit != 0) +	 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + +			  (color_bit - BUFFER_COLOR0 - 1)); +      else +	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + +      /* Control writing of the depth clear value to depth. */ +      if (this_mask & BUFFER_BIT_DEPTH) { +	 _mesa_DepthFunc(GL_ALWAYS); +	 _mesa_DepthMask(GL_TRUE); +	 _mesa_Enable(GL_DEPTH_TEST); +      } else { +	 _mesa_Disable(GL_DEPTH_TEST); +	 _mesa_DepthMask(GL_FALSE); +      } + +      /* Control writing of the stencil clear value to stencil. */ +      if (this_mask & BUFFER_BIT_STENCIL) { +	 _mesa_Enable(GL_STENCIL_TEST); +	 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); +	 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, +				   ctx->Stencil.WriteMask[0]); +      } else { +	 _mesa_Disable(GL_STENCIL_TEST); +      } + +      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + +      mask &= ~this_mask; +   } + +   radeon_meta_restore_transform(rmesa); + +   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); +   if (saved_fp_enable) +      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); +   if (saved_vp_enable) +      _mesa_Enable(GL_VERTEX_PROGRAM_ARB); + +   if (saved_shader_program) +      _mesa_UseProgramObjectARB(saved_shader_program); + +   _mesa_PopClientAttrib(); +   _mesa_PopAttrib(); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index c97492d742..f3e2290cab 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -5,6 +5,18 @@  #include "radeon_dma.h"  #include "radeon_texture.h" + +#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |			\ +			      BUFFER_BIT_FRONT_LEFT |			\ +			      BUFFER_BIT_COLOR0 |			\ +			      BUFFER_BIT_COLOR1 |			\ +			      BUFFER_BIT_COLOR2 |			\ +			      BUFFER_BIT_COLOR3 |			\ +			      BUFFER_BIT_COLOR4 |			\ +			      BUFFER_BIT_COLOR5 |			\ +			      BUFFER_BIT_COLOR6 |			\ +			      BUFFER_BIT_COLOR7) +  void radeonRecalcScissorRects(radeonContextPtr radeon);  void radeonSetCliprects(radeonContextPtr radeon);  void radeonUpdateScissor( GLcontext *ctx ); @@ -24,6 +36,8 @@ void radeonFlush(GLcontext *ctx);  void radeonFinish(GLcontext * ctx);  void radeonEmitState(radeonContextPtr radeon); +void radeon_clear_tris(GLcontext *ctx, GLbitfield mask); +  void radeon_window_moved(radeonContextPtr radeon);  void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb);  void radeonDrawBuffer( GLcontext *ctx, GLenum mode ); @@ -35,7 +49,10 @@ void radeon_get_cliprects(radeonContextPtr radeon,  			  int *x_off, int *y_off);  void radeon_fbo_init(struct radeon_context *radeon); -struct gl_renderbuffer * +void +radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, +			   struct radeon_bo *bo); +struct radeon_renderbuffer *  radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv);  static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)  { diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index a818440faf..f335eb0313 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -392,6 +392,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)  	struct radeon_framebuffer *draw;  	radeonContextPtr radeon;  	char *regname; +	struct radeon_bo *depth_bo, *bo;  	if (RADEON_DEBUG & DEBUG_DRI)  	    fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); @@ -448,7 +449,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)  			regname = "dri2 depth buffer";  			break;  		case __DRI_BUFFER_STENCIL: -			rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); +			rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);  			regname = "dri2 stencil buffer";  			break;  		case __DRI_BUFFER_ACCUM: @@ -463,25 +464,49 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)  			continue;  		if (rb->bo) { -			radeon_bo_unref(rb->bo); -			rb->bo = NULL; +			uint32_t name = radeon_gem_name_bo(rb->bo); +			if (name == buffers[i].name) +				continue;  		} + +		if (RADEON_DEBUG & DEBUG_DRI) +			fprintf(stderr, +				"attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", +				regname, buffers[i].name, buffers[i].attachment, +				buffers[i].cpp, buffers[i].pitch); +  		rb->cpp = buffers[i].cpp;  		rb->pitch = buffers[i].pitch;  		rb->width = drawable->w;  		rb->height = drawable->h;  		rb->has_surface = 0; -		rb->bo = radeon_bo_open(radeon->radeonScreen->bom, -					buffers[i].name, -					0, -					0, -					RADEON_GEM_DOMAIN_VRAM, -					buffers[i].flags); -		if (rb->bo == NULL) { -			fprintf(stderr, "failed to attach %s %d\n", -				regname, buffers[i].name); +		if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { +			if (RADEON_DEBUG & DEBUG_DRI) +				fprintf(stderr, "(reusing depth buffer as stencil)\n"); +			bo = depth_bo; +			radeon_bo_ref(bo); +		} else { +			bo = radeon_bo_open(radeon->radeonScreen->bom, +						buffers[i].name, +						0, +						0, +						RADEON_GEM_DOMAIN_VRAM, +						buffers[i].flags); +			if (bo == NULL) { + +				fprintf(stderr, "failed to attach %s %d\n", +					regname, buffers[i].name); +				 +			}  		} + +		if (buffers[i].attachment == __DRI_BUFFER_DEPTH) +			depth_bo = bo; + +		radeon_renderbuffer_set_bo(rb, bo); +		radeon_bo_unref(bo); +		      	}  	driUpdateFramebufferSize(radeon->glCtx, drawable); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 612cc97f25..0ce72c9198 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -123,7 +123,6 @@ struct radeon_colorbuffer_state {  struct radeon_depthbuffer_state {  	GLuint clear; -	GLfloat scale;  	struct radeon_renderbuffer *rrb;  }; @@ -137,7 +136,6 @@ struct radeon_scissor_state {  };  struct radeon_stencilbuffer_state { -	GLboolean hwBuffer;  	GLuint clear;		/* rb3d_stencilrefmask value */  }; @@ -444,9 +442,23 @@ struct radeon_context {     struct radeon_cmdbuf cmdbuf; -	drm_clip_rect_t fboRect; -	GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ -	GLboolean front_cliprects; +  drm_clip_rect_t fboRect; +  GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ +  GLboolean front_cliprects; + +  struct { +      struct gl_fragment_program *bitmap_fp; +      struct gl_vertex_program *passthrough_vp; + +      struct gl_fragment_program *saved_fp; +      GLboolean saved_fp_enable; +      struct gl_vertex_program *saved_vp; +      GLboolean saved_vp_enable; + +      GLint saved_vp_x, saved_vp_y; +      GLsizei saved_vp_width, saved_vp_height; +      GLenum saved_matrix_mode; +   } meta;     struct {  	   void (*get_lock)(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 3f69de8d27..ac945ecc4d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -66,6 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #define need_GL_EXT_blend_minmax  #define need_GL_EXT_fog_coord  #define need_GL_EXT_secondary_color +#define need_GL_EXT_framebuffer_object  #include "extension_helper.h"  #define DRIVER_DATE	"20061018" @@ -88,6 +89,7 @@ const struct dri_extension card_extensions[] =      { "GL_EXT_blend_logic_op",             NULL },      { "GL_EXT_blend_subtract",             GL_EXT_blend_minmax_functions },      { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions }, +    { "GL_EXT_packed_depth_stencil",	   NULL},      { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },      { "GL_EXT_stencil_wrap",               NULL },      { "GL_EXT_texture_edge_clamp",         NULL }, @@ -104,6 +106,11 @@ const struct dri_extension card_extensions[] =      { NULL,                                NULL }  }; +const struct dri_extension mm_extensions[] = { +  { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, +  { NULL, NULL } +}; +  extern const struct tnl_pipeline_stage _radeon_render_stage;  extern const struct tnl_pipeline_stage _radeon_tcl_stage; @@ -338,6 +345,8 @@ radeonCreateContext( const __GLcontextModes *glVisual,     }     driInitExtensions( ctx, card_extensions, GL_TRUE ); +   if (rmesa->radeon.radeonScreen->kernel_mm) +     driInitExtensions(ctx, mm_extensions, GL_FALSE);     if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100)        _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );     if (rmesa->radeon.glCtx->Mesa_DXTn) { diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 2015e96a74..5235a6e374 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -435,20 +435,6 @@ struct r100_context {  	GLuint c_textureBytes;  	GLuint c_vertexBuffers; -  struct { -      struct gl_fragment_program *bitmap_fp; -      struct gl_vertex_program *passthrough_vp; - -      struct gl_fragment_program *saved_fp; -      GLboolean saved_fp_enable; -      struct gl_vertex_program *saved_vp; -      GLboolean saved_vp_enable; - -      GLint saved_vp_x, saved_vp_y; -      GLsizei saved_vp_width, saved_vp_height; -      GLenum saved_matrix_mode; -   } meta; -  }; diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 7342f2295e..f914c8c8d0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -54,7 +54,6 @@ radeon_new_framebuffer(GLcontext *ctx, GLuint name)  static void  radeon_delete_renderbuffer(struct gl_renderbuffer *rb)  { -  GET_CURRENT_CONTEXT(ctx);    struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);    ASSERT(rrb); @@ -62,8 +61,6 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)    if (rrb && rrb->bo) {      radeon_bo_unref(rrb->bo);    } - -    _mesa_free(rrb);  } @@ -255,7 +252,7 @@ radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,     return GL_FALSE;  } -struct gl_renderbuffer * +struct radeon_renderbuffer *  radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)  {      struct radeon_renderbuffer *rrb; @@ -325,7 +322,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)      rrb->base.GetPointer = radeon_get_pointer;      rrb->bo = NULL; -    return &rrb->base; +    return rrb;  }  static struct gl_renderbuffer * @@ -383,6 +380,13 @@ radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb,        rrb->base.DataType = GL_UNSIGNED_BYTE;        DBG("Render to RGBA8 texture OK\n");     } +   else if (texImage->TexFormat == &_mesa_texformat_argb4444) { +      rrb->cpp = 2; +      rrb->base._ActualFormat = GL_RGBA4; +      rrb->base._BaseFormat = GL_RGBA; +      rrb->base.DataType = GL_UNSIGNED_BYTE; +      DBG("Render to RGBA4 texture OK\n"); +   }     else if (texImage->TexFormat == &_mesa_texformat_rgb565) {        rrb->cpp = 2;        rrb->base._ActualFormat = GL_RGB5; @@ -493,7 +497,7 @@ radeon_render_texture(GLcontext * ctx,         return;     } -   fprintf(stderr,"Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", +   DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",         _glthread_GetID(),         att->Texture->Name, newImage->Width, newImage->Height,         rrb->base.RefCount); @@ -558,4 +562,13 @@ void radeon_fbo_init(struct radeon_context *radeon)  } -   +void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, +				struct radeon_bo *bo) +{ +  struct radeon_bo *old; +  old = rb->bo; +  rb->bo = bo; +  radeon_bo_ref(bo); +  if (old) +    radeon_bo_unref(old); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 22584f4817..f18aa1a4da 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -419,218 +419,6 @@ void radeonEmitAOS( r100ContextPtr rmesa,   */  #define RADEON_MAX_CLEARS	256 - - -static void -r100_meta_set_passthrough_transform(r100ContextPtr r100) -{ -   GLcontext *ctx = r100->radeon.glCtx; - -   r100->meta.saved_vp_x = ctx->Viewport.X; -   r100->meta.saved_vp_y = ctx->Viewport.Y; -   r100->meta.saved_vp_width = ctx->Viewport.Width; -   r100->meta.saved_vp_height = ctx->Viewport.Height; -   r100->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - -   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -} - -static void -r100_meta_restore_transform(r100ContextPtr r100) -{ -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PopMatrix(); -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PopMatrix(); - -   _mesa_MatrixMode(r100->meta.saved_matrix_mode); - -   _mesa_Viewport(r100->meta.saved_vp_x, r100->meta.saved_vp_y, -		  r100->meta.saved_vp_width, r100->meta.saved_vp_height); -} - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering.  The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ -static void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) -{ -   r100ContextPtr rmesa = R100_CONTEXT(ctx); -   GLfloat vertices[4][3]; -   GLfloat color[4][4]; -   GLfloat dst_z; -   struct gl_framebuffer *fb = ctx->DrawBuffer; -   int i; -   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; -   GLboolean saved_shader_program = 0; -   unsigned int saved_active_texture; -    -   assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT | -		    BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); - -   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | -		    GL_CURRENT_BIT | -		    GL_DEPTH_BUFFER_BIT | -		    GL_ENABLE_BIT | -		    GL_STENCIL_BUFFER_BIT | -		    GL_TRANSFORM_BIT | -		    GL_CURRENT_BIT); -   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); -   saved_active_texture = ctx->Texture.CurrentUnit; -   -  /* Disable existing GL state we don't want to apply to a clear. */ -   _mesa_Disable(GL_ALPHA_TEST); -   _mesa_Disable(GL_BLEND); -   _mesa_Disable(GL_CULL_FACE); -   _mesa_Disable(GL_FOG); -   _mesa_Disable(GL_POLYGON_SMOOTH); -   _mesa_Disable(GL_POLYGON_STIPPLE); -   _mesa_Disable(GL_POLYGON_OFFSET_FILL); -   _mesa_Disable(GL_LIGHTING); -   _mesa_Disable(GL_CLIP_PLANE0); -   _mesa_Disable(GL_CLIP_PLANE1); -   _mesa_Disable(GL_CLIP_PLANE2); -   _mesa_Disable(GL_CLIP_PLANE3); -   _mesa_Disable(GL_CLIP_PLANE4); -   _mesa_Disable(GL_CLIP_PLANE5); -   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { -      saved_fp_enable = GL_TRUE; -      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { -      saved_vp_enable = GL_TRUE; -      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { -      saved_shader_program = ctx->Shader.CurrentProgram->Name; -      _mesa_UseProgramObjectARB(0); -   } -    -   if (ctx->Texture._EnabledUnits != 0) { -      int i; -       -      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { -	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); -	 _mesa_Disable(GL_TEXTURE_1D); -	 _mesa_Disable(GL_TEXTURE_2D); -	 _mesa_Disable(GL_TEXTURE_3D); -	 if (ctx->Extensions.ARB_texture_cube_map) -	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); -	 if (ctx->Extensions.NV_texture_rectangle) -	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); -	 if (ctx->Extensions.MESA_texture_array) { -	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); -	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); -	 } -      } -   } -   -   r100_meta_set_passthrough_transform(rmesa); -    -   for (i = 0; i < 4; i++) { -      color[i][0] = ctx->Color.ClearColor[0]; -      color[i][1] = ctx->Color.ClearColor[1]; -      color[i][2] = ctx->Color.ClearColor[2]; -      color[i][3] = ctx->Color.ClearColor[3]; -   } - -   /* convert clear Z from [0,1] to NDC coord in [-1,1] */ -   dst_z = -1.0 + 2.0 * ctx->Depth.Clear; -    -   /* Prepare the vertices, which are the same regardless of which buffer we're -    * drawing to. -    */ -   vertices[0][0] = fb->_Xmin; -   vertices[0][1] = fb->_Ymin; -   vertices[0][2] = dst_z; -   vertices[1][0] = fb->_Xmax; -   vertices[1][1] = fb->_Ymin; -   vertices[1][2] = dst_z; -   vertices[2][0] = fb->_Xmax; -   vertices[2][1] = fb->_Ymax; -   vertices[2][2] = dst_z; -   vertices[3][0] = fb->_Xmin; -   vertices[3][1] = fb->_Ymax; -   vertices[3][2] = dst_z; - -   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); -   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); -   _mesa_Enable(GL_COLOR_ARRAY); -   _mesa_Enable(GL_VERTEX_ARRAY); - -   while (mask != 0) { -      GLuint this_mask = 0; - -      if (mask & BUFFER_BIT_BACK_LEFT) -	 this_mask = BUFFER_BIT_BACK_LEFT; -      else if (mask & BUFFER_BIT_FRONT_LEFT) -	 this_mask = BUFFER_BIT_FRONT_LEFT; - -      /* Clear depth/stencil in the same pass as color. */ -      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - -      /* Select the current color buffer and use the color write mask if -       * we have one, otherwise don't write any color channels. -       */ -      if (this_mask & BUFFER_BIT_FRONT_LEFT) -	 _mesa_DrawBuffer(GL_FRONT_LEFT); -      else if (this_mask & BUFFER_BIT_BACK_LEFT) -	 _mesa_DrawBuffer(GL_BACK_LEFT); -      else -	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - -      /* Control writing of the depth clear value to depth. */ -      if (this_mask & BUFFER_BIT_DEPTH) { -	 _mesa_DepthFunc(GL_ALWAYS); -	 _mesa_Enable(GL_DEPTH_TEST); -      } else { -	 _mesa_Disable(GL_DEPTH_TEST); -	 _mesa_DepthMask(GL_FALSE); -      } - -      /* Control writing of the stencil clear value to stencil. */ -      if (this_mask & BUFFER_BIT_STENCIL) { -	 _mesa_Enable(GL_STENCIL_TEST); -	 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); -	 _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, -				   ctx->Stencil.WriteMask[0]); -      } else { -	 _mesa_Disable(GL_STENCIL_TEST); -      } - -      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); - -      mask &= ~this_mask; -   } - -   r100_meta_restore_transform(rmesa); - -   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); -   if (saved_fp_enable) -      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -   if (saved_vp_enable) -      _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - -   if (saved_shader_program) -      _mesa_UseProgramObjectARB(saved_shader_program); - -   _mesa_PopClientAttrib(); -   _mesa_PopAttrib(); -} -  static void radeonUserClear(GLcontext *ctx, GLuint mask)  {     radeon_clear_tris(ctx, mask); @@ -795,7 +583,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )        mask &= ~BUFFER_BIT_DEPTH;     } -   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) { +   if ( (mask & BUFFER_BIT_STENCIL) ) {        flags |= RADEON_STENCIL;        mask &= ~BUFFER_BIT_STENCIL;     } @@ -813,8 +601,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )        flags |= RADEON_USE_COMP_ZBUF;  /*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)            flags |= RADEON_USE_HIERZ; */ -      if (!(rmesa->radeon.state.stencil.hwBuffer) || -	 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && +      if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&  	    ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {  	  flags |= RADEON_CLEAR_FASTZ;        } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index a14a0c3cb2..4725f38ae8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1086,6 +1086,9 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)     else        screen->chip_flags |= RADEON_CLASS_R300; +   if (getenv("R300_NO_TCL")) +     screen->chip_flags &= ~RADEON_CHIPSET_TCL; +     i = 0;     screen->extensions[i++] = &driCopySubBufferExtension.base;     screen->extensions[i++] = &driFrameTrackingExtension.base; @@ -1197,7 +1200,6 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,      const GLboolean swStencil = mesaVis->stencilBits > 0 &&  	mesaVis->depthBits != 24;      GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); -    GLenum depthFormat = GL_NONE;      struct radeon_framebuffer *rfb;      if (isPixmap) @@ -1209,37 +1211,35 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,      _mesa_initialize_framebuffer(&rfb->base, mesaVis); -    if (mesaVis->depthBits == 16) -	depthFormat = GL_DEPTH_COMPONENT16; -    else if (mesaVis->depthBits == 24) -	depthFormat = GL_DEPTH_COMPONENT24; -      /* front color renderbuffer */ -    rfb->color_rb[0] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv)); +    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);      _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);      rfb->color_rb[0]->has_surface = 1;      /* back color renderbuffer */      if (mesaVis->doubleBufferMode) { -      rfb->color_rb[1] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv)); +      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);  	_mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);  	rfb->color_rb[1]->has_surface = 1;      } -    /* depth renderbuffer */ -    if (depthFormat != GL_NONE) { -      struct radeon_renderbuffer *depth = radeon_renderbuffer( -							      radeon_create_renderbuffer(depthFormat, driDrawPriv)); +    if (mesaVis->depthBits == 24) { +      if (mesaVis->stencilBits == 8) { +	struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv); +	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base); +	_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base); +	depthStencilRb->has_surface = screen->depthHasSurface; +      } else { +	/* depth renderbuffer */ +	struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv); +	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); +	depth->has_surface = screen->depthHasSurface; +      } +    } else if (mesaVis->depthBits == 16) { +      /* just 16-bit depth buffer, no hw stencil */ +	struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv);  	_mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);  	depth->has_surface = screen->depthHasSurface; -    } - -    /* stencil renderbuffer */ -    if (mesaVis->stencilBits > 0 && !swStencil) { -      struct radeon_renderbuffer *stencil = radeon_renderbuffer( -								radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv)); -	_mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base); -	stencil->has_surface = screen->depthHasSurface;      }      _mesa_add_soft_renderbuffers(&rfb->base, diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 768a51b51d..3d2c5da4c0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -377,33 +377,64 @@ do {									\  #include "stenciltmp.h" -static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) +void map_unmap_rb(struct gl_renderbuffer *rb, int flag)  { -	struct radeon_renderbuffer *rrb = (void*)rb; +	struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);  	int r; -	if (rrb->bo) { -		r = radeon_bo_map(rrb->bo, write); +	if (rrb == NULL || !rrb->bo) +		return; + +	if (flag) { +		r = radeon_bo_map(rrb->bo, 1);  		if (r) {  			fprintf(stderr, "(%s) error(%d) mapping buffer.\n",  				__FUNCTION__, r);  		} -	} -	radeonSetSpanFunctions(rrb); +		radeonSetSpanFunctions(rrb); +	} else { +		radeon_bo_unmap(rrb->bo); +		rb->GetRow = NULL; +		rb->PutRow = NULL; +	}  } -static void unmap_buffer(struct gl_renderbuffer *rb) +static void +radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)  { -	struct radeon_renderbuffer *rrb = (void*)rb; +	radeonContextPtr rmesa = RADEON_CONTEXT(ctx); +	GLuint i, j; -	if (rrb->bo) { -		radeon_bo_unmap(rrb->bo); +	/* color draw buffers */ +	for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) +		map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map); + +	/* check for render to textures */ +	for (i = 0; i < BUFFER_COUNT; i++) { +		struct gl_renderbuffer_attachment *att = +			ctx->DrawBuffer->Attachment + i; +		struct gl_texture_object *tex = att->Texture; +		if (tex) { +			/* render to texture */ +			ASSERT(att->Renderbuffer); +			if (map) +				ctx->Driver.MapTexture(ctx, tex); +			else +				ctx->Driver.UnmapTexture(ctx, tex); +		}  	} -	rb->GetRow = NULL; -	rb->PutRow = NULL; -} +	 +	map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map); + +	/* depth buffer (Note wrapper!) */ +	if (ctx->DrawBuffer->_DepthBuffer) +		map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); +	 +	if (ctx->DrawBuffer->_StencilBuffer) +		map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map); +}  static void radeonSpanRenderStart(GLcontext * ctx)  {  	radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -416,18 +447,7 @@ static void radeonSpanRenderStart(GLcontext * ctx)  			ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);  	} -	/* color draw buffers */ -	for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { -		map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); -	} - -	map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); - -	if (ctx->DrawBuffer->_DepthBuffer) { -		map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); -	} -	if (ctx->DrawBuffer->_StencilBuffer) -		map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); +	radeon_map_unmap_buffers(ctx, 1);  	/* The locking and wait for idle should really only be needed in classic mode.  	 * In a future memory manager based implementation, this should become @@ -450,16 +470,7 @@ static void radeonSpanRenderFinish(GLcontext * ctx)  			ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);  	} -	/* color draw buffers */ -	for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) -		unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); - -	unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer); - -	if (ctx->DrawBuffer->_DepthBuffer) -		unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); -	if (ctx->DrawBuffer->_StencilBuffer) -		unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); +	radeon_map_unmap_buffers(ctx, 0);  }  void radeonInitSpanFuncs(GLcontext * ctx) @@ -485,6 +496,8 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)  		radeonInitDepthPointers_z16(&rrb->base);  	} else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) {  		radeonInitDepthPointers_z24_s8(&rrb->base); +	} else if (rrb->base._ActualFormat == GL_DEPTH24_STENCIL8_EXT) { +		radeonInitStencilPointers_z24_s8(&rrb->base);  	} else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) {  		radeonInitStencilPointers_z24_s8(&rrb->base);  	} diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 635fe43ce4..19ff2688e6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -528,7 +528,8 @@ static void radeonPolygonOffset( GLcontext *ctx,  				 GLfloat factor, GLfloat units )  {     r100ContextPtr rmesa = R100_CONTEXT(ctx); -   float_ui32_type constant =  { units * rmesa->radeon.state.depth.scale }; +   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; +   float_ui32_type constant =  { units * depthScale };     float_ui32_type factoru = { factor };     RADEON_STATECHANGE( rmesa, zbs ); @@ -1391,6 +1392,7 @@ void radeonUpdateWindow( GLcontext *ctx )     GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;     const GLfloat *v = ctx->Viewport._WindowMap.m;     const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0); +   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;     GLfloat y_scale, y_bias;     if (render_to_fbo) { @@ -1405,8 +1407,8 @@ void radeonUpdateWindow( GLcontext *ctx )     float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };     float_ui32_type sy = { v[MAT_SY] * y_scale };     float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y }; -   float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale }; -   float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale }; +   float_ui32_type sz = { v[MAT_SZ] * depthScale }; +   float_ui32_type tz = { v[MAT_TZ] * depthScale };     RADEON_STATECHANGE( rmesa, vpt ); @@ -1800,15 +1802,24 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )        break;     case GL_STENCIL_TEST: -      if ( rmesa->radeon.state.stencil.hwBuffer ) { -	 RADEON_STATECHANGE( rmesa, ctx ); -	 if ( state ) { -	    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE; +      { +	 GLboolean hw_stencil = GL_FALSE; +	 if (ctx->DrawBuffer) { +	    struct radeon_renderbuffer *rrbStencil +	       = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); +	    hw_stencil = (rrbStencil && rrbStencil->bo); +	 } + +	 if (hw_stencil) { +	    RADEON_STATECHANGE( rmesa, ctx ); +	    if ( state ) { +	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE; +	    } else { +	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; +	    }  	 } else { -	    rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; +	    FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );  	 } -      } else { -	 FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );        }        break; diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 8b6caf19d3..3d0cd8d3f8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -592,22 +592,16 @@ void radeonInitState( r100ContextPtr rmesa )     switch ( ctx->Visual.depthBits ) {     case 16:        rmesa->radeon.state.depth.clear = 0x0000ffff; -      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff;        rmesa->radeon.state.stencil.clear = 0x00000000;        break;     case 24:        rmesa->radeon.state.depth.clear = 0x00ffffff; -      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff;        rmesa->radeon.state.stencil.clear = 0xffff0000;        break;     default:        break;     } -   /* Only have hw stencil when depth buffer is 24 bits deep */ -   rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && -				     ctx->Visual.depthBits == 24 ); -     rmesa->radeon.Fallback = 0;  | 
