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