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