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