blob: b1dcbfcdcfaa150b7d76f1e57d4e1a2c04801b55 [file] [log] [blame]
/*
* 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;
}