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