📄 fxdd.c
字号:
/* KW: Put the word Mesa in the render string because quakeworld * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE). * Why? */static const GLubyte *fxDDGetString(GLcontext * ctx, GLenum name){ fxMesaContext fxMesa = FX_CONTEXT(ctx); switch (name) { case GL_RENDERER: return (GLubyte *)fxMesa->rendererString;#if __WIN32__ /* hack to advertise vanilla extension names */ case GL_EXTENSIONS: if (ctx->Extensions.String == NULL) { GLubyte *ext = _mesa_make_extension_string(ctx); if (ext != NULL) { ctx->Extensions.String = _mesa_malloc(strlen((char *)ext) + 256); if (ctx->Extensions.String != NULL) { strcpy((char *)ctx->Extensions.String, (char *)ext); /* put any additional extension names here */#if 0 strcat((char *)ctx->Extensions.String, " 3DFX_set_global_palette");#endif#if __WIN32__ strcat((char *)ctx->Extensions.String, " WGL_3DFX_gamma_control"); strcat((char *)ctx->Extensions.String, " WGL_EXT_swap_control"); strcat((char *)ctx->Extensions.String, " WGL_EXT_extensions_string WGL_ARB_extensions_string");#endif /* put any additional extension names here */ _mesa_free(ext); } else { ctx->Extensions.String = ext; } } } return ctx->Extensions.String;#endif default: return NULL; }}static const struct tnl_pipeline_stage *fx_pipeline[] = { &_tnl_vertex_transform_stage, /* XXX todo - Add the fastpath here */ &_tnl_normal_transform_stage, &_tnl_lighting_stage, &_tnl_fog_coordinate_stage, &_tnl_texgen_stage, &_tnl_texture_transform_stage, &_tnl_point_attenuation_stage,#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program) &_tnl_vertex_program_stage,#endif &_tnl_render_stage, 0,};intfxDDInitFxMesaContext(fxMesaContext fxMesa){ GLcontext *ctx = fxMesa->glCtx; FX_setupGrVertexLayout(); fxMesa->color = 0xffffffff; fxMesa->clearC = 0; fxMesa->clearA = 0; fxMesa->stats.swapBuffer = 0; fxMesa->stats.reqTexUpload = 0; fxMesa->stats.texUpload = 0; fxMesa->stats.memTexUpload = 0; fxMesa->tmuSrc = FX_TMU_NONE; fxMesa->lastUnitsMode = FX_UM_NONE; fxTMInit(fxMesa); /* FX units setup */ fxMesa->unitsState.alphaTestEnabled = GL_FALSE; fxMesa->unitsState.alphaTestFunc = GL_ALWAYS; fxMesa->unitsState.alphaTestRefValue = 0.0; fxMesa->unitsState.blendEnabled = GL_FALSE; fxMesa->unitsState.blendSrcFuncRGB = GR_BLEND_ONE; fxMesa->unitsState.blendDstFuncRGB = GR_BLEND_ZERO; fxMesa->unitsState.blendSrcFuncAlpha = GR_BLEND_ONE; fxMesa->unitsState.blendDstFuncAlpha = GR_BLEND_ZERO; fxMesa->unitsState.blendEqRGB = GR_BLEND_OP_ADD; fxMesa->unitsState.blendEqAlpha = GR_BLEND_OP_ADD; fxMesa->unitsState.depthTestEnabled = GL_FALSE; fxMesa->unitsState.depthMask = GL_TRUE; fxMesa->unitsState.depthTestFunc = GL_LESS; fxMesa->unitsState.depthBias = 0; fxMesa->unitsState.stencilWriteMask = 0xff; if (fxMesa->colDepth == 32) { /* 32bpp */ fxMesa->Glide.grColorMaskExt(FXTRUE, FXTRUE, FXTRUE, fxMesa->haveHwAlpha); } else { /* 15/16 bpp mode */ grColorMask(FXTRUE, fxMesa->haveHwAlpha); } fxMesa->currentFB = fxMesa->haveDoubleBuffer ? GR_BUFFER_BACKBUFFER : GR_BUFFER_FRONTBUFFER; grRenderBuffer(fxMesa->currentFB); fxMesa->state = MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE)); fxMesa->fogTable = (GrFog_t *) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES) * sizeof(GrFog_t)); if (!fxMesa->state || !fxMesa->fogTable) { if (fxMesa->state) FREE(fxMesa->state); if (fxMesa->fogTable) FREE(fxMesa->fogTable); return 0; } if (fxMesa->haveZBuffer) { grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); } if (!fxMesa->bgrOrder) { grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); } if (fxMesa->Glide.grSetNumPendingBuffers != NULL) { fxMesa->Glide.grSetNumPendingBuffers(fxMesa->maxPendingSwapBuffers); } fxMesa->textureAlign = FX_grGetInteger(GR_TEXTURE_ALIGN); /* [koolsmoky] */ { char *env; int textureLevels = 0; int textureSize = FX_grGetInteger(GR_MAX_TEXTURE_SIZE); do { textureLevels++; } while ((textureSize >>= 0x1) & 0x7ff); ctx->Const.MaxTextureLevels = textureLevels; ctx->Const.MaxTextureLodBias = /*textureLevels - 1*/8; /* Glide bug */#if FX_RESCALE_BIG_TEXURES_HACK fxMesa->textureMaxLod = textureLevels - 1; if ((env = getenv("MESA_FX_MAXLOD")) != NULL) { int maxLevels = atoi(env) + 1; if ((maxLevels <= MAX_TEXTURE_LEVELS) && (maxLevels > textureLevels)) { ctx->Const.MaxTextureLevels = maxLevels; } }#endif } ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureImageUnits = fxMesa->haveTwoTMUs ? 2 : 1; ctx->Const.MaxTextureUnits = MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits); fxMesa->new_state = _NEW_ALL; if (!fxMesa->haveHwStencil) { /* don't touch stencil if there is none */ fxMesa->new_state &= ~FX_NEW_STENCIL; } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); /* Install customized pipeline */ _tnl_destroy_pipeline(ctx); _tnl_install_pipeline(ctx, fx_pipeline); fxAllocVB(ctx); fxSetupDDPointers(ctx); fxDDInitTriFuncs(ctx); /* Tell the software rasterizer to use pixel fog always. */ _swrast_allow_vertex_fog(ctx, GL_FALSE); _swrast_allow_pixel_fog(ctx, GL_TRUE); _tnl_allow_vertex_fog( ctx, GL_FALSE ); _tnl_allow_pixel_fog( ctx, GL_TRUE ); /* Tell tnl not to calculate or use vertex fog factors. (Needed to * tell render stage not to clip fog coords). *//* _tnl_calculate_vertex_fog( ctx, GL_FALSE ); */ fxDDInitExtensions(ctx);#if 0 /* do we want dither? It just looks bad... */ grEnable(GR_ALLOW_MIPMAP_DITHER);#endif grGlideGetState((GrState *) fxMesa->state); return 1;}/* Undo the above. */voidfxDDDestroyFxMesaContext(fxMesaContext fxMesa){ _swsetup_DestroyContext(fxMesa->glCtx); _tnl_DestroyContext(fxMesa->glCtx); _vbo_DestroyContext(fxMesa->glCtx); _swrast_DestroyContext(fxMesa->glCtx); if (fxMesa->state) FREE(fxMesa->state); if (fxMesa->fogTable) FREE(fxMesa->fogTable); fxFreeVB(fxMesa->glCtx);}voidfxDDInitExtensions(GLcontext * ctx){ fxMesaContext fxMesa = FX_CONTEXT(ctx);#if 1 /* multipass ColorSum stage */ _mesa_enable_extension(ctx, "GL_EXT_secondary_color");#endif _mesa_enable_extension(ctx, "GL_ARB_point_sprite"); _mesa_enable_extension(ctx, "GL_EXT_point_parameters"); _mesa_enable_extension(ctx, "GL_EXT_paletted_texture"); _mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias"); _mesa_enable_extension(ctx, "GL_EXT_shared_texture_palette"); _mesa_enable_extension(ctx, "GL_EXT_blend_func_separate"); _mesa_enable_extension(ctx, "GL_EXT_texture_env_add"); _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap"); _mesa_enable_extension(ctx, "GL_EXT_stencil_two_side"); if (fxMesa->haveTwoTMUs) { _mesa_enable_extension(ctx, "GL_ARB_multitexture"); } if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { _mesa_enable_extension(ctx, "GL_ARB_texture_compression"); _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1"); _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); _mesa_enable_extension(ctx, "GL_S3_s3tc"); _mesa_enable_extension(ctx, "GL_NV_blend_square"); } else { /* [dBorca] * We should enable generic texture compression functions, * but some poorly written apps automatically assume S3TC. * Binding NCC to GL_COMPRESSED_RGB[A] is an unnecessary hassle, * since it's slow and ugly (better with palette textures, then). * Moreover, NCC is not an OpenGL standard, so we can't use * precompressed textures. Last, but not least, NCC runs amok * when multitexturing on a Voodoo3 and up (see POINTCAST vs UMA). * Note: this is also a problem with palette textures, but * faking multitex by multipass is evil... * Implementing NCC requires three stages: * fxDDChooseTextureFormat: * bind GL_COMPRESSED_RGB[A] to _mesa_texformat_argb8888, * so we can quantize properly, at a later time * fxDDTexImage: * if GL_COMPRESSED_RGB * use _mesa_texformat_l8 to get 1bpt and set GR_TEXFMT_YIQ_422 * if GL_COMPRESSED_RGBA * use _mesa_texformat_al88 to get 2bpt and set GR_TEXFMT_AYIQ_8422 * txMipQuantize(...); * if (level == 0) { * txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal); * } * fxSetupSingleTMU_NoLock/fxSetupDoubleTMU_NoLock: * grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette)); */ /*_mesa_enable_extension(ctx, "GL_ARB_texture_compression");*/ _mesa_enable_extension(ctx, "GL_SGIS_generate_mipmap"); } if (fxMesa->HaveCmbExt) { _mesa_enable_extension(ctx, "GL_ARB_texture_env_combine"); _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine"); } if (fxMesa->HavePixExt) { _mesa_enable_extension(ctx, "GL_EXT_blend_subtract"); _mesa_enable_extension(ctx, "GL_EXT_blend_equation_separate"); } if (fxMesa->HaveMirExt) { _mesa_enable_extension(ctx, "GL_ARB_texture_mirrored_repeat"); } if (fxMesa->type >= GR_SSTTYPE_Voodoo2) { _mesa_enable_extension(ctx, "GL_EXT_fog_coord"); } /* core-level extensions */ _mesa_enable_extension(ctx, "GL_EXT_multi_draw_arrays"); _mesa_enable_extension(ctx, "GL_IBM_multimode_draw_arrays"); _mesa_enable_extension(ctx, "GL_ARB_vertex_buffer_object"); /* dangerous */ if (getenv("MESA_FX_ALLOW_VP")) { _mesa_enable_extension(ctx, "GL_ARB_vertex_program"); _mesa_enable_extension(ctx, "GL_NV_vertex_program"); _mesa_enable_extension(ctx, "GL_NV_vertex_program1_1"); _mesa_enable_extension(ctx, "GL_MESA_program_debug"); }#if 0 /* this requires _tnl_vertex_cull_stage in the pipeline */ _mesa_enable_extension(ctx, "EXT_cull_vertex");#endif}/************************************************************************//************************************************************************//************************************************************************//* Check if the hardware supports the current context * * Performs similar work to fxDDChooseRenderState() - should be merged. */GLuintfx_check_IsInHardware(GLcontext * ctx){ fxMesaContext fxMesa = FX_CONTEXT(ctx); if (ctx->RenderMode != GL_RENDER) { return FX_FALLBACK_RENDER_MODE; } if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) { return FX_FALLBACK_STENCIL; } if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) && (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT)) { return FX_FALLBACK_DRAW_BUFFER; } if (ctx->Color.BlendEnabled) { if (ctx->Color.BlendEquationRGB != GL_FUNC_ADD) { if (!fxMesa->HavePixExt || ((ctx->Color.BlendEquationRGB != GL_FUNC_SUBTRACT) && (ctx->Color.BlendEquationRGB != GL_FUNC_REVERSE_SUBTRACT))) { return FX_FALLBACK_BLEND; } } if (ctx->Color.BlendEquationA != GL_FUNC_ADD) { if (!fxMesa->HavePixExt || ((ctx->Color.BlendEquationA != GL_FUNC_SUBTRACT) && (ctx->Color.BlendEquationA != GL_FUNC_REVERSE_SUBTRACT))) { return FX_FALLBACK_BLEND; } }#if 0 /* [dBorca] * We fail the spec here, unless certain blending modes: * RGB: (GL_ONE + GL_*) or (GL_ZERO + GL_*) or ... */ if (NEED_SECONDARY_COLOR(ctx)) { if ((ctx->Color.BlendEquationRGB != GL_FUNC_ADD) && (ctx->Color.BlendSrcRGB != GL_ONE)) { /* Can't use multipass to blend ColorSum stage */ return FX_FALLBACK_SPECULAR; } }#endif } /* [dBorca] * We could avoid this for certain `sfactor/dfactor' * I do not think that is even worthwhile to check * because if someone is using blending they use more * interesting settings and also it would add more * state tracking to a lot of the code. */ if (ctx->Color.ColorLogicOpEnabled && (ctx->Color.LogicOp != GL_COPY)) { return FX_FALLBACK_LOGICOP; } if ((fxMesa->colDepth != 32) && ((ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP]) || (ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]))) { return FX_FALLBACK_COLORMASK; } /* Unsupported texture/multitexture cases */ /* we can only do 1D/2D textures */ if (ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -