| /* |
| * 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, <alanh@tungstengraphics.com> |
| * |
| * 3DLabs Gamma driver. |
| * |
| */ |
| #include "gamma_context.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 "context.h" |
| #include "simple_list.h" |
| #include "imports.h" |
| #include "matrix.h" |
| #include "extensions.h" |
| #if defined(USE_X86_ASM) |
| #include "x86/common_x86_asm.h" |
| #endif |
| #include "simple_list.h" |
| #include "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; |
| } |