Hi, Dnia 28-01-2005, pią o godzinie 16:27 +0100, Roland Scheidegger napisał(a): > Jacek Rosik wrote: > > Hi, > > > > I have some questions about r200 depth tiling. Generally I'm also > > interested in r100 tiling too, but currently i work on r200. > > > > First of all in functions r200_mba_z16|32 from r200_span.c frontPitch > > offset is used. Is it intentional or just because depthOffset is > > also the same? Maybe it should be depthOffset? > Yes, I think depthPitch (you surely meant that, yes?) instead of > frontPitch might be a good idea. I don't think there's a good reason to > use frontPitch there, even though currently they are always the same.
Yes, I meant depthPitch. They are the same but only for resolutions where width is multiple of 32. Depth pitch is rounded to be multiple of 32. Hmm... I think that is wrong since tile size seems to depend on fb depth and probably tiles on r100 also have different sizes. So this is correct only for r200 with 32bpp fb depth. > > Depth tiles on r200 are 32x16 or 64x16, depending on FB depth, right? > > > > > Well, the span functions would indicate that. It doesn't quite match the > experiences made when implementing hyperz, however (where the same > number of tiles needed to be cleared regardless of 16 or 32bit z depth, > and tile size more seemed to correspond to 4x4 microtiles and 8x2 > macrotiles, thus a tile size of 32x8). I never really fully understood > that however, something just doesn't fit. See th drm clear code for details. Thanks, I'll take a look at it. > > I don't quite follow third line before last? Can someone enlighten > > me? > You mean the pitch & 0x20 stuff? Yeah, looks strange. > Looking at it, it seems like it ensures that each "block line" starts > with alternating 2KB addresses (i.e. that 11th-bit). So y 0-15 will have > set that (for x 0-31) to 0, y 16-31 to 1 and so on. > Seems to me like it might be related to how the ram is organized (e.g. > something like ensuring it's on a different memory channel or different > bank or whatnot). Yeah, I thought something similar. > This is, btw, quite similarly strange to what Stephane needed on his > rv100 to get the correct pixel address for color tiling, this one also > tinkered with that 11th bit (see RadeonDoAdjustFrame). > > > Generally if one could explain tiling a bit for me I would be > > grateful. What I'm trying to do is to is to modify depthOffset to be > > as close to top-left corner of viewport as possible and modify. I > > this possible with shared depth buffer. This means that each 3D > > window would have different depthOffset but pointing to the same > > shared buffer. > I'm not sure if it's possible to do that with depthOffset (well maybe). > There is however an interesting bit in RB3D_CNTL > (R200_DEPTH_XZ_OFFEST_ENABLE, I guess "XZ" is a typo, just as is > "OFFEST"?) and the corresponding (?) register > (R200_RB3D_DEPTHXY_OFFSET), which sound to me like they are exactly > invented for that... So this would mean that depth buffer can start at different x,y than color buffer? Can someone with the docs confirm that. Anyway I think I will experiment with it a little more and see what I'll get. Unfortunately I'll be quite busy in next weeks, but I hope I'll get back to it soon. BTW: I have working solution for color but I wonder if this will work with color tiling. Of course offset Would have to be aligned to the closest tile. Can You take a look at it? (It's missing some bits but generaly apps which don't use depth should work Unfortunately I don't think there are many ;). Attached is a patch. Any comments are welcome. Best, -- Jacek Rosik <[EMAIL PROTECTED]>
Index: src/mesa/drivers/dri/r200/r200_state_init.c =================================================================== --- src/mesa/drivers/dri/r200/r200_state_init.c (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_state_init.c (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -492,6 +492,10 @@ else rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; + /* Note that offset will get recalculated later on, when context + * will be bound to a window. It will point to the top left corner + * of window's viewport. + */ rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset + rmesa->r200Screen->fbLocation) & R200_COLOROFFSET_MASK); Index: src/mesa/drivers/dri/r200/r200_ioctl.c =================================================================== --- src/mesa/drivers/dri/r200/r200_ioctl.c (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_ioctl.c (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -138,10 +138,10 @@ if (rmesa->state.scissor.enabled) { cmd.nbox = rmesa->state.scissor.numClipRects; - cmd.boxes = (drm_clip_rect_t *)rmesa->state.scissor.pClipRects; + cmd.boxes = (drm_clip_rect_t *)rmesa->state.scissor.pClipRects3D; } else { cmd.nbox = rmesa->numClipRects; - cmd.boxes = (drm_clip_rect_t *)rmesa->pClipRects; + cmd.boxes = (drm_clip_rect_t *)rmesa->pClipRects3D; } ret = drmCommandWrite( rmesa->dri.fd, @@ -564,10 +564,7 @@ rmesa->state.color.drawPitch = rmesa->r200Screen->backPitch; } - R200_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset - + rmesa->r200Screen->fbLocation; - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; + r200RecalcAndUpdateColor( rmesa ); } @@ -579,6 +576,8 @@ { r200ContextPtr rmesa = R200_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + GLint xoffset = R200_CLIP3D_XOFFSET( rmesa ); + GLint yoffset = R200_CLIP3D_YOFFSET( rmesa ); GLuint flags = 0; GLuint color_mask = 0; GLint ret, i; @@ -726,10 +725,10 @@ n--; b = rmesa->sarea->boxes; for ( ; n >= 0 ; n-- ) { - depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1; - depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1; - depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2; - depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2; + depth_boxes[n].f[CLEAR_X1] = (float) ( b[n].x1 + xoffset ); + depth_boxes[n].f[CLEAR_Y1] = (float) ( b[n].y1 + yoffset ); + depth_boxes[n].f[CLEAR_X2] = (float) ( b[n].x2 + xoffset ); + depth_boxes[n].f[CLEAR_Y2] = (float) ( b[n].y2 + yoffset ); depth_boxes[n].f[CLEAR_DEPTH] = ctx->Depth.Clear; } Index: src/mesa/drivers/dri/r200/r200_state.c =================================================================== --- src/mesa/drivers/dri/r200/r200_state.c (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_state.c (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -548,7 +548,8 @@ void r200RecalcScissorRects( r200ContextPtr rmesa ) { - drm_clip_rect_t *out; + GLint xoffset, yoffset; + drm_clip_rect_t *out, *out3d; int i; /* Grow cliprect store? @@ -561,26 +562,43 @@ if (rmesa->state.scissor.pClipRects) FREE(rmesa->state.scissor.pClipRects); + if (rmesa->state.scissor.pClipRects3D) + FREE(rmesa->state.scissor.pClipRects3D); rmesa->state.scissor.pClipRects = MALLOC( rmesa->state.scissor.numAllocedClipRects * sizeof(drm_clip_rect_t) ); + rmesa->state.scissor.pClipRects3D = + MALLOC( rmesa->state.scissor.numAllocedClipRects * + sizeof(drm_clip_rect_t) ); - if ( rmesa->state.scissor.pClipRects == NULL ) { + if ( rmesa->state.scissor.pClipRects == NULL + || rmesa->state.scissor.pClipRects3D == NULL ) { rmesa->state.scissor.numAllocedClipRects = 0; return; } } out = rmesa->state.scissor.pClipRects; + out3d = rmesa->state.scissor.pClipRects3D; rmesa->state.scissor.numClipRects = 0; + xoffset = R200_CLIP3D_XOFFSET( rmesa ); + yoffset = R200_CLIP3D_YOFFSET( rmesa ); + for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { if ( intersect_rect( out, &rmesa->pClipRects[i], &rmesa->state.scissor.rect ) ) { rmesa->state.scissor.numClipRects++; - out++; + + out3d->x1 = out->x1 + xoffset; + out3d->x2 = out->x2 + xoffset; + out3d->y1 = out->y1 + yoffset; + out3d->y2 = out->y2 + yoffset; + + ++out; + ++out3d; } } } @@ -1604,17 +1622,32 @@ { r200ContextPtr rmesa = R200_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; - GLfloat xoffset = (GLfloat)dPriv->x; - GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; + GLint xoffset, yoffset; GLfloat sx = v[MAT_SX]; - GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; + GLfloat tx = SUBPIXEL_X + v[MAT_TX]; GLfloat sy = - v[MAT_SY]; - GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; + GLfloat ty = SUBPIXEL_Y - v[MAT_TY]; GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale; GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale; + /* Color offset may not point to the location left of or above + * current color buffer. In other situations it points to the top + * left corner of window's viewport, and will compensate for + * positive offests. + */ + xoffset = dPriv->x + ctx->Viewport.X; + yoffset = dPriv->y + dPriv->h - ctx->Viewport.X - ctx->Viewport.Height; + if ( xoffset < 0.0 ) + tx += (GLfloat) dPriv->x; + else + tx -= (GLfloat) ctx->Viewport.X - R200_DRAW_XBIAS( rmesa ); + if ( yoffset < 0.0 ) + ty += (GLfloat) (dPriv->y + dPriv->h); + else + ty += (GLfloat) ctx->Viewport.Height; + R200_FIREVERTICES( rmesa ); R200_STATECHANGE( rmesa, vpt ); @@ -1624,6 +1657,9 @@ rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = *(GLuint *)&sz; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz; + + r200RecalcAndUpdateColor( rmesa ); + r200UpdateCliprects( rmesa ); } @@ -1649,13 +1685,28 @@ { r200ContextPtr rmesa = R200_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; - GLfloat xoffset = (GLfloat)dPriv->x; - GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; + GLint xoffset, yoffset; - GLfloat tx = v[MAT_TX] + xoffset; - GLfloat ty = (- v[MAT_TY]) + yoffset; + GLfloat tx = SUBPIXEL_X + v[MAT_TX]; + GLfloat ty = SUBPIXEL_Y - v[MAT_TY]; + /* Color offset may not point to the location left of or above + * current color buffer. In other situations it points to the top + * left corner of window's viewport, and will compensate for + * positive offests. + */ + xoffset = dPriv->x + ctx->Viewport.X; + yoffset = dPriv->y + dPriv->h - ctx->Viewport.X - ctx->Viewport.Height; + if ( xoffset < 0.0 ) + tx += (GLfloat) dPriv->x; + else + tx -= (GLfloat) ctx->Viewport.X - R200_DRAW_XBIAS( rmesa ); + if ( yoffset < 0.0 ) + ty += (GLfloat) (dPriv->y + dPriv->h); + else + ty += (GLfloat) ctx->Viewport.Height; + if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx || rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty ) { @@ -1668,15 +1719,19 @@ /* update polygon stipple x/y screen offset */ { GLuint stx, sty; + GLint xoffset, yoffset; GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC]; m &= ~(R200_STIPPLE_X_OFFSET_MASK | R200_STIPPLE_Y_OFFSET_MASK); /* add magic offsets, then invert */ - stx = 31 - ((rmesa->dri.drawable->x - 1) & R200_STIPPLE_COORD_MASK); - sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1) - & R200_STIPPLE_COORD_MASK); + xoffset = R200_CLIP3D_XOFFSET( rmesa ) - ctx->Viewport.X; + xoffset += rmesa->dri.drawable->x - 1; + yoffset = R200_CLIP3D_YOFFSET( rmesa ) - ctx->Viewport.Y; + yoffset += rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1; + stx = 31 - ( xoffset & R200_STIPPLE_COORD_MASK ); + sty = 31 - ( yoffset & R200_STIPPLE_COORD_MASK ); m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) | (sty << R200_STIPPLE_Y_OFFSET_SHIFT)); @@ -1691,8 +1746,39 @@ r200UpdateScissor( ctx ); } +void r200RecalcAndUpdateColor( r200ContextPtr rmesa ) +{ + GLint x, y, offset, pitch; + GLcontext *ctx = rmesa->glCtx; + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + /* Color offset may not point to the location left of or above + * current color buffer. In other situations it points to the topn n + * left corner of window's viewport. + */ + x = dPriv->x; + if ( x < 0 ) x = 0 + ctx->Viewport.X; + y = (dPriv->y + dPriv->h) - (ctx->Viewport.Y + ctx->Viewport.Height); + if ( y < 0 ) y = 0; + pitch = rmesa->state.color.drawPitch; + offset = rmesa->state.color.drawOffset; + offset += x * rmesa->r200Screen->cpp; + offset += y * pitch * rmesa->r200Screen->cpp; + + rmesa->state.color.xbias = offset & ~R200_COLOROFFSET_MASK; + rmesa->state.color.xbias /= rmesa->r200Screen->cpp; + offset &= R200_COLOROFFSET_MASK; + + rmesa->state.color.drawOffset3D = offset; + offset += rmesa->r200Screen->fbLocation; + + R200_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = offset; + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = pitch; +} + + /* ============================================================= * Miscellaneous */ @@ -1757,6 +1843,7 @@ case GL_FRONT_LEFT: rmesa->numClipRects = dPriv->numClipRects; rmesa->pClipRects = dPriv->pClipRects; + rmesa->pClipRects3D = rmesa->pFrontClipRects3D; break; case GL_BACK_LEFT: /* Can't ignore 2d windows if we are page flipping. @@ -1764,10 +1851,12 @@ if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) { rmesa->numClipRects = dPriv->numClipRects; rmesa->pClipRects = dPriv->pClipRects; + rmesa->pClipRects3D = rmesa->pFrontClipRects3D; } else { rmesa->numClipRects = dPriv->numBackClipRects; rmesa->pClipRects = dPriv->pBackClipRects; + rmesa->pClipRects3D = rmesa->pBackClipRects3D; } break; default: @@ -1779,7 +1868,70 @@ r200RecalcScissorRects( rmesa ); } +void r200UpdateCliprects( r200ContextPtr rmesa ) +{ + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + GLuint nback = dPriv->numBackClipRects; + GLuint nfront = dPriv->numClipRects; + GLint xoffset, yoffset; + if ( rmesa->pFrontClipRects3D ) { + FREE( rmesa->pFrontClipRects3D ); + rmesa->pFrontClipRects3D = NULL; + } + if ( rmesa->pBackClipRects3D ) { + FREE( rmesa->pBackClipRects3D ); + rmesa->pBackClipRects3D = NULL; + } + + /* Calculate cliprect offset basing on difference between topleft + * screen offset and offset used by 3D engine. + */ + xoffset = R200_CLIP3D_XOFFSET( rmesa ); + yoffset = R200_CLIP3D_YOFFSET( rmesa ); + + if ( nfront ) { + rmesa->pFrontClipRects3D = MALLOC( nfront * sizeof( drm_clip_rect_t )); + + if ( rmesa->pFrontClipRects3D ) { + int i; + drm_clip_rect_t *src = dPriv->pClipRects; + drm_clip_rect_t *dest = rmesa->pFrontClipRects3D; + + for ( i = 0; i < nfront; ++i, ++src, ++dest ) { + dest->x1 = src->x1 + xoffset; + dest->x2 = src->x2 + xoffset; + dest->y1 = src->y1 + yoffset; + dest->y2 = src->y2 + yoffset; + } + + rmesa->numFrontClipRects3D = nfront; + } else + rmesa->numFrontClipRects3D = 0; + } + + if ( nback ) { + rmesa->pBackClipRects3D = MALLOC( nback * sizeof( drm_clip_rect_t )); + + if ( rmesa->pBackClipRects3D ) { + int i; + drm_clip_rect_t *src = dPriv->pBackClipRects; + drm_clip_rect_t *dest = rmesa->pBackClipRects3D; + + for ( i = 0; i < nback; ++i, ++src, ++dest ) { + dest->x1 = src->x1 + xoffset; + dest->x2 = src->x2 + xoffset; + dest->y1 = src->y1 + yoffset; + dest->y2 = src->y2 + yoffset; + } + + rmesa->numBackClipRects3D = nback; + } else + rmesa->numBackClipRects3D = 0; + } +} + + static void r200DrawBuffer( GLcontext *ctx, GLenum mode ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -1812,12 +1964,7 @@ * gets called. */ _swrast_DrawBuffer(ctx, mode); - - R200_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset + - rmesa->r200Screen->fbLocation) - & R200_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; + r200RecalcAndUpdateColor( rmesa ); } Index: src/mesa/drivers/dri/r200/r200_context.c =================================================================== --- src/mesa/drivers/dri/r200/r200_context.c (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_context.c (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -556,10 +556,23 @@ rmesa->glCtx->DriverCtx = NULL; _mesa_destroy_context( rmesa->glCtx ); + if (rmesa->pFrontClipRects3D) { + FREE(rmesa->pFrontClipRects3D); + rmesa->pFrontClipRects3D = NULL; + } + if (rmesa->pBackClipRects3D) { + FREE(rmesa->pBackClipRects3D); + rmesa->pBackClipRects3D = NULL; + } + if (rmesa->state.scissor.pClipRects) { FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = 0; } + if (rmesa->state.scissor.pClipRects3D) { + FREE(rmesa->state.scissor.pClipRects3D); + rmesa->state.scissor.pClipRects3D = NULL; + } if ( release_texture_heaps ) { /* This share group is about to go away, free our private Index: src/mesa/drivers/dri/r200/r200_state.h =================================================================== --- src/mesa/drivers/dri/r200/r200_state.h (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_state.h (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -47,9 +47,11 @@ extern void r200UpdateMaterial( GLcontext *ctx ); extern void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ); +extern void r200UpdateCliprects( r200ContextPtr rmesa ); extern void r200RecalcScissorRects( r200ContextPtr rmesa ); extern void r200UpdateViewportOffset( GLcontext *ctx ); extern void r200UpdateWindow( GLcontext *ctx ); +extern void r200RecalcAndUpdateColor( r200ContextPtr rmesa ); extern void r200ValidateState( GLcontext *ctx ); Index: src/mesa/drivers/dri/r200/r200_lock.c =================================================================== --- src/mesa/drivers/dri/r200/r200_lock.c (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_lock.c (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -63,11 +63,6 @@ rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; } - - R200_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset - + rmesa->r200Screen->fbLocation; - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; } @@ -101,6 +96,8 @@ if ( rmesa->lastStamp != dPriv->lastStamp ) { r200UpdatePageFlipping( rmesa ); + r200RecalcAndUpdateColor( rmesa ); + r200UpdateCliprects( rmesa ); if (rmesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) r200SetCliprects( rmesa, GL_BACK_LEFT ); else Index: src/mesa/drivers/dri/r200/r200_context.h =================================================================== --- src/mesa/drivers/dri/r200/r200_context.h (.../vendor/mesa/mesa-20050101) (wersja 22) +++ src/mesa/drivers/dri/r200/r200_context.h (.../branches/radeon-viewport-1.0/mesa) (wersja 22) @@ -96,7 +96,8 @@ struct r200_colorbuffer_state { GLuint clear; - GLint drawOffset, drawPitch; + GLint drawOffset, drawOffset3D, drawPitch; + GLint xbias; int roundEnable; }; @@ -114,9 +115,9 @@ drm_clip_rect_t rect; GLboolean enabled; - GLuint numClipRects; /* Cliprects active */ + GLuint numClipRects, numClipRects3D; /* Cliprects active */ GLuint numAllocedClipRects; /* Cliprects available */ - drm_clip_rect_t *pClipRects; + drm_clip_rect_t *pClipRects, *pClipRects3D; }; struct r200_stencilbuffer_state { @@ -881,7 +882,13 @@ /* Drawable, cliprect and scissor information */ GLuint numClipRects; /* Cliprects for the draw buffer */ - drm_clip_rect_t *pClipRects; + drm_clip_rect_t *pClipRects, *pClipRects3D; + /* Cliprects used by 3D engine. These must be offseted in order to + * compensate that drawOffset3D ponts to top left corner of viewport. + */ + GLuint numFrontClipRects3D, numBackClipRects3D; + drm_clip_rect_t *pFrontClipRects3D, *pBackClipRects3D; + unsigned int lastStamp; GLboolean lost_context; GLboolean save_on_next_emit; @@ -938,6 +945,23 @@ #define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) +#define R200_DRAW_XBIAS( rmesa ) \ + ( (rmesa)->state.color.xbias ) + +#define R200_CLIP3D_XOFFSET( rmesa ) \ + ( -( ( (rmesa)->state.color.drawOffset3D \ + - (rmesa)->state.color.drawOffset ) \ + / (rmesa)->r200Screen->cpp ) \ + % (rmesa)->state.color.drawPitch ) + +#define R200_CLIP3D_YOFFSET( rmesa ) \ + ( -( ( (rmesa)->state.color.drawOffset3D \ + - (rmesa)->state.color.drawOffset ) \ + / (rmesa)->r200Screen->cpp ) \ + / (rmesa)->state.color.drawPitch ) + + + static __inline GLuint r200PackColor( GLuint cpp, GLubyte r, GLubyte g, GLubyte b, GLubyte a )