Move fallback debugging under MACH64_DEBUG=fall (matching other drivers) and
[mesa.git] / src / mesa / drivers / dri / mach64 / mach64_context.c
1 /* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3 * Copyright 2000 Gareth Hughes
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
30 */
31
32 #include "glheader.h"
33 #include "context.h"
34 #include "simple_list.h"
35 #include "imports.h"
36 #include "matrix.h"
37 #include "extensions.h"
38
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "array_cache/acache.h"
42
43 #include "tnl/tnl.h"
44 #include "tnl/t_pipeline.h"
45
46 #include "drivers/common/driverfuncs.h"
47
48 #include "mach64_context.h"
49 #include "mach64_ioctl.h"
50 #include "mach64_dd.h"
51 #include "mach64_span.h"
52 #include "mach64_state.h"
53 #include "mach64_tex.h"
54 #include "mach64_tris.h"
55 #include "mach64_vb.h"
56
57 #include "utils.h"
58 #include "vblank.h"
59
60 #ifndef MACH64_DEBUG
61 int MACH64_DEBUG = (0);
62 #endif
63
64 static const struct dri_debug_control debug_control[] =
65 {
66 { "sync", DEBUG_ALWAYS_SYNC },
67 { "api", DEBUG_VERBOSE_API },
68 { "msg", DEBUG_VERBOSE_MSG },
69 { "lru", DEBUG_VERBOSE_LRU },
70 { "dri", DEBUG_VERBOSE_DRI },
71 { "ioctl", DEBUG_VERBOSE_IOCTL },
72 { "prims", DEBUG_VERBOSE_PRIMS },
73 { "count", DEBUG_VERBOSE_COUNT },
74 { "nowait", DEBUG_NOWAIT },
75 { "fall", DEBUG_VERBOSE_FALLBACK },
76 { NULL, 0 }
77 };
78
79 static const char * const card_extensions[] =
80 {
81 "GL_ARB_multitexture",
82 "GL_EXT_texture_edge_clamp",
83 "GL_MESA_ycbcr_texture",
84 "GL_SGIS_generate_mipmap",
85 "GL_SGIS_texture_edge_clamp",
86 NULL
87 };
88
89
90 /* Create the device specific context.
91 */
92 GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
93 __DRIcontextPrivate *driContextPriv,
94 void *sharedContextPrivate )
95 {
96 GLcontext *ctx, *shareCtx;
97 __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv;
98 struct dd_function_table functions;
99 mach64ContextPtr mmesa;
100 mach64ScreenPtr mach64Screen;
101 int i, heap;
102
103 #if DO_DEBUG
104 MACH64_DEBUG = driParseDebugString(getenv("MACH64_DEBUG"), debug_control);
105 #endif
106
107 /* Allocate the mach64 context */
108 mmesa = (mach64ContextPtr) CALLOC( sizeof(*mmesa) );
109 if ( !mmesa )
110 return GL_FALSE;
111
112 /* Init default driver functions then plug in our Mach64-specific functions
113 * (the texture functions are especially important)
114 */
115 _mesa_init_driver_functions( &functions );
116 mach64InitDriverFuncs( &functions );
117 mach64InitIoctlFuncs( &functions );
118 mach64InitTextureFuncs( &functions );
119
120 /* Allocate the Mesa context */
121 if (sharedContextPrivate)
122 shareCtx = ((mach64ContextPtr) sharedContextPrivate)->glCtx;
123 else
124 shareCtx = NULL;
125 mmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
126 &functions, (void *)mmesa);
127 if (!mmesa->glCtx) {
128 FREE(mmesa);
129 return GL_FALSE;
130 }
131 driContextPriv->driverPrivate = mmesa;
132 ctx = mmesa->glCtx;
133
134 mmesa->driContext = driContextPriv;
135 mmesa->driScreen = driScreen;
136 mmesa->driDrawable = NULL;
137 mmesa->hHWContext = driContextPriv->hHWContext;
138 mmesa->driHwLock = &driScreen->pSAREA->lock;
139 mmesa->driFd = driScreen->fd;
140
141 mach64Screen = mmesa->mach64Screen = (mach64ScreenPtr)driScreen->private;
142
143 /* Parse configuration files */
144 driParseConfigFiles (&mmesa->optionCache, &mach64Screen->optionCache,
145 mach64Screen->driScreen->myNum, "mach64");
146
147 mmesa->sarea = (drm_mach64_sarea_t *)((char *)driScreen->pSAREA +
148 sizeof(drm_sarea_t));
149
150 mmesa->CurrentTexObj[0] = NULL;
151 mmesa->CurrentTexObj[1] = NULL;
152
153 make_empty_list( &mmesa->SwappedOut );
154
155 mmesa->firstTexHeap = mach64Screen->firstTexHeap;
156 mmesa->lastTexHeap = mach64Screen->firstTexHeap + mach64Screen->numTexHeaps;
157
158 for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
159 make_empty_list( &mmesa->TexObjList[i] );
160 mmesa->texHeap[i] = mmInit( 0, mach64Screen->texSize[i] );
161 mmesa->lastTexAge[i] = -1;
162 }
163
164 mmesa->RenderIndex = -1; /* Impossible value */
165 mmesa->vert_buf = NULL;
166 mmesa->num_verts = 0;
167 mmesa->new_state = MACH64_NEW_ALL;
168 mmesa->dirty = MACH64_UPLOAD_ALL;
169
170 /* Set the maximum texture size small enough that we can
171 * guarentee that both texture units can bind a maximal texture
172 * and have them both in memory (on-card or AGP) at once.
173 * Test for 2 textures * bytes/texel * size * size. There's no
174 * need to account for mipmaps since we only upload one level.
175 */
176 heap = mach64Screen->IsPCI ? MACH64_CARD_HEAP : MACH64_AGP_HEAP;
177
178 if ( mach64Screen->texSize[heap] >= 2 * mach64Screen->cpp * 1024*1024 ) {
179 ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */
180 } else if ( mach64Screen->texSize[heap] >= 2 * mach64Screen->cpp * 512*512 ) {
181 ctx->Const.MaxTextureLevels = 10; /* 512x512 */
182 } else {
183 ctx->Const.MaxTextureLevels = 9; /* 256x256 */
184 }
185
186 ctx->Const.MaxTextureUnits = 2;
187
188 #if ENABLE_PERF_BOXES
189 mmesa->boxes = ( getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL );
190 #endif
191
192 /* Allocate the vertex buffer
193 */
194 mmesa->vert_buf = ALIGN_MALLOC(MACH64_BUFFER_SIZE, 32);
195 if ( !mmesa->vert_buf )
196 return GL_FALSE;
197 mmesa->vert_used = 0;
198 mmesa->vert_total = MACH64_BUFFER_SIZE;
199
200 /* Initialize the software rasterizer and helper modules.
201 */
202 _swrast_CreateContext( ctx );
203 _ac_CreateContext( ctx );
204 _tnl_CreateContext( ctx );
205 _swsetup_CreateContext( ctx );
206
207 /* Install the customized pipeline:
208 */
209 /* _tnl_destroy_pipeline( ctx ); */
210 /* _tnl_install_pipeline( ctx, mach64_pipeline ); */
211
212 /* Configure swrast and T&L to match hardware characteristics:
213 */
214 _swrast_allow_pixel_fog( ctx, GL_FALSE );
215 _swrast_allow_vertex_fog( ctx, GL_TRUE );
216 _tnl_allow_pixel_fog( ctx, GL_FALSE );
217 _tnl_allow_vertex_fog( ctx, GL_TRUE );
218
219 driInitExtensions( ctx, card_extensions, GL_TRUE );
220
221 mach64InitVB( ctx );
222 mach64InitTriFuncs( ctx );
223 mach64DDInitStateFuncs( ctx );
224 mach64DDInitSpanFuncs( ctx );
225 mach64DDInitState( mmesa );
226
227 mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS"));
228
229 mmesa->vblank_flags = (mmesa->do_irqs)
230 ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
231
232 driContextPriv->driverPrivate = (void *)mmesa;
233
234 if (driQueryOptionb(&mmesa->optionCache, "no_rast")) {
235 fprintf(stderr, "disabling 3D acceleration\n");
236 FALLBACK(mmesa, MACH64_FALLBACK_DISABLE, 1);
237 }
238
239 return GL_TRUE;
240 }
241
242 /* Destroy the device specific context.
243 */
244 void mach64DestroyContext( __DRIcontextPrivate *driContextPriv )
245 {
246 mach64ContextPtr mmesa = (mach64ContextPtr) driContextPriv->driverPrivate;
247
248 assert(mmesa); /* should never be null */
249 if ( mmesa ) {
250 if (mmesa->glCtx->Shared->RefCount == 1) {
251 /* This share group is about to go away, free our private
252 * texture object data.
253 */
254 mach64TexObjPtr t, next_t;
255 int i;
256
257 for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) {
258 foreach_s ( t, next_t, &mmesa->TexObjList[i] ) {
259 mach64DestroyTexObj( mmesa, t );
260 }
261 mmDestroy( mmesa->texHeap[i] );
262 mmesa->texHeap[i] = NULL;
263 }
264
265 foreach_s ( t, next_t, &mmesa->SwappedOut ) {
266 mach64DestroyTexObj( mmesa, t );
267 }
268 }
269
270 _swsetup_DestroyContext( mmesa->glCtx );
271 _tnl_DestroyContext( mmesa->glCtx );
272 _ac_DestroyContext( mmesa->glCtx );
273 _swrast_DestroyContext( mmesa->glCtx );
274
275 mach64FreeVB( mmesa->glCtx );
276
277 /* Free the vertex buffer */
278 if ( mmesa->vert_buf )
279 ALIGN_FREE( mmesa->vert_buf );
280
281 /* free the Mesa context */
282 mmesa->glCtx->DriverCtx = NULL;
283 _mesa_destroy_context(mmesa->glCtx);
284
285 FREE( mmesa );
286 }
287 }
288
289 /* Force the context `c' to be the current context and associate with it
290 * buffer `b'.
291 */
292 GLboolean
293 mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
294 __DRIdrawablePrivate *driDrawPriv,
295 __DRIdrawablePrivate *driReadPriv )
296 {
297 if ( driContextPriv ) {
298 GET_CURRENT_CONTEXT(ctx);
299 mach64ContextPtr oldMach64Ctx = ctx ? MACH64_CONTEXT(ctx) : NULL;
300 mach64ContextPtr newMach64Ctx = (mach64ContextPtr) driContextPriv->driverPrivate;
301
302 if ( newMach64Ctx != oldMach64Ctx ) {
303 newMach64Ctx->new_state |= MACH64_NEW_CONTEXT;
304 newMach64Ctx->dirty = MACH64_UPLOAD_ALL;
305 }
306
307
308 driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags );
309
310 if ( newMach64Ctx->driDrawable != driDrawPriv ) {
311 newMach64Ctx->driDrawable = driDrawPriv;
312 mach64CalcViewport( newMach64Ctx->glCtx );
313 }
314
315 _mesa_make_current( newMach64Ctx->glCtx,
316 (GLframebuffer *) driDrawPriv->driverPrivate,
317 (GLframebuffer *) driReadPriv->driverPrivate );
318
319
320 newMach64Ctx->new_state |= MACH64_NEW_CLIP;
321 } else {
322 _mesa_make_current( NULL, NULL, NULL );
323 }
324
325 return GL_TRUE;
326 }
327
328
329 /* Force the context `c' to be unbound from its buffer.
330 */
331 GLboolean
332 mach64UnbindContext( __DRIcontextPrivate *driContextPriv )
333 {
334 return GL_TRUE;
335 }