95e54a6af500f1e2faf3f3fcfbfb40fa072d7b66
[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 "vbo/vbo.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_ARB_vertex_buffer_object
72 #define need_GL_EXT_blend_minmax
73 #define need_GL_EXT_fog_coord
74 #define need_GL_EXT_secondary_color
75 #include "extension_helper.h"
76
77 const struct dri_extension card_extensions[] =
78 {
79 { "GL_ARB_multisample", GL_ARB_multisample_functions },
80 { "GL_ARB_multitexture", NULL },
81 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
82 { "GL_ARB_texture_env_add", NULL },
83 { "GL_ARB_texture_mirrored_repeat", NULL },
84 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
85 { "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions },
86 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
87 { "GL_EXT_texture_edge_clamp", NULL },
88 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
89 { "GL_EXT_stencil_wrap", NULL },
90 { "GL_MESA_ycbcr_texture", NULL },
91 { "GL_NV_blend_square", NULL },
92 { "GL_SGIS_generate_mipmap", NULL },
93 { NULL, NULL }
94 };
95
96 static const struct dri_debug_control debug_control[] =
97 {
98 { "ioctl", DEBUG_VERBOSE_IOCTL },
99 { "verb", DEBUG_VERBOSE_MSG },
100 { "dri", DEBUG_VERBOSE_DRI },
101 { "2d", DEBUG_VERBOSE_2D },
102 { "sync", DEBUG_ALWAYS_SYNC },
103 { "api", DEBUG_VERBOSE_API },
104 { "fall", DEBUG_VERBOSE_FALL },
105 { NULL, 0 }
106 };
107
108 /* Create the device specific context.
109 */
110 GLboolean r128CreateContext( const __GLcontextModes *glVisual,
111 __DRIcontextPrivate *driContextPriv,
112 void *sharedContextPrivate )
113 {
114 GLcontext *ctx, *shareCtx;
115 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
116 struct dd_function_table functions;
117 r128ContextPtr rmesa;
118 r128ScreenPtr r128scrn;
119 int i;
120
121 /* Allocate the r128 context */
122 rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) );
123 if ( !rmesa )
124 return GL_FALSE;
125
126 /* Init default driver functions then plug in our Radeon-specific functions
127 * (the texture functions are especially important)
128 */
129 _mesa_init_driver_functions( &functions );
130 r128InitDriverFuncs( &functions );
131 r128InitIoctlFuncs( &functions );
132 r128InitTextureFuncs( &functions );
133
134 /* Allocate the Mesa context */
135 if (sharedContextPrivate)
136 shareCtx = ((r128ContextPtr) sharedContextPrivate)->glCtx;
137 else
138 shareCtx = NULL;
139 rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
140 &functions, (void *) rmesa);
141 if (!rmesa->glCtx) {
142 FREE(rmesa);
143 return GL_FALSE;
144 }
145 driContextPriv->driverPrivate = rmesa;
146 ctx = rmesa->glCtx;
147
148 rmesa->driContext = driContextPriv;
149 rmesa->driScreen = sPriv;
150 rmesa->driDrawable = NULL;
151 rmesa->hHWContext = driContextPriv->hHWContext;
152 rmesa->driHwLock = &sPriv->pSAREA->lock;
153 rmesa->driFd = sPriv->fd;
154
155 r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private);
156
157 /* Parse configuration files */
158 driParseConfigFiles (&rmesa->optionCache, &r128scrn->optionCache,
159 r128scrn->driScreen->myNum, "r128");
160
161 rmesa->sarea = (drm_r128_sarea_t *)((char *)sPriv->pSAREA +
162 r128scrn->sarea_priv_offset);
163
164 rmesa->CurrentTexObj[0] = NULL;
165 rmesa->CurrentTexObj[1] = NULL;
166
167 (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
168 make_empty_list( & rmesa->swapped );
169
170 rmesa->nr_heaps = r128scrn->numTexHeaps;
171 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
172 rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
173 r128scrn->texSize[i],
174 12,
175 R128_NR_TEX_REGIONS,
176 (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
177 &rmesa->sarea->tex_age[i],
178 &rmesa->swapped,
179 sizeof( r128TexObj ),
180 (destroy_texture_object_t *) r128DestroyTexObj );
181
182 driSetTextureSwapCounterLocation( rmesa->texture_heaps[i],
183 & rmesa->c_textureSwaps );
184 }
185 rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
186 "texture_depth");
187 if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
188 rmesa->texture_depth = ( r128scrn->cpp == 4 ) ?
189 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
190
191
192 rmesa->RenderIndex = -1; /* Impossible value */
193 rmesa->vert_buf = NULL;
194 rmesa->num_verts = 0;
195 RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
196
197 /* Set the maximum texture size small enough that we can guarentee that
198 * all texture units can bind a maximal texture and have them both in
199 * texturable memory at once.
200 */
201
202 ctx->Const.MaxTextureUnits = 2;
203 ctx->Const.MaxTextureImageUnits = 2;
204 ctx->Const.MaxTextureCoordUnits = 2;
205
206 driCalculateMaxTextureLevels( rmesa->texture_heaps,
207 rmesa->nr_heaps,
208 & ctx->Const,
209 4,
210 10, /* max 2D texture size is 1024x1024 */
211 0, /* 3D textures unsupported. */
212 0, /* cube textures unsupported. */
213 0, /* texture rectangles unsupported. */
214 11,
215 GL_FALSE,
216 0 );
217
218 /* No wide points.
219 */
220 ctx->Const.MinPointSize = 1.0;
221 ctx->Const.MinPointSizeAA = 1.0;
222 ctx->Const.MaxPointSize = 1.0;
223 ctx->Const.MaxPointSizeAA = 1.0;
224
225 /* No wide lines.
226 */
227 ctx->Const.MinLineWidth = 1.0;
228 ctx->Const.MinLineWidthAA = 1.0;
229 ctx->Const.MaxLineWidth = 1.0;
230 ctx->Const.MaxLineWidthAA = 1.0;
231 ctx->Const.LineWidthGranularity = 1.0;
232
233 #if ENABLE_PERF_BOXES
234 rmesa->boxes = driQueryOptionb(&rmesa->optionCache, "performance_boxes");
235 #endif
236
237 /* Initialize the software rasterizer and helper modules.
238 */
239 _swrast_CreateContext( ctx );
240 _vbo_CreateContext( ctx );
241 _tnl_CreateContext( ctx );
242 _swsetup_CreateContext( ctx );
243
244 /* Install the customized pipeline:
245 */
246 /* _tnl_destroy_pipeline( ctx ); */
247 /* _tnl_install_pipeline( ctx, r128_pipeline ); */
248
249 /* Configure swrast and T&L to match hardware characteristics:
250 */
251 _swrast_allow_pixel_fog( ctx, GL_FALSE );
252 _swrast_allow_vertex_fog( ctx, GL_TRUE );
253 _tnl_allow_pixel_fog( ctx, GL_FALSE );
254 _tnl_allow_vertex_fog( ctx, GL_TRUE );
255
256 driInitExtensions( ctx, card_extensions, GL_TRUE );
257 if (sPriv->drmMinor >= 4)
258 _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
259
260 r128InitTriFuncs( ctx );
261 r128DDInitStateFuncs( ctx );
262 r128DDInitSpanFuncs( ctx );
263 r128DDInitState( rmesa );
264
265 rmesa->vblank_flags = (rmesa->r128Screen->irq != 0)
266 ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
267
268 driContextPriv->driverPrivate = (void *)rmesa;
269
270 #if DO_DEBUG
271 R128_DEBUG = driParseDebugString( getenv( "R128_DEBUG" ),
272 debug_control );
273 #endif
274
275 if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
276 fprintf(stderr, "disabling 3D acceleration\n");
277 FALLBACK(rmesa, R128_FALLBACK_DISABLE, 1);
278 }
279
280 return GL_TRUE;
281 }
282
283 /* Destroy the device specific context.
284 */
285 void r128DestroyContext( __DRIcontextPrivate *driContextPriv )
286 {
287 r128ContextPtr rmesa = (r128ContextPtr) driContextPriv->driverPrivate;
288
289 assert(rmesa); /* should never be null */
290 if ( rmesa ) {
291 GLboolean release_texture_heaps;
292
293
294 release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
295
296 _swsetup_DestroyContext( rmesa->glCtx );
297 _tnl_DestroyContext( rmesa->glCtx );
298 _vbo_DestroyContext( rmesa->glCtx );
299 _swrast_DestroyContext( rmesa->glCtx );
300
301 if ( release_texture_heaps ) {
302 /* This share group is about to go away, free our private
303 * texture object data.
304 */
305 int i;
306
307 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
308 driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
309 rmesa->texture_heaps[ i ] = NULL;
310 }
311
312 assert( is_empty_list( & rmesa->swapped ) );
313 }
314
315 /* free the Mesa context */
316 rmesa->glCtx->DriverCtx = NULL;
317 _mesa_destroy_context(rmesa->glCtx);
318
319 /* free the option cache */
320 driDestroyOptionCache (&rmesa->optionCache);
321
322 FREE( rmesa );
323 }
324
325 #if 0
326 /* Use this to force shared object profiling. */
327 glx_fini_prof();
328 #endif
329 }
330
331
332 /* Force the context `c' to be the current context and associate with it
333 * buffer `b'.
334 */
335 GLboolean
336 r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
337 __DRIdrawablePrivate *driDrawPriv,
338 __DRIdrawablePrivate *driReadPriv )
339 {
340 if ( driContextPriv ) {
341 GET_CURRENT_CONTEXT(ctx);
342 r128ContextPtr oldR128Ctx = ctx ? R128_CONTEXT(ctx) : NULL;
343 r128ContextPtr newR128Ctx = (r128ContextPtr) driContextPriv->driverPrivate;
344
345 if ( newR128Ctx != oldR128Ctx ) {
346 newR128Ctx->new_state |= R128_NEW_CONTEXT;
347 newR128Ctx->dirty = R128_UPLOAD_ALL;
348 }
349
350 driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags,
351 &newR128Ctx->vbl_seq );
352 newR128Ctx->driDrawable = driDrawPriv;
353
354 _mesa_make_current( newR128Ctx->glCtx,
355 (GLframebuffer *) driDrawPriv->driverPrivate,
356 (GLframebuffer *) driReadPriv->driverPrivate );
357
358 newR128Ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP;
359 } else {
360 _mesa_make_current( NULL, NULL, NULL );
361 }
362
363 return GL_TRUE;
364 }
365
366
367 /* Force the context `c' to be unbound from its buffer.
368 */
369 GLboolean
370 r128UnbindContext( __DRIcontextPrivate *driContextPriv )
371 {
372 return GL_TRUE;
373 }