Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / r128 / r128_context.c
1 /**************************************************************************
2
3 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
4 Cedar Park, Texas.
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Kevin E. Martin <martin@valinux.com>
31 * Gareth Hughes <gareth@valinux.com>
32 *
33 */
34
35 #include "main/glheader.h"
36 #include "main/context.h"
37 #include "main/simple_list.h"
38 #include "main/imports.h"
39 #include "main/matrix.h"
40 #include "main/extensions.h"
41
42 #include "swrast/swrast.h"
43 #include "swrast_setup/swrast_setup.h"
44 #include "vbo/vbo.h"
45
46 #include "tnl/tnl.h"
47 #include "tnl/t_pipeline.h"
48
49 #include "drivers/common/driverfuncs.h"
50
51 #include "r128_context.h"
52 #include "r128_ioctl.h"
53 #include "r128_dd.h"
54 #include "r128_state.h"
55 #include "r128_span.h"
56 #include "r128_tex.h"
57 #include "r128_tris.h"
58
59 #include "vblank.h"
60 #include "utils.h"
61 #include "texmem.h"
62 #include "xmlpool.h" /* for symbolic values of enum-type options */
63
64 #ifndef R128_DEBUG
65 int R128_DEBUG = 0;
66 #endif
67
68 #define need_GL_EXT_blend_minmax
69 #define need_GL_EXT_fog_coord
70 #define need_GL_EXT_secondary_color
71 #include "main/remap_helper.h"
72
73 static const struct dri_extension card_extensions[] =
74 {
75 { "GL_ARB_multitexture", NULL },
76 { "GL_ARB_texture_env_add", NULL },
77 { "GL_ARB_texture_mirrored_repeat", NULL },
78 { "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions },
79 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
80 { "GL_EXT_texture_edge_clamp", NULL },
81 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
82 { "GL_EXT_stencil_wrap", NULL },
83 { "GL_MESA_ycbcr_texture", NULL },
84 { "GL_NV_blend_square", NULL },
85 { "GL_SGIS_generate_mipmap", NULL },
86 { NULL, NULL }
87 };
88
89 static const struct dri_debug_control debug_control[] =
90 {
91 { "ioctl", DEBUG_VERBOSE_IOCTL },
92 { "verb", DEBUG_VERBOSE_MSG },
93 { "dri", DEBUG_VERBOSE_DRI },
94 { "2d", DEBUG_VERBOSE_2D },
95 { "sync", DEBUG_ALWAYS_SYNC },
96 { "api", DEBUG_VERBOSE_API },
97 { "fall", DEBUG_VERBOSE_FALL },
98 { NULL, 0 }
99 };
100
101 /* Create the device specific context.
102 */
103 GLboolean r128CreateContext( const __GLcontextModes *glVisual,
104 __DRIcontext *driContextPriv,
105 void *sharedContextPrivate )
106 {
107 GLcontext *ctx, *shareCtx;
108 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
109 struct dd_function_table functions;
110 r128ContextPtr rmesa;
111 r128ScreenPtr r128scrn;
112 int i;
113
114 /* Allocate the r128 context */
115 rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) );
116 if ( !rmesa )
117 return GL_FALSE;
118
119 /* Init default driver functions then plug in our Radeon-specific functions
120 * (the texture functions are especially important)
121 */
122 _mesa_init_driver_functions( &functions );
123 r128InitDriverFuncs( &functions );
124 r128InitIoctlFuncs( &functions );
125 r128InitTextureFuncs( &functions );
126
127 /* Allocate the Mesa context */
128 if (sharedContextPrivate)
129 shareCtx = ((r128ContextPtr) sharedContextPrivate)->glCtx;
130 else
131 shareCtx = NULL;
132 rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
133 &functions, (void *) rmesa);
134 if (!rmesa->glCtx) {
135 FREE(rmesa);
136 return GL_FALSE;
137 }
138 driContextPriv->driverPrivate = rmesa;
139 ctx = rmesa->glCtx;
140
141 rmesa->driContext = driContextPriv;
142 rmesa->driScreen = sPriv;
143 rmesa->driDrawable = NULL;
144 rmesa->hHWContext = driContextPriv->hHWContext;
145 rmesa->driHwLock = &sPriv->pSAREA->lock;
146 rmesa->driFd = sPriv->fd;
147
148 r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private);
149
150 /* Parse configuration files */
151 driParseConfigFiles (&rmesa->optionCache, &r128scrn->optionCache,
152 r128scrn->driScreen->myNum, "r128");
153
154 rmesa->sarea = (drm_r128_sarea_t *)((char *)sPriv->pSAREA +
155 r128scrn->sarea_priv_offset);
156
157 rmesa->CurrentTexObj[0] = NULL;
158 rmesa->CurrentTexObj[1] = NULL;
159
160 (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
161 make_empty_list( & rmesa->swapped );
162
163 rmesa->nr_heaps = r128scrn->numTexHeaps;
164 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
165 rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
166 r128scrn->texSize[i],
167 12,
168 R128_NR_TEX_REGIONS,
169 (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
170 &rmesa->sarea->tex_age[i],
171 &rmesa->swapped,
172 sizeof( r128TexObj ),
173 (destroy_texture_object_t *) r128DestroyTexObj );
174
175 driSetTextureSwapCounterLocation( rmesa->texture_heaps[i],
176 & rmesa->c_textureSwaps );
177 }
178 rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
179 "texture_depth");
180 if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
181 rmesa->texture_depth = ( r128scrn->cpp == 4 ) ?
182 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
183
184
185 rmesa->RenderIndex = -1; /* Impossible value */
186 rmesa->vert_buf = NULL;
187 rmesa->num_verts = 0;
188 RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
189
190 /* Set the maximum texture size small enough that we can guarentee that
191 * all texture units can bind a maximal texture and have them both in
192 * texturable memory at once.
193 */
194
195 ctx->Const.MaxTextureUnits = 2;
196 ctx->Const.MaxTextureImageUnits = 2;
197 ctx->Const.MaxTextureCoordUnits = 2;
198
199 driCalculateMaxTextureLevels( rmesa->texture_heaps,
200 rmesa->nr_heaps,
201 & ctx->Const,
202 4,
203 10, /* max 2D texture size is 1024x1024 */
204 0, /* 3D textures unsupported. */
205 0, /* cube textures unsupported. */
206 0, /* texture rectangles unsupported. */
207 11,
208 GL_FALSE,
209 0 );
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 ctx->Const.MaxDrawBuffers = 1;
227
228 #if ENABLE_PERF_BOXES
229 rmesa->boxes = driQueryOptionb(&rmesa->optionCache, "performance_boxes");
230 #endif
231
232 /* Initialize the software rasterizer and helper modules.
233 */
234 _swrast_CreateContext( ctx );
235 _vbo_CreateContext( ctx );
236 _tnl_CreateContext( ctx );
237 _swsetup_CreateContext( ctx );
238
239 /* Install the customized pipeline:
240 */
241 /* _tnl_destroy_pipeline( ctx ); */
242 /* _tnl_install_pipeline( ctx, r128_pipeline ); */
243
244 /* Configure swrast and T&L to match hardware characteristics:
245 */
246 _swrast_allow_pixel_fog( ctx, GL_FALSE );
247 _swrast_allow_vertex_fog( ctx, GL_TRUE );
248 _tnl_allow_pixel_fog( ctx, GL_FALSE );
249 _tnl_allow_vertex_fog( ctx, GL_TRUE );
250
251 driInitExtensions( ctx, card_extensions, GL_TRUE );
252 if (sPriv->drm_version.minor >= 4)
253 _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
254
255 r128InitTriFuncs( ctx );
256 r128DDInitStateFuncs( ctx );
257 r128DDInitSpanFuncs( ctx );
258 r128DDInitState( rmesa );
259
260 driContextPriv->driverPrivate = (void *)rmesa;
261
262 #if DO_DEBUG
263 R128_DEBUG = driParseDebugString( getenv( "R128_DEBUG" ),
264 debug_control );
265 #endif
266
267 if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
268 fprintf(stderr, "disabling 3D acceleration\n");
269 FALLBACK(rmesa, R128_FALLBACK_DISABLE, 1);
270 }
271
272 return GL_TRUE;
273 }
274
275 /* Destroy the device specific context.
276 */
277 void r128DestroyContext( __DRIcontext *driContextPriv )
278 {
279 r128ContextPtr rmesa = (r128ContextPtr) driContextPriv->driverPrivate;
280
281 assert(rmesa); /* should never be null */
282 if ( rmesa ) {
283 GLboolean release_texture_heaps;
284
285
286 release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
287
288 _swsetup_DestroyContext( rmesa->glCtx );
289 _tnl_DestroyContext( rmesa->glCtx );
290 _vbo_DestroyContext( rmesa->glCtx );
291 _swrast_DestroyContext( rmesa->glCtx );
292
293 if ( release_texture_heaps ) {
294 /* This share group is about to go away, free our private
295 * texture object data.
296 */
297 int i;
298
299 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
300 driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
301 rmesa->texture_heaps[ i ] = NULL;
302 }
303
304 assert( is_empty_list( & rmesa->swapped ) );
305 }
306
307 /* free the Mesa context */
308 rmesa->glCtx->DriverCtx = NULL;
309 _mesa_destroy_context(rmesa->glCtx);
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( __DRIcontext *driContextPriv,
329 __DRIdrawable *driDrawPriv,
330 __DRIdrawable *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 if (driDrawPriv->swap_interval == (unsigned)-1) {
343 driDrawPriv->vblFlags = (newR128Ctx->r128Screen->irq != 0)
344 ? driGetDefaultVBlankFlags(&newR128Ctx->optionCache)
345 : VBLANK_FLAG_NO_IRQ;
346
347 driDrawableInitVBlank( driDrawPriv );
348 }
349 newR128Ctx->driDrawable = driDrawPriv;
350
351 _mesa_make_current( newR128Ctx->glCtx,
352 (GLframebuffer *) driDrawPriv->driverPrivate,
353 (GLframebuffer *) driReadPriv->driverPrivate );
354
355 newR128Ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP;
356 } else {
357 _mesa_make_current( NULL, NULL, NULL );
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( __DRIcontext *driContextPriv )
368 {
369 return GL_TRUE;
370 }