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