static void ffbSWRenderFinish(GLcontext *ctx) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); UNLOCK_HARDWARE(fmesa); fmesa->hw_locked = 0; }
static void ffb_dd_line( GLcontext *ctx, GLuint e0, GLuint e1 ) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); ffb_vertex *v0 = &fmesa->verts[e0]; ffb_vertex *v1 = &fmesa->verts[e1]; fmesa->draw_line( ctx, v0, v1 ); }
void ffbChooseLineState(GLcontext *ctx) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint ind = 0; tnl->Driver.Render.Line = ffb_dd_line; if (flags & DD_FLATSHADE) ind |= FFB_LINE_FLAT_BIT; if ((flags & DD_LINE_STIPPLE) != 0 && fmesa->lpat == FFB_LPAT_BAD) { fmesa->draw_line = ffb_fallback_line; return; } /* If blending or the alpha test is enabled we need to * provide alpha components to the chip, else we can * do without it and thus feed vertex data to the chip * more efficiently. */ if (ctx->Color.BlendEnabled || ctx->Color.AlphaEnabled) ind |= FFB_LINE_ALPHA_BIT; fmesa->draw_line = ffb_line_tab[ind]; }
static void ffbDDBuildVertices(GLcontext *ctx, GLuint start, GLuint count, GLuint newinputs) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); newinputs |= fmesa->setupnewinputs; fmesa->setupnewinputs = 0; if (!newinputs) return; if (newinputs & VERT_BIT_CLIP) { setup_tab[fmesa->setupindex].emit(ctx, start, count); } else { GLuint ind = 0; if (newinputs & VERT_BIT_COLOR0) ind |= (FFB_VB_RGBA_BIT | FFB_VB_TWOSIDE_BIT); ind &= fmesa->setupindex; if (ind) setup_tab[ind].emit(ctx, start, count); } }
static const GLubyte *ffbDDGetString(GLcontext *ctx, GLenum name) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); static char buffer[128]; switch (name) { case GL_VENDOR: return (GLubyte *) "David S. Miller"; case GL_RENDERER: sprintf(buffer, "Mesa DRI FFB " FFB_DATE); if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2) strncat(buffer, " FFB2", 5); if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS) strncat(buffer, " FFB2PLUS", 9); if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) strncat(buffer, " PAC1", 5); if (fmesa->ffb_sarea->flags & FFB_DRI_PAC2) strncat(buffer, " PAC2", 5); #ifdef USE_SPARC_ASM strncat(buffer, " Sparc", 6); #endif return (GLubyte *) buffer; default: return NULL; }; }
void ffbFreeVB( GLcontext *ctx ) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); if (fmesa->verts) { ALIGN_FREE(fmesa->verts); fmesa->verts = 0; } }
static void ffbDDFinish(GLcontext *ctx) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); LOCK_HARDWARE(fmesa); FFBWait(fmesa, fmesa->regs); UNLOCK_HARDWARE(fmesa); }
static void ffbBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) { GET_CURRENT_CONTEXT(ctx); ffbContextPtr fmesa = FFB_CONTEXT(ctx); LOCK_HARDWARE(fmesa); *width = fmesa->driDrawable->w; *height = fmesa->driDrawable->h; UNLOCK_HARDWARE(fmesa); }
/* Even when doing full software rendering we need to * wrap render{start,finish} so that the hardware is kept * in sync (because multipass rendering changes the write * buffer etc.) */ static void ffbSWRenderStart(GLcontext *ctx) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); LOCK_HARDWARE(fmesa); fmesa->hw_locked = 1; if (fmesa->state_dirty != 0) ffbSyncHardware(fmesa); }
void ffbChooseTriangleState(GLcontext *ctx) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint ind = 0; if (flags & DD_TRI_SMOOTH) { fmesa->draw_tri = ffb_fallback_triangle; fmesa->draw_quad = ffb_fallback_quad; return; } if (flags & DD_FLATSHADE) ind |= FFB_TRI_FLAT_BIT; if (ctx->Polygon.CullFlag) { if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) { fmesa->draw_tri = ffb_nodraw_triangle; fmesa->draw_quad = ffb_nodraw_quad; return; } ind |= FFB_TRI_CULL_BIT; ffb_update_cullsign(ctx); } else FFB_CONTEXT(ctx)->backface_sign = 0; /* If blending or the alpha test is enabled we need to * provide alpha components to the chip, else we can * do without it and thus feed vertex data to the chip * more efficiently. */ if (ctx->Color.BlendEnabled || ctx->Color.AlphaEnabled) ind |= FFB_TRI_ALPHA_BIT; fmesa->draw_tri = ffb_tri_tab[ind]; fmesa->draw_quad = ffb_quad_tab[ind]; }
static void ffbRenderPrimitive(GLcontext *ctx, GLenum prim) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint rprim = reduced_prim[prim]; fmesa->render_primitive = prim; if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; if (fmesa->raster_primitive != rprim) { ffbRasterPrimitive( ctx, rprim ); } }
static void ffb_copy_pv_oneside(GLcontext *ctx, GLuint edst, GLuint esrc) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); ffb_vertex *dst = &fmesa->verts[edst]; ffb_vertex *src = &fmesa->verts[esrc]; #ifdef VB_DEBUG fprintf(stderr, "ffb_copy_pv_oneside: edst(%d) esrc(%d)\n", edst, esrc); #endif dst->color[0].alpha = src->color[0].alpha; dst->color[0].red = src->color[0].red; dst->color[0].green = src->color[0].green; dst->color[0].blue = src->color[0].blue; }
static void FFBWriteDepthPixels( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], const void *values, const GLubyte mask[] ) { const GLuint *depth = (const GLuint *) values; #ifdef DEPTH_TRACE fprintf(stderr, "FFBWriteDepthPixels: n(%d)\n", (int) n); #endif if (ctx->Depth.Mask) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; char *zbase; GLuint i; if (!fmesa->hw_locked) LOCK_HARDWARE(fmesa); FFBFifo(fmesa, 2); fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_ON | FFB_FBC_YE_OFF | FFB_FBC_RGBE_OFF); fmesa->regs->ppc = FFB_PPC_ZS_VAR; fmesa->ffbScreen->rp_active = 1; FFBWait(fmesa, fmesa->regs); zbase = ((char *)fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13)); for (i = 0; i < n; i++) { GLint y1 = (dPriv->h - y[i]); GLint x1 = x[i]; GLuint *zptr; zptr = (GLuint *) (zbase + (x1 << 2) + (y1 << 13)); if (mask[i]) *zptr = Z_FROM_MESA(depth[i]); } FFBFifo(fmesa, 2); fmesa->regs->fbc = fmesa->fbc; fmesa->regs->ppc = fmesa->ppc; fmesa->ffbScreen->rp_active = 1; if (!fmesa->hw_locked) UNLOCK_HARDWARE(fmesa); } }
void ffbInitVB( GLcontext *ctx ) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint size = TNL_CONTEXT(ctx)->vb.Size; fmesa->verts = (ffb_vertex *)ALIGN_MALLOC(size * sizeof(ffb_vertex), 32); { static int firsttime = 1; if (firsttime) { init_setup_tab(); firsttime = 0; } } }
static void FFBWriteDepthSpan( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const void *values, const GLubyte mask[] ) { const GLuint *depth = (const GLuint *) values; #ifdef DEPTH_TRACE fprintf(stderr, "FFBWriteDepthSpan: n(%d) x(%d) y(%d)\n", (int) n, x, y); #endif if (ctx->Depth.Mask) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; GLuint *zptr; GLuint i; if (!fmesa->hw_locked) LOCK_HARDWARE(fmesa); FFBFifo(fmesa, 2); fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_ON | FFB_FBC_YE_OFF | FFB_FBC_RGBE_OFF); fmesa->regs->ppc = FFB_PPC_ZS_VAR; FFBWait(fmesa, fmesa->regs); y = (dPriv->h - y); zptr = (GLuint *) ((char *)fmesa->sfb32 + ((dPriv->x + x) << 2) + ((dPriv->y + y) << 13)); for (i = 0; i < n; i++) { if (mask[i]) { *zptr = Z_FROM_MESA(depth[i]); } zptr++; } FFBFifo(fmesa, 2); fmesa->regs->fbc = fmesa->fbc; fmesa->regs->ppc = fmesa->ppc; fmesa->ffbScreen->rp_active = 1; if (!fmesa->hw_locked) UNLOCK_HARDWARE(fmesa); } }
static void ffbRenderClippedPolygon(GLcontext *ctx, const GLuint *elts, GLuint n) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint prim = fmesa->render_primitive; /* Render the new vertices as an unclipped polygon. */ { GLuint *tmp = VB->Elts; VB->Elts = (GLuint *)elts; tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, PRIM_BEGIN|PRIM_END); VB->Elts = tmp; } /* Restore the render primitive. */ if (prim != GL_POLYGON) tnl->Driver.Render.PrimitiveNotify(ctx, prim); }
static void FFBReadDepthPixels( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], void *values ) { GLuint *depth = (GLuint *) values; ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; char *zbase; GLuint i; #ifdef DEPTH_TRACE fprintf(stderr, "FFBReadDepthPixels: n(%d)\n", (int) n); #endif if (!fmesa->hw_locked) LOCK_HARDWARE(fmesa); FFBFifo(fmesa, 1); fmesa->regs->fbc = FFB_FBC_RB_C; fmesa->ffbScreen->rp_active = 1; FFBWait(fmesa, fmesa->regs); zbase = ((char *)fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13)); for (i = 0; i < n; i++) { GLint y1 = (dPriv->h - y[i]); GLint x1 = x[i]; GLuint *zptr; zptr = (GLuint *) (zbase + (x1 << 2) + (y1 << 13)); depth[i] = Z_TO_MESA(*zptr); } FFBFifo(fmesa, 1); fmesa->regs->fbc = fmesa->fbc; fmesa->ffbScreen->rp_active = 1; if (!fmesa->hw_locked) UNLOCK_HARDWARE(fmesa); }
static void ffb_update_cullsign(GLcontext *ctx) { GLfloat backface_sign = 1; switch (ctx->Polygon.CullFaceMode) { case GL_BACK: if (ctx->Polygon.FrontFace==GL_CCW) backface_sign = -1; break; case GL_FRONT: if (ctx->Polygon.FrontFace!=GL_CCW) backface_sign = -1; break; default: break; }; FFB_CONTEXT(ctx)->backface_sign = backface_sign; }
static void ffbRunPipeline(GLcontext *ctx) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); if (fmesa->bad_fragment_attrs == 0 && fmesa->new_gl_state) { if (fmesa->new_gl_state & _FFB_NEW_TRIANGLE) ffbChooseTriangleState(ctx); if (fmesa->new_gl_state & _FFB_NEW_LINE) ffbChooseLineState(ctx); if (fmesa->new_gl_state & _FFB_NEW_POINT) ffbChoosePointState(ctx); if (fmesa->new_gl_state & _FFB_NEW_RENDER) ffbChooseRenderState(ctx); if (fmesa->new_gl_state & _FFB_NEW_VERTEX) ffbChooseVertexState(ctx); fmesa->new_gl_state = 0; } _tnl_run_pipeline(ctx); }
static void FFBReadDepthSpan( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, void *values ) { GLuint *depth = (GLuint *) values; ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; GLuint *zptr; GLuint i; #ifdef DEPTH_TRACE fprintf(stderr, "FFBReadDepthSpan: n(%d) x(%d) y(%d)\n", (int) n, x, y); #endif if (!fmesa->hw_locked) LOCK_HARDWARE(fmesa); FFBFifo(fmesa, 1); fmesa->regs->fbc = FFB_FBC_RB_C; fmesa->ffbScreen->rp_active = 1; FFBWait(fmesa, fmesa->regs); y = (dPriv->h - y); zptr = (GLuint *) ((char *)fmesa->sfb32 + ((dPriv->x + x) << 2) + ((dPriv->y + y) << 13)); for (i = 0; i < n; i++) { depth[i] = Z_TO_MESA(*zptr); zptr++; } FFBFifo(fmesa, 1); fmesa->regs->fbc = fmesa->fbc; fmesa->ffbScreen->rp_active = 1; if (!fmesa->hw_locked) UNLOCK_HARDWARE(fmesa); }
/* Build a SWvertex from a hardware vertex. */ static void ffb_translate_vertex(GLcontext *ctx, const ffb_vertex *src, SWvertex *dst) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLfloat *m = ctx->Viewport._WindowMap.m; const GLfloat sx = m[0]; const GLfloat sy = m[5]; const GLfloat sz = m[10]; const GLfloat tx = m[12]; const GLfloat ty = m[13]; const GLfloat tz = m[14]; dst->win[0] = sx * src->x + tx; dst->win[1] = sy * src->y + ty; dst->win[2] = sz * src->z + tz; dst->win[3] = 1.0; dst->color[0] = FFB_UBYTE_FROM_COLOR(src->color[0].red); dst->color[1] = FFB_UBYTE_FROM_COLOR(src->color[0].green); dst->color[2] = FFB_UBYTE_FROM_COLOR(src->color[0].blue); dst->color[3] = FFB_UBYTE_FROM_COLOR(src->color[0].alpha); }
void ffbChooseVertexState( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); ffbContextPtr fmesa = FFB_CONTEXT(ctx); int ind = FFB_VB_XYZ_BIT | FFB_VB_RGBA_BIT; if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ind |= FFB_VB_TWOSIDE_BIT; #ifdef VB_DEBUG ffbPrintSetupFlags("ffb: full setup function", ind); #endif fmesa->setupindex = ind; tnl->Driver.Render.BuildVertices = ffbDDBuildVertices; tnl->Driver.Render.Interp = setup_tab[ind].interp; if (ind & FFB_VB_TWOSIDE_BIT) tnl->Driver.Render.CopyPV = ffb_copy_pv_twoside; else tnl->Driver.Render.CopyPV = ffb_copy_pv_oneside; }
void ffbFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint oldfallback = fmesa->bad_fragment_attrs; if (mode) { fmesa->bad_fragment_attrs |= bit; if (oldfallback == 0) { /* FFB_FIREVERTICES(fmesa); */ _swsetup_Wakeup( ctx ); if (fmesa->debugFallbacks) fprintf(stderr, "FFB begin software fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } else { fmesa->bad_fragment_attrs &= ~bit; if (oldfallback == bit) { _swrast_flush( ctx ); tnl->Driver.Render.Start = ffbRenderStart; tnl->Driver.Render.PrimitiveNotify = ffbRenderPrimitive; tnl->Driver.Render.Finish = ffbRenderFinish; fmesa->new_gl_state = ~0; /* Just re-choose everything: */ ffbChooseVertexState(ctx); ffbChooseRenderState(ctx); ffbChooseTriangleState(ctx); ffbChooseLineState(ctx); ffbChoosePointState(ctx); if (fmesa->debugFallbacks) fprintf(stderr, "FFB end software fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } }
static void ffb_bitmap(GLcontext *ctx, GLint px, GLint py, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); ffb_fbcPtr ffb = fmesa->regs; __DRIdrawablePrivate *dPriv = fmesa->driDrawable; unsigned int ppc, pixel; GLint row, col, row_stride; const GLubyte *src; char *buf; if (fmesa->bad_fragment_attrs != 0) _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap); pixel = (((((GLuint)(ctx->Current.RasterColor[0] * 255.0f)) & 0xff) << 0) | ((((GLuint)(ctx->Current.RasterColor[1] * 255.0f)) & 0xff) << 8) | ((((GLuint)(ctx->Current.RasterColor[2] * 255.0f)) & 0xff) << 16) | ((((GLuint)(ctx->Current.RasterColor[3] * 255.0f)) & 0xff) << 24)); #ifdef FFB_BITMAP_TRACE fprintf(stderr, "ffb_bitmap: ppc(%08x) fbc(%08x) cmp(%08x) pixel(%08x)\n", fmesa->ppc, fmesa->fbc, fmesa->cmp, pixel); #endif LOCK_HARDWARE(fmesa); fmesa->hw_locked = 1; if (fmesa->state_dirty) ffbSyncHardware(fmesa); ppc = fmesa->ppc; FFBFifo(fmesa, 4); ffb->ppc = ((ppc & ~(FFB_PPC_TBE_MASK | FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK)) | (FFB_PPC_TBE_TRANSPARENT | FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST | (ctx->Color.BlendEnabled ? FFB_PPC_XS_CONST : FFB_PPC_XS_WID))); ffb->constz = ((GLuint) (ctx->Current.RasterPos[2] * 0x0fffffff)); ffb->fg = pixel; ffb->fontinc = (0 << 16) | 32; buf = (char *)(fmesa->sfb32 + (dPriv->x << 2) + (dPriv->y << 13)); row_stride = (unpack->Alignment * CEILING(width, 8 * unpack->Alignment)); src = (const GLubyte *) (bitmap + (unpack->SkipRows * row_stride) + (unpack->SkipPixels / 8)); if (unpack->LsbFirst == GL_TRUE) { for (row = 0; row < height; row++, src += row_stride) { const GLubyte *row_src = src; GLuint base_x, base_y; base_x = dPriv->x + px; base_y = dPriv->y + (dPriv->h - (py + row)); FFBFifo(fmesa, 1); ffb->fontxy = (base_y << 16) | base_x; for (col = 0; col < width; col += 32, row_src += 4) { GLint bitnum, font_w = (width - col); GLuint font_data; if (font_w > 32) font_w = 32; font_data = 0; for (bitnum = 0; bitnum < 32; bitnum++) { const GLubyte val = row_src[bitnum >> 3]; if (val & (1 << (bitnum & (8 - 1)))) font_data |= (1 << (31 - bitnum)); } FFBFifo(fmesa, 2); ffb->fontw = font_w; ffb->font = font_data; } } } else { for (row = 0; row < height; row++, src += row_stride) {
static void ffbRasterPrimitive(GLcontext *ctx, GLenum rprim) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint drawop, fbc, ppc; int do_sw = 0; fmesa->raster_primitive = rprim; drawop = fmesa->drawop; fbc = fmesa->fbc; ppc = fmesa->ppc & ~(FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK); #ifdef STATE_TRACE fprintf(stderr, "ffbReducedPrimitiveChange: rprim(%d) ", rprim); #endif switch(rprim) { case GL_POINTS: #ifdef STATE_TRACE fprintf(stderr, "GL_POINTS "); #endif if (fmesa->draw_point == ffb_fallback_point) { do_sw = 1; break; } if (ctx->Point.SmoothFlag) { ppc |= (FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST); drawop = FFB_DRAWOP_AADOT; } else { ppc |= (FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST); drawop = FFB_DRAWOP_DOT; } break; case GL_LINES: #ifdef STATE_TRACE fprintf(stderr, "GL_LINES "); #endif if (fmesa->draw_line == ffb_fallback_line) { do_sw = 1; break; } if (ctx->_TriangleCaps & DD_FLATSHADE) { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST; } else { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR; } if (ctx->Line.SmoothFlag) drawop = FFB_DRAWOP_AALINE; else drawop = FFB_DRAWOP_DDLINE; break; case GL_TRIANGLES: #ifdef STATE_TRACE fprintf(stderr, "GL_POLYGON "); #endif if (fmesa->draw_tri == ffb_fallback_triangle) { do_sw = 1; break; } ppc &= ~FFB_PPC_APE_MASK; if (ctx->Polygon.StippleFlag) ppc |= FFB_PPC_APE_ENABLE; else ppc |= FFB_PPC_APE_DISABLE; if (ctx->_TriangleCaps & DD_FLATSHADE) { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST; } else { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR; } drawop = FFB_DRAWOP_TRIANGLE; break; default: #ifdef STATE_TRACE fprintf(stderr, "unknown %d!\n", rprim); #endif return; }; #ifdef STATE_TRACE fprintf(stderr, "do_sw(%d) ", do_sw); #endif if (do_sw != 0) { fbc &= ~(FFB_FBC_WB_C); fbc &= ~(FFB_FBC_ZE_MASK | FFB_FBC_RGBE_MASK); fbc |= FFB_FBC_ZE_OFF | FFB_FBC_RGBE_MASK; ppc &= ~(FFB_PPC_XS_MASK | FFB_PPC_ABE_MASK | FFB_PPC_DCE_MASK | FFB_PPC_APE_MASK); ppc |= (FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR | FFB_PPC_XS_WID | FFB_PPC_ABE_DISABLE | FFB_PPC_DCE_DISABLE | FFB_PPC_APE_DISABLE); } else { fbc |= FFB_FBC_WB_C; fbc &= ~(FFB_FBC_RGBE_MASK); fbc |= FFB_FBC_RGBE_MASK; ppc &= ~(FFB_PPC_ABE_MASK | FFB_PPC_XS_MASK); if (ctx->Color.BlendEnabled) { if ((rprim == GL_POINTS && !ctx->Point.SmoothFlag) || (rprim != GL_POINTS && ctx->_TriangleCaps & DD_FLATSHADE)) ppc |= FFB_PPC_ABE_ENABLE | FFB_PPC_XS_CONST; else ppc |= FFB_PPC_ABE_ENABLE | FFB_PPC_XS_VAR; } else { ppc |= FFB_PPC_ABE_DISABLE | FFB_PPC_XS_WID; } } #ifdef STATE_TRACE fprintf(stderr, "fbc(%08x) ppc(%08x)\n", fbc, ppc); #endif FFBFifo(fmesa, 4); if (fmesa->drawop != drawop) fmesa->regs->drawop = fmesa->drawop = drawop; if (fmesa->fbc != fbc) fmesa->regs->fbc = fmesa->fbc = fbc; if (fmesa->ppc != ppc) fmesa->regs->ppc = fmesa->ppc = ppc; if (do_sw != 0) { fmesa->regs->cmp = (fmesa->cmp & ~(0xff<<16)) | (0x80 << 16); } else fmesa->regs->cmp = fmesa->cmp; }
void ffbDDClear(GLcontext *ctx, GLbitfield mask) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; unsigned int stcmask = BUFFER_BIT_STENCIL; #ifdef CLEAR_TRACE fprintf(stderr, "ffbDDClear: mask(%08x) \n", mask); #endif if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS)) stcmask = 0; if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH | stcmask)) { ffb_fbcPtr ffb = fmesa->regs; unsigned int fbc, ppc; fbc = (FFB_FBC_XE_ON); ppc = (FFB_PPC_ACE_DISABLE | FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_XS_WID | FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST); /* Y/X enables must be both on or both off. */ if (mask & (BUFFER_BIT_DEPTH | stcmask)) { fbc |= (FFB_FBC_ZE_ON | FFB_FBC_YE_ON | FFB_FBC_WB_C); } else fbc |= FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF; /* All RGB enables must be both on or both off. */ if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) { if (mask & BUFFER_BIT_FRONT_LEFT) { if (fmesa->back_buffer == 0) fbc |= FFB_FBC_WB_B; else fbc |= FFB_FBC_WB_A; } if (mask & BUFFER_BIT_BACK_LEFT) { if (fmesa->back_buffer == 0) fbc |= FFB_FBC_WB_A; else fbc |= FFB_FBC_WB_B; } fbc |= FFB_FBC_RGBE_ON; } else fbc |= FFB_FBC_RGBE_OFF; LOCK_HARDWARE(fmesa); if (dPriv->numClipRects) { FFBFifo(fmesa, 8); ffb->fbc = fbc; ffb->ppc = ppc; ffb->xclip = FFB_XCLIP_TEST_ALWAYS; ffb->cmp = 0x80808080; ffb->rop = FFB_ROP_NEW; if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) ffb->fg = fmesa->clear_pixel; if (mask & BUFFER_BIT_DEPTH) ffb->constz = fmesa->clear_depth; if (mask & stcmask) ffb->consty = fmesa->clear_stencil; ffb_do_clear(ctx, dPriv); FFBFifo(fmesa, 6); ffb->ppc = fmesa->ppc; ffb->fbc = fmesa->fbc; ffb->xclip = fmesa->xclip; ffb->cmp = fmesa->cmp; ffb->rop = fmesa->rop; ffb->drawop = fmesa->drawop; if (mask & stcmask) ffb->consty = fmesa->consty; fmesa->ffbScreen->rp_active = 1; } UNLOCK_HARDWARE(fmesa); mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH | stcmask); } if (mask) _swrast_Clear(ctx, mask); }
static void ffb_do_clear(GLcontext *ctx, __DRIdrawablePrivate *dPriv) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); FFBDRIPtr gDRIPriv = (FFBDRIPtr) fmesa->driScreen->pDevPriv; ffb_fbcPtr ffb = fmesa->regs; drm_clip_rect_t *box = dPriv->pClipRects; int nc = dPriv->numClipRects; GLint cx, cy, cw, ch; /* compute region after locking: */ cx = ctx->DrawBuffer->_Xmin; cy = ctx->DrawBuffer->_Ymin; cw = ctx->DrawBuffer->_Xmax - cx; ch = ctx->DrawBuffer->_Ymax - cy; cy = dPriv->h - cy - ch; cx += dPriv->x; cy += dPriv->y; while (nc--) { GLint x = box[nc].x1; GLint y = box[nc].y1; GLint width = box[nc].x2 - x; GLint height = box[nc].y2 - y; int paligned_y, paligned_x; int paligned_h, paligned_w = 0; int extra_work; if (BOX_AREA(width, height) < gDRIPriv->fastfill_small_area) { FFBFifo(fmesa, 5); ffb->drawop = FFB_DRAWOP_RECTANGLE; ffb->by = y; ffb->bx = x; ffb->bh = height; ffb->bw = width; continue; } FFBFifo(fmesa, 1); ffb->drawop = FFB_DRAWOP_FASTFILL; if (gDRIPriv->disable_pagefill || (width < (gDRIPriv->pagefill_width<<1)) || (height < (gDRIPriv->pagefill_height<<1))) goto do_fastfill; CreatorPageFillParms(gDRIPriv, x, y, width, height, paligned_x, paligned_y, paligned_w, paligned_h, extra_work); if (extra_work < 0 || BOX_AREA(paligned_w, paligned_h) < gDRIPriv->pagefill_small_area) { do_fastfill: FFBFifo(fmesa, 10); ffb->by = FFB_FASTFILL_COLOR_BLK; ffb->dy = 0; ffb->dx = 0; ffb->bh = gDRIPriv->fastfill_height; ffb->bw = (gDRIPriv->fastfill_width * 4); ffb->by = FFB_FASTFILL_BLOCK; ffb->dy = y; ffb->dx = x; ffb->bh = (height + (y & (gDRIPriv->fastfill_height - 1))); ffb->bx = (width + (x & (gDRIPriv->fastfill_width - 1))); continue; } /* Ok, page fill is possible and worth it. */ FFBFifo(fmesa, 15); ffb->by = FFB_FASTFILL_COLOR_BLK; ffb->dy = 0; ffb->dx = 0; ffb->bh = gDRIPriv->fastfill_height; ffb->bw = gDRIPriv->fastfill_width * 4; ffb->by = FFB_FASTFILL_BLOCK_X; ffb->dy = 0; ffb->dx = 0; ffb->bh = gDRIPriv->pagefill_height; ffb->bw = gDRIPriv->pagefill_width * 4; ffb->by = FFB_FASTFILL_PAGE; ffb->dy = paligned_y; ffb->dx = paligned_x; ffb->bh = paligned_h; ffb->bx = paligned_w; if (extra_work) { struct ff_fixups local_fixups[4]; int nfixups; nfixups = CreatorComputePageFillFixups(local_fixups, x, y, width, height, paligned_x, paligned_y, paligned_w, paligned_h); FFBFifo(fmesa, 5 + (nfixups * 5)); ffb->by = FFB_FASTFILL_COLOR_BLK; ffb->dy = 0; ffb->dx = 0; ffb->bh = gDRIPriv->fastfill_height; ffb->bw = gDRIPriv->fastfill_width * 4; while (--nfixups >= 0) { int xx, yy, ww, hh; xx = local_fixups[nfixups].x; yy = local_fixups[nfixups].y; ffb->dy = yy; ffb->dx = xx; ww = (local_fixups[nfixups].width + (xx & (gDRIPriv->fastfill_width - 1))); hh = (local_fixups[nfixups].height + (yy & (gDRIPriv->fastfill_height - 1))); if (nfixups != 0) { ffb->by = FFB_FASTFILL_BLOCK; ffb->bh = hh; ffb->bw = ww; } else { ffb->bh = hh; ffb->by = FFB_FASTFILL_BLOCK; ffb->bx = ww; } } } } }