/* * Copyright 2001 by Alan Hourihane. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Alan Hourihane not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Alan Hourihane makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Alan Hourihane, * * 3DLabs Gamma driver. * */ #include "gammacontext.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" #include "main/matrix.h" #include "main/extensions.h" #if defined(USE_X86_ASM) #include "x86/common_x86_asm.h" #endif #include "main/simple_list.h" #include "main/mm.h" #include "gamma_vb.h" #include "gamma_tris.h" extern const struct tnl_pipeline_stage _gamma_render_stage; static const struct tnl_pipeline_stage *gamma_pipeline[] = { &_tnl_vertex_transform_stage, &_tnl_normal_transform_stage, &_tnl_lighting_stage, &_tnl_fog_coordinate_stage, &_tnl_texgen_stage, &_tnl_texture_transform_stage, /* REMOVE: point attenuation stage */ #if 1 &_gamma_render_stage, /* ADD: unclipped rastersetup-to-dma */ #endif &_tnl_render_stage, 0, }; GLboolean gammaCreateContext( const __GLcontextModes *glVisual, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate) { GLcontext *ctx, *shareCtx; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; gammaContextPtr gmesa; gammaScreenPtr gammascrn; GLINTSAREADRIPtr saPriv=(GLINTSAREADRIPtr)(((char*)sPriv->pSAREA)+ sizeof(drm_sarea_t)); struct dd_function_table functions; gmesa = (gammaContextPtr) CALLOC( sizeof(*gmesa) ); if (!gmesa) return GL_FALSE; /* Init default driver functions then plug in our gamma-specific functions * (the texture functions are especially important) */ _mesa_init_driver_functions( &functions ); gammaDDInitTextureFuncs( &functions ); /* Allocate the Mesa context */ if (sharedContextPrivate) shareCtx = ((gammaContextPtr) sharedContextPrivate)->glCtx; else shareCtx = NULL; gmesa->glCtx = _mesa_create_context(glVisual, shareCtx, &functions, (void *) gmesa); if (!gmesa->glCtx) { FREE(gmesa); return GL_FALSE; } gmesa->driContext = driContextPriv; gmesa->driScreen = sPriv; gmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */ gmesa->hHWContext = driContextPriv->hHWContext; gmesa->driHwLock = &sPriv->pSAREA->lock; gmesa->driFd = sPriv->fd; gmesa->sarea = saPriv; gammascrn = gmesa->gammaScreen = (gammaScreenPtr)(sPriv->private); ctx = gmesa->glCtx; ctx->Const.MaxTextureLevels = GAMMA_TEX_MAXLEVELS; ctx->Const.MaxTextureUnits = 1; /* Permedia 3 */ ctx->Const.MaxTextureImageUnits = 1; ctx->Const.MaxTextureCoordUnits = 1; ctx->Const.MinLineWidth = 0.0; ctx->Const.MaxLineWidth = 255.0; ctx->Const.MinLineWidthAA = 0.0; ctx->Const.MaxLineWidthAA = 65536.0; ctx->Const.MinPointSize = 0.0; ctx->Const.MaxPointSize = 255.0; ctx->Const.MinPointSizeAA = 0.5; /* 4x4 quality mode */ ctx->Const.MaxPointSizeAA = 16.0; ctx->Const.PointSizeGranularity = 0.25; gmesa->texHeap = mmInit( 0, gmesa->gammaScreen->textureSize ); make_empty_list(&gmesa->TexObjList); make_empty_list(&gmesa->SwappedOut); gmesa->CurrentTexObj[0] = 0; gmesa->CurrentTexObj[1] = 0; /* Permedia 3, second texture */ gmesa->RenderIndex = ~0; /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); /* Install the customized pipeline: */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, gamma_pipeline ); /* Configure swrast & TNL to match hardware characteristics: */ _swrast_allow_pixel_fog( ctx, GL_FALSE ); _swrast_allow_vertex_fog( ctx, GL_TRUE ); _tnl_allow_pixel_fog( ctx, GL_FALSE ); _tnl_allow_vertex_fog( ctx, GL_TRUE ); gammaInitVB( ctx ); gammaDDInitExtensions( ctx ); /* XXX these should really go right after _mesa_init_driver_functions() */ gammaDDInitDriverFuncs( ctx ); gammaDDInitStateFuncs( ctx ); gammaDDInitSpanFuncs( ctx ); gammaDDInitTriFuncs( ctx ); gammaDDInitState( gmesa ); gammaInitTextureObjects( ctx ); driContextPriv->driverPrivate = (void *)gmesa; GET_FIRST_DMA(gmesa->driFd, gmesa->hHWContext, 1, &gmesa->bufIndex, &gmesa->bufSize, &gmesa->buf, &gmesa->bufCount, gammascrn); #ifdef DO_VALIDATE GET_FIRST_DMA(gmesa->driFd, gmesa->hHWContext, 1, &gmesa->WCbufIndex, &gmesa->WCbufSize, &gmesa->WCbuf, &gmesa->WCbufCount, gammascrn); #endif switch (glVisual->depthBits) { case 16: gmesa->DeltaMode = DM_Depth16; gmesa->depth_scale = 1.0f / 0xffff; break; case 24: gmesa->DeltaMode = DM_Depth24; gmesa->depth_scale = 1.0f / 0xffffff; break; case 32: gmesa->DeltaMode = DM_Depth32; gmesa->depth_scale = 1.0f / 0xffffffff; break; default: break; } gmesa->DepthSize = glVisual->depthBits; gmesa->Flags = GAMMA_FRONT_BUFFER; gmesa->Flags |= (glVisual->doubleBufferMode ? GAMMA_BACK_BUFFER : 0); gmesa->Flags |= (gmesa->DepthSize > 0 ? GAMMA_DEPTH_BUFFER : 0); gmesa->EnabledFlags = GAMMA_FRONT_BUFFER; gmesa->EnabledFlags |= (glVisual->doubleBufferMode ? GAMMA_BACK_BUFFER : 0); if (gmesa->Flags & GAMMA_BACK_BUFFER) { gmesa->readOffset = gmesa->drawOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp; } else { gmesa->readOffset = gmesa->drawOffset = 0; } gammaInitHW( gmesa ); driContextPriv->driverPrivate = (void *)gmesa; return GL_TRUE; }