add gamma driver - no kernel driver yet
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_context.c
1 /*
2 * Copyright 2001 by Alan Hourihane.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
23 *
24 * 3DLabs Gamma driver.
25 *
26 */
27 #include "gamma_context.h"
28
29 #include "swrast/swrast.h"
30 #include "swrast_setup/swrast_setup.h"
31 #include "array_cache/acache.h"
32
33 #include "tnl/tnl.h"
34 #include "tnl/t_pipeline.h"
35
36 #include "context.h"
37 #include "simple_list.h"
38 #include "imports.h"
39 #include "matrix.h"
40 #include "extensions.h"
41 #if defined(USE_X86_ASM)
42 #include "X86/common_x86_asm.h"
43 #endif
44 #include "simple_list.h"
45 #include "mm.h"
46
47
48 #include "gamma_vb.h"
49 #include "gamma_tris.h"
50
51 extern const struct gl_pipeline_stage _gamma_render_stage;
52
53 static const struct gl_pipeline_stage *gamma_pipeline[] = {
54 &_tnl_vertex_transform_stage,
55 &_tnl_normal_transform_stage,
56 &_tnl_lighting_stage,
57 &_tnl_fog_coordinate_stage,
58 &_tnl_texgen_stage,
59 &_tnl_texture_transform_stage,
60 /* REMOVE: point attenuation stage */
61 #if 1
62 &_gamma_render_stage, /* ADD: unclipped rastersetup-to-dma */
63 #endif
64 &_tnl_render_stage,
65 0,
66 };
67
68 GLboolean gammaCreateContext( const __GLcontextModes *glVisual,
69 __DRIcontextPrivate *driContextPriv,
70 void *sharedContextPrivate)
71 {
72 GLcontext *ctx, *shareCtx;
73 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
74 gammaContextPtr gmesa;
75 gammaScreenPtr gammascrn;
76 GLINTSAREADRIPtr saPriv=(GLINTSAREADRIPtr)(((char*)sPriv->pSAREA)+
77 sizeof(XF86DRISAREARec));
78
79 gmesa = (gammaContextPtr) CALLOC( sizeof(*gmesa) );
80 if ( !gmesa ) return GL_FALSE;
81
82 /* Allocate the Mesa context */
83 if (sharedContextPrivate)
84 shareCtx = ((gammaContextPtr) sharedContextPrivate)->glCtx;
85 else
86 shareCtx = NULL;
87
88 gmesa->glCtx = _mesa_create_context(glVisual, shareCtx, (void *) gmesa, GL_TRUE);
89 if (!gmesa->glCtx) {
90 FREE(gmesa);
91 return GL_FALSE;
92 }
93
94 gmesa->driContext = driContextPriv;
95 gmesa->driScreen = sPriv;
96 gmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
97
98 gmesa->hHWContext = driContextPriv->hHWContext;
99 gmesa->driHwLock = &sPriv->pSAREA->lock;
100 gmesa->driFd = sPriv->fd;
101 gmesa->sarea = saPriv;
102
103 gammascrn = gmesa->gammaScreen = (gammaScreenPtr)(sPriv->private);
104
105 ctx = gmesa->glCtx;
106
107 ctx->Const.MaxTextureLevels = 13; /* 4K by 4K? Is that right? */
108 ctx->Const.MaxTextureUnits = 1; /* Permedia 3 */
109
110 ctx->Const.MinLineWidth = 0.0;
111 ctx->Const.MaxLineWidth = 255.0;
112
113 ctx->Const.MinLineWidthAA = 0.0;
114 ctx->Const.MaxLineWidthAA = 65536.0;
115
116 ctx->Const.MinPointSize = 0.0;
117 ctx->Const.MaxPointSize = 255.0;
118
119 ctx->Const.MinPointSizeAA = 0.5; /* 4x4 quality mode */
120 ctx->Const.MaxPointSizeAA = 16.0;
121 ctx->Const.PointSizeGranularity = 0.25;
122
123 gmesa->texHeap = mmInit( 0, gmesa->gammaScreen->textureSize );
124
125 make_empty_list(&gmesa->TexObjList);
126 make_empty_list(&gmesa->SwappedOut);
127
128 gmesa->CurrentTexObj[0] = 0;
129 gmesa->CurrentTexObj[1] = 0; /* Permedia 3, second texture */
130
131 gmesa->RenderIndex = ~0;
132
133
134 /* Initialize the software rasterizer and helper modules.
135 */
136 _swrast_CreateContext( ctx );
137 _ac_CreateContext( ctx );
138 _tnl_CreateContext( ctx );
139 _swsetup_CreateContext( ctx );
140
141 /* Install the customized pipeline:
142 */
143 _tnl_destroy_pipeline( ctx );
144 _tnl_install_pipeline( ctx, gamma_pipeline );
145
146 /* Configure swrast to match hardware characteristics:
147 */
148 _swrast_allow_pixel_fog( ctx, GL_FALSE );
149 _swrast_allow_vertex_fog( ctx, GL_TRUE );
150
151 gammaInitVB( ctx );
152 gammaDDInitExtensions( ctx );
153 gammaDDInitDriverFuncs( ctx );
154 gammaDDInitStateFuncs( ctx );
155 gammaDDInitSpanFuncs( ctx );
156 gammaDDInitTextureFuncs( ctx );
157 gammaDDInitTriFuncs( ctx );
158 gammaDDInitState( gmesa );
159
160 driContextPriv->driverPrivate = (void *)gmesa;
161
162 GET_FIRST_DMA(gmesa->driFd, gmesa->hHWContext,
163 1, &gmesa->bufIndex, &gmesa->bufSize,
164 &gmesa->buf, &gmesa->bufCount, gammascrn);
165
166 #ifdef DO_VALIDATE
167 GET_FIRST_DMA(gmesa->driFd, gmesa->hHWContext,
168 1, &gmesa->WCbufIndex, &gmesa->WCbufSize,
169 &gmesa->WCbuf, &gmesa->WCbufCount, gammascrn);
170 #endif
171
172 switch (glVisual->depthBits) {
173 case 16:
174 gmesa->DeltaMode = DM_Depth16;
175 gmesa->depth_scale = 1.0f / 0xffff;
176 break;
177 case 24:
178 gmesa->DeltaMode = DM_Depth24;
179 gmesa->depth_scale = 1.0f / 0xffffff;
180 break;
181 case 32:
182 gmesa->DeltaMode = DM_Depth32;
183 gmesa->depth_scale = 1.0f / 0xffffffff;
184 break;
185 default:
186 break;
187 }
188
189 gmesa->DepthSize = glVisual->depthBits;
190 gmesa->Flags = GAMMA_FRONT_BUFFER;
191 gmesa->Flags |= (glVisual->doubleBufferMode ? GAMMA_BACK_BUFFER : 0);
192 gmesa->Flags |= (gmesa->DepthSize > 0 ? GAMMA_DEPTH_BUFFER : 0);
193
194 gmesa->EnabledFlags = GAMMA_FRONT_BUFFER;
195 gmesa->EnabledFlags |= (glVisual->doubleBufferMode ? GAMMA_BACK_BUFFER : 0);
196
197
198 if (gmesa->Flags & GAMMA_BACK_BUFFER) {
199 gmesa->readOffset = gmesa->drawOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp;
200 } else {
201 gmesa->readOffset = gmesa->drawOffset = 0;
202 }
203
204 gammaInitHW( gmesa );
205
206 driContextPriv->driverPrivate = (void *)gmesa;
207
208 return GL_TRUE;
209 }