Add support for GL_EXT_fog_coord, tested using tests/fog.c. (Also, matches the
[mesa.git] / src / mesa / drivers / dri / r128 / r128_context.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.8 2002/10/30 12:51:38 alanh Exp $ */
2 /**************************************************************************
3
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
5 Cedar Park, Texas.
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Kevin E. Martin <martin@valinux.com>
32 * Gareth Hughes <gareth@valinux.com>
33 *
34 */
35
36 #include "glheader.h"
37 #include "context.h"
38 #include "simple_list.h"
39 #include "imports.h"
40 #include "matrix.h"
41 #include "extensions.h"
42
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "array_cache/acache.h"
46
47 #include "tnl/tnl.h"
48 #include "tnl/t_pipeline.h"
49
50 #include "drivers/common/driverfuncs.h"
51
52 #include "r128_context.h"
53 #include "r128_ioctl.h"
54 #include "r128_dd.h"
55 #include "r128_state.h"
56 #include "r128_span.h"
57 #include "r128_tex.h"
58 #include "r128_tris.h"
59
60 #include "vblank.h"
61 #include "utils.h"
62 #include "texmem.h"
63 #include "xmlpool.h" /* for symbolic values of enum-type options */
64
65 #ifndef R128_DEBUG
66 int R128_DEBUG = 0;
67 #endif
68
69 #define need_GL_ARB_multisample
70 #define need_GL_ARB_texture_compression
71 #define need_GL_EXT_fog_coord
72 #define need_GL_EXT_blend_minmax
73 #include "extension_helper.h"
74
75 const struct dri_extension card_extensions[] =
76 {
77 { "GL_ARB_multisample", GL_ARB_multisample_functions },
78 { "GL_ARB_multitexture", NULL },
79 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
80 { "GL_ARB_texture_env_add", NULL },
81 { "GL_ARB_texture_mirrored_repeat", NULL },
82 { "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions },
83 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
84 { "GL_EXT_texture_edge_clamp", NULL },
85 { "GL_MESA_ycbcr_texture", NULL },
86 { "GL_NV_blend_square", NULL },
87 { "GL_SGIS_generate_mipmap", NULL },
88 { NULL, NULL }
89 };
90
91 static const struct dri_debug_control debug_control[] =
92 {
93 { "ioctl", DEBUG_VERBOSE_IOCTL },
94 { "verb", DEBUG_VERBOSE_MSG },
95 { "dri", DEBUG_VERBOSE_DRI },
96 { "2d", DEBUG_VERBOSE_2D },
97 { "sync", DEBUG_ALWAYS_SYNC },
98 { "api", DEBUG_VERBOSE_API },
99 { "fall", DEBUG_VERBOSE_FALL },
100 { NULL, 0 }
101 };
102
103 /* Create the device specific context.
104 */
105 GLboolean r128CreateContext( const __GLcontextModes *glVisual,
106 __DRIcontextPrivate *driContextPriv,
107 void *sharedContextPrivate )
108 {
109 GLcontext *ctx, *shareCtx;
110 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
111 struct dd_function_table functions;
112 r128ContextPtr rmesa;
113 r128ScreenPtr r128scrn;
114 int i;
115
116 /* Allocate the r128 context */
117 rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) );
118 if ( !rmesa )
119 return GL_FALSE;
120
121 /* Init default driver functions then plug in our Radeon-specific functions
122 * (the texture functions are especially important)
123 */
124 _mesa_init_driver_functions( &functions );
125 r128InitDriverFuncs( &functions );
126 r128InitIoctlFuncs( &functions );
127 r128InitTextureFuncs( &functions );
128
129 /* Allocate the Mesa context */
130 if (sharedContextPrivate)
131 shareCtx = ((r128ContextPtr) sharedContextPrivate)->glCtx;
132 else
133 shareCtx = NULL;
134 rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
135 &functions, (void *) rmesa);
136 if (!rmesa->glCtx) {
137 FREE(rmesa);
138 return GL_FALSE;
139 }
140 driContextPriv->driverPrivate = rmesa;
141 ctx = rmesa->glCtx;
142
143 rmesa->driContext = driContextPriv;
144 rmesa->driScreen = sPriv;
145 rmesa->driDrawable = NULL;
146 rmesa->hHWContext = driContextPriv->hHWContext;
147 rmesa->driHwLock = &sPriv->pSAREA->lock;
148 rmesa->driFd = sPriv->fd;
149
150 r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private);
151
152 /* Parse configuration files */
153 driParseConfigFiles (&rmesa->optionCache, &r128scrn->optionCache,
154 r128scrn->driScreen->myNum, "r128");
155
156 rmesa->sarea = (drm_r128_sarea_t *)((char *)sPriv->pSAREA +
157 r128scrn->sarea_priv_offset);
158
159 rmesa->CurrentTexObj[0] = NULL;
160 rmesa->CurrentTexObj[1] = NULL;
161
162 (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
163 make_empty_list( & rmesa->swapped );
164
165 rmesa->nr_heaps = r128scrn->numTexHeaps;
166 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
167 rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
168 r128scrn->texSize[i],
169 12,
170 R128_NR_TEX_REGIONS,
171 (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
172 &rmesa->sarea->tex_age[i],
173 &rmesa->swapped,
174 sizeof( r128TexObj ),
175 (destroy_texture_object_t *) r128DestroyTexObj );
176
177 driSetTextureSwapCounterLocation( rmesa->texture_heaps[i],
178 & rmesa->c_textureSwaps );
179 }
180 rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
181 "texture_depth");
182 if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
183 rmesa->texture_depth = ( r128scrn->cpp == 4 ) ?
184 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
185
186
187 rmesa->RenderIndex = -1; /* Impossible value */
188 rmesa->vert_buf = NULL;
189 rmesa->num_verts = 0;
190 rmesa->tnl_state = ~0;
191
192 /* Set the maximum texture size small enough that we can guarentee that
193 * all texture units can bind a maximal texture and have them both in
194 * texturable memory at once.
195 */
196
197 ctx->Const.MaxTextureUnits = 2;
198 ctx->Const.MaxTextureImageUnits = 2;
199 ctx->Const.MaxTextureCoordUnits = 2;
200
201 driCalculateMaxTextureLevels( rmesa->texture_heaps,
202 rmesa->nr_heaps,
203 & ctx->Const,
204 4,
205 10, /* max 2D texture size is 1024x1024 */
206 0, /* 3D textures unsupported. */
207 0, /* cube textures unsupported. */
208 0, /* texture rectangles unsupported. */
209 11,
210 GL_FALSE );
211
212 /* No wide points.
213 */
214 ctx->Const.MinPointSize = 1.0;
215 ctx->Const.MinPointSizeAA = 1.0;
216 ctx->Const.MaxPointSize = 1.0;
217 ctx->Const.MaxPointSizeAA = 1.0;
218
219 /* No wide lines.
220 */
221 ctx->Const.MinLineWidth = 1.0;
222 ctx->Const.MinLineWidthAA = 1.0;
223 ctx->Const.MaxLineWidth = 1.0;
224 ctx->Const.MaxLineWidthAA = 1.0;
225 ctx->Const.LineWidthGranularity = 1.0;
226
227 #if ENABLE_PERF_BOXES
228 rmesa->boxes = driQueryOptionb(&rmesa->optionCache, "performance_boxes");
229 #endif
230
231 /* Initialize the software rasterizer and helper modules.
232 */
233 _swrast_CreateContext( ctx );
234 _ac_CreateContext( ctx );
235 _tnl_CreateContext( ctx );
236 _swsetup_CreateContext( ctx );
237
238 /* Install the customized pipeline:
239 */
240 /* _tnl_destroy_pipeline( ctx ); */
241 /* _tnl_install_pipeline( ctx, r128_pipeline ); */
242
243 /* Configure swrast and T&L to match hardware characteristics:
244 */
245 _swrast_allow_pixel_fog( ctx, GL_FALSE );
246 _swrast_allow_vertex_fog( ctx, GL_TRUE );
247 _tnl_allow_pixel_fog( ctx, GL_FALSE );
248 _tnl_allow_vertex_fog( ctx, GL_TRUE );
249
250 driInitExtensions( ctx, card_extensions, GL_TRUE );
251 if (sPriv->drmMinor >= 4)
252 _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
253
254 r128InitTriFuncs( ctx );
255 r128DDInitStateFuncs( ctx );
256 r128DDInitSpanFuncs( ctx );
257 r128DDInitState( rmesa );
258
259 rmesa->vblank_flags = (rmesa->r128Screen->irq != 0)
260 ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
261
262 driContextPriv->driverPrivate = (void *)rmesa;
263
264 #if DO_DEBUG
265 R128_DEBUG = driParseDebugString( getenv( "R128_DEBUG" ),
266 debug_control );
267 #endif
268
269 if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
270 fprintf(stderr, "disabling 3D acceleration\n");
271 FALLBACK(rmesa, R128_FALLBACK_DISABLE, 1);
272 }
273
274 return GL_TRUE;
275 }
276
277 /* Destroy the device specific context.
278 */
279 void r128DestroyContext( __DRIcontextPrivate *driContextPriv )
280 {
281 r128ContextPtr rmesa = (r128ContextPtr) driContextPriv->driverPrivate;
282
283 assert(rmesa); /* should never be null */
284 if ( rmesa ) {
285 GLboolean release_texture_heaps;
286
287
288 release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
289
290 _swsetup_DestroyContext( rmesa->glCtx );
291 _tnl_DestroyContext( rmesa->glCtx );
292 _ac_DestroyContext( rmesa->glCtx );
293 _swrast_DestroyContext( rmesa->glCtx );
294
295 /* free the Mesa context */
296 rmesa->glCtx->DriverCtx = NULL;
297 _mesa_destroy_context(rmesa->glCtx);
298
299 if ( release_texture_heaps ) {
300 /* This share group is about to go away, free our private
301 * texture object data.
302 */
303 int i;
304
305 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
306 driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
307 rmesa->texture_heaps[ i ] = NULL;
308 }
309
310 assert( is_empty_list( & rmesa->swapped ) );
311 }
312
313 /* free the option cache */
314 driDestroyOptionCache (&rmesa->optionCache);
315
316 FREE( rmesa );
317 }
318
319 #if 0
320 /* Use this to force shared object profiling. */
321 glx_fini_prof();
322 #endif
323 }
324
325
326 /* Force the context `c' to be the current context and associate with it
327 * buffer `b'.
328 */
329 GLboolean
330 r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
331 __DRIdrawablePrivate *driDrawPriv,
332 __DRIdrawablePrivate *driReadPriv )
333 {
334 if ( driContextPriv ) {
335 GET_CURRENT_CONTEXT(ctx);
336 r128ContextPtr oldR128Ctx = ctx ? R128_CONTEXT(ctx) : NULL;
337 r128ContextPtr newR128Ctx = (r128ContextPtr) driContextPriv->driverPrivate;
338
339 if ( newR128Ctx != oldR128Ctx ) {
340 newR128Ctx->new_state |= R128_NEW_CONTEXT;
341 newR128Ctx->dirty = R128_UPLOAD_ALL;
342 }
343
344 driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags );
345 newR128Ctx->driDrawable = driDrawPriv;
346
347 _mesa_make_current( newR128Ctx->glCtx,
348 (GLframebuffer *) driDrawPriv->driverPrivate,
349 (GLframebuffer *) driReadPriv->driverPrivate );
350
351 newR128Ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP;
352 } else {
353 _mesa_make_current( NULL, NULL, NULL );
354 }
355
356 return GL_TRUE;
357 }
358
359
360 /* Force the context `c' to be unbound from its buffer.
361 */
362 GLboolean
363 r128UnbindContext( __DRIcontextPrivate *driContextPriv )
364 {
365 return GL_TRUE;
366 }