static const GLubyte *savageDDGetString( struct gl_context *ctx, GLenum name ) { static char *cardNames[S3_LAST] = { "Unknown", "Savage3D", "Savage/MX/IX", "Savage4", "ProSavage", "Twister", "ProSavageDDR", "SuperSavage", "Savage2000" }; static char buffer[128]; savageContextPtr imesa = SAVAGE_CONTEXT(ctx); savageScreenPrivate *screen = imesa->savageScreen; enum S3CHIPTAGS chipset = screen->chipset; unsigned offset; if (chipset < S3_SAVAGE3D || chipset >= S3_LAST) chipset = S3_UNKNOWN; /* should not happen */ switch (name) { case GL_VENDOR: return (GLubyte *)"S3 Graphics Inc."; case GL_RENDERER: offset = driGetRendererString( buffer, cardNames[chipset], DRIVER_DATE, screen->agpMode ); return (GLubyte *)buffer; default: return 0; } }
/* * This function is called to specify which buffer to read and write * for software rasterization (swrast) fallbacks. This doesn't necessarily * correspond to glDrawBuffer() or glReadBuffer() calls. */ static void savageDDSetBuffer(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); char *map; assert((bufferBit == DD_FRONT_LEFT_BIT) || (bufferBit == DD_BACK_LEFT_BIT)); map = (bufferBit == DD_FRONT_LEFT_BIT) ? (char*)imesa->apertureBase[TARGET_FRONT] : (char*)imesa->apertureBase[TARGET_BACK]; imesa->drawMap = map; imesa->readMap = map; assert( (buffer == imesa->driDrawable->driverPrivate) || (buffer == imesa->driReadable->driverPrivate) ); imesa->mesa_drawable = (buffer == imesa->driDrawable->driverPrivate) ? imesa->driDrawable : imesa->driReadable; }
void savageDDInitSpanFuncs( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); swdd->SetBuffer = savageDDSetBuffer; switch (imesa->savageScreen->cpp) { case 2: swdd->WriteRGBASpan = savageWriteRGBASpan_565; swdd->WriteRGBSpan = savageWriteRGBSpan_565; swdd->WriteMonoRGBASpan = savageWriteMonoRGBASpan_565; swdd->WriteRGBAPixels = savageWriteRGBAPixels_565; swdd->WriteMonoRGBAPixels = savageWriteMonoRGBAPixels_565; swdd->ReadRGBASpan = savageReadRGBASpan_565; swdd->ReadRGBAPixels = savageReadRGBAPixels_565; break; case 4: swdd->WriteRGBASpan = savageWriteRGBASpan_8888; swdd->WriteRGBSpan = savageWriteRGBSpan_8888; swdd->WriteMonoRGBASpan = savageWriteMonoRGBASpan_8888; swdd->WriteRGBAPixels = savageWriteRGBAPixels_8888; swdd->WriteMonoRGBAPixels = savageWriteMonoRGBAPixels_8888; swdd->ReadRGBASpan = savageReadRGBASpan_8888; swdd->ReadRGBAPixels = savageReadRGBAPixels_8888; } switch (imesa->savageScreen->zpp) { case 2: swdd->ReadDepthSpan = savageReadDepthSpan_16; swdd->WriteDepthSpan = savageWriteDepthSpan_16; swdd->ReadDepthPixels = savageReadDepthPixels_16; swdd->WriteDepthPixels = savageWriteDepthPixels_16; break; case 4: swdd->ReadDepthSpan = savageReadDepthSpan_8_24; swdd->WriteDepthSpan = savageWriteDepthSpan_8_24; swdd->ReadDepthPixels = savageReadDepthPixels_8_24; swdd->WriteDepthPixels = savageWriteDepthPixels_8_24; swdd->ReadStencilSpan = savageReadStencilSpan_8_24; swdd->WriteStencilSpan = savageWriteStencilSpan_8_24; swdd->ReadStencilPixels = savageReadStencilPixels_8_24; swdd->WriteStencilPixels = savageWriteStencilPixels_8_24; break; } swdd->WriteCI8Span =NULL; swdd->WriteCI32Span =NULL; swdd->WriteMonoCISpan =NULL; swdd->WriteCI32Pixels =NULL; swdd->WriteMonoCIPixels =NULL; swdd->ReadCI32Span =NULL; swdd->ReadCI32Pixels =NULL; /* Pixel path fallbacks. */ ctx->Driver.Accum = _swrast_Accum; ctx->Driver.Bitmap = _swrast_Bitmap; ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; }
static GLboolean run_texnorm_stage( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage); savageContextPtr imesa = SAVAGE_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint i; if (imesa->Fallback || !store->active) return GL_TRUE; for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { const GLbitfield reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled; if (reallyEnabled) { const struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; const GLboolean normalizeS = (texObj->WrapS == GL_REPEAT); const GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) && (texObj->WrapT == GL_REPEAT); const GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data; const GLint instride = VB->TexCoordPtr[i]->stride; GLfloat (*out)[4] = store->texcoord[i].data; GLint j; if (!ctx->Texture.Unit[i]._ReallyEnabled || VB->TexCoordPtr[i]->size == 4) /* Never try to normalize homogenous tex coords! */ continue; if (normalizeS && normalizeT) { /* take first texcoords as rough estimate of mean value */ GLfloat correctionS = -floor(in[0]+0.5); GLfloat correctionT = -floor(in[1]+0.5); for (j = 0; j < VB->Count; ++j) { out[j][0] = in[0] + correctionS; out[j][1] = in[1] + correctionT; in = (GLfloat *)((GLubyte *)in + instride); } } else if (normalizeS) { /* take first texcoords as rough estimate of mean value */ GLfloat correctionS = -floor(in[0]+0.5); if (reallyEnabled & TEXTURE_2D_BIT) { for (j = 0; j < VB->Count; ++j) { out[j][0] = in[0] + correctionS; out[j][1] = in[1]; in = (GLfloat *)((GLubyte *)in + instride); } } else { for (j = 0; j < VB->Count; ++j) { out[j][0] = in[0] + correctionS; in = (GLfloat *)((GLubyte *)in + instride); } } } else if (normalizeT) { /* take first texcoords as rough estimate of mean value */ GLfloat correctionT = -floor(in[1]+0.5); for (j = 0; j < VB->Count; ++j) { out[j][0] = in[0]; out[j][1] = in[1] + correctionT; in = (GLfloat *)((GLubyte *)in + instride); } } if (normalizeS || normalizeT) VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i]; } } return GL_TRUE; }
static GLboolean savage_run_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_render_func *tab, *tab_elts; GLboolean valid; GLuint i; if (savageHaveIndexedVerts(imesa)) savageReleaseIndexedVerts(imesa); if (imesa->savageScreen->chipset < S3_SAVAGE4 && (ctx->_TriangleCaps & DD_FLATSHADE)) { tab = savage_flat_render_tab_verts_s3d; tab_elts = savage_flat_render_tab_elts_s3d; valid = savage_flat_validate_render_s3d( ctx, VB ); } else { tab = savage_render_tab_verts; tab_elts = savage_render_tab_elts; valid = savage_validate_render( ctx, VB ); } /* Don't handle clipping or vertex manipulations. */ if (imesa->RenderIndex != 0 || !valid) { return GL_TRUE; } tnl->Driver.Render.Start( ctx ); /* Check RenderIndex again. The ptexHack is detected late in RenderStart. * Also check for ptex fallbacks detected late. */ if (imesa->RenderIndex != 0 || imesa->Fallback != 0) { return GL_TRUE; } /* setup for hardware culling */ imesa->raster_primitive = GL_TRIANGLES; imesa->new_state |= SAVAGE_NEW_CULL; /* update and emit state */ savageDDUpdateHwState(ctx); savageEmitChangedState(imesa); if (VB->Elts) { tab = tab_elts; if (!savageHaveIndexedVerts(imesa)) { if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS()) return GL_TRUE; EMIT_INDEXED_VERTS(ctx, 0, VB->Count); } } for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; if (length) tab[prim & PRIM_MODE_MASK]( ctx, start, start+length, prim); } tnl->Driver.Render.Finish( ctx ); return GL_FALSE; /* finished the pipe */ }
/* Still keeping this around because it demonstrates page flipping and * automatic z-clear. */ static void savage_BCI_clear(struct gl_context *ctx, drm_savage_clear_t *pclear) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); int nbox = imesa->sarea->nbox; drm_clip_rect_t *pbox = imesa->sarea->boxes; int i; if (nbox > SAVAGE_NR_SAREA_CLIPRECTS) nbox = SAVAGE_NR_SAREA_CLIPRECTS; for (i = 0 ; i < nbox ; i++, pbox++) { unsigned int x = pbox->x1; unsigned int y = pbox->y1; unsigned int width = pbox->x2 - x; unsigned int height = pbox->y2 - y; uint32_t *bciptr; if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || pbox->x2 > imesa->savageScreen->width || pbox->y2 > imesa->savageScreen->height) continue; if ( pclear->flags & SAVAGE_FRONT ) { bciptr = savageDMAAlloc (imesa, 8); WRITE_CMD((bciptr) , 0x4BCC8C00,uint32_t); WRITE_CMD((bciptr) , imesa->savageScreen->frontOffset,uint32_t); WRITE_CMD((bciptr) , imesa->savageScreen->frontBitmapDesc,uint32_t); WRITE_CMD((bciptr) , pclear->clear_color,uint32_t); WRITE_CMD((bciptr) , (y <<16) | x,uint32_t); WRITE_CMD((bciptr) , (height << 16) | width,uint32_t); savageDMACommit (imesa, bciptr); } if ( pclear->flags & SAVAGE_BACK ) { bciptr = savageDMAAlloc (imesa, 8); WRITE_CMD((bciptr) , 0x4BCC8C00,uint32_t); WRITE_CMD((bciptr) , imesa->savageScreen->backOffset,uint32_t); WRITE_CMD((bciptr) , imesa->savageScreen->backBitmapDesc,uint32_t); WRITE_CMD((bciptr) , pclear->clear_color,uint32_t); WRITE_CMD((bciptr) , (y <<16) | x,uint32_t); WRITE_CMD((bciptr) , (height << 16) | width,uint32_t); savageDMACommit (imesa, bciptr); } if ( pclear->flags & (SAVAGE_DEPTH |SAVAGE_STENCIL) ) { uint32_t writeMask = 0x0; if(imesa->hw_stencil) { if(pclear->flags & SAVAGE_STENCIL) { writeMask |= 0xFF000000; } if(pclear->flags & SAVAGE_DEPTH) { writeMask |= 0x00FFFFFF; } } if(imesa->IsFullScreen && imesa->NotFirstFrame && imesa->savageScreen->chipset >= S3_SAVAGE4) { imesa->regs.s4.zBufCtrl.ni.autoZEnable = GL_TRUE; imesa->regs.s4.zBufCtrl.ni.frameID = ~imesa->regs.s4.zBufCtrl.ni.frameID; imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; } else { if(imesa->IsFullScreen) imesa->NotFirstFrame = GL_TRUE; if(imesa->hw_stencil) { bciptr = savageDMAAlloc (imesa, 10); if(writeMask != 0xFFFFFFFF) { WRITE_CMD((bciptr) , 0x960100D7,uint32_t); WRITE_CMD((bciptr) , writeMask,uint32_t); } } else { bciptr = savageDMAAlloc (imesa, 6); } WRITE_CMD((bciptr) , 0x4BCC8C00,uint32_t); WRITE_CMD((bciptr) , imesa->savageScreen->depthOffset,uint32_t); WRITE_CMD((bciptr) , imesa->savageScreen->depthBitmapDesc,uint32_t); WRITE_CMD((bciptr) , pclear->clear_depth,uint32_t); WRITE_CMD((bciptr) , (y <<16) | x,uint32_t); WRITE_CMD((bciptr) , (height << 16) | width,uint32_t); if(imesa->hw_stencil) { if(writeMask != 0xFFFFFFFF) { WRITE_CMD((bciptr) , 0x960100D7,uint32_t); WRITE_CMD((bciptr) , 0xFFFFFFFF,uint32_t); } } savageDMACommit (imesa, bciptr); } } } /* FK: Make sure that the clear stuff is emitted. Otherwise a software fallback may get overwritten by a delayed clear. */ savageDMAFlush (imesa); }