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