Remove leftover __DRI{screen,drawable,context}Private references
[mesa.git] / src / mesa / drivers / dri / i810 / i810context.c
1 /**************************************************************************
2
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 All Rights Reserved.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sub license, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial portions
16 of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 *
32 */
33
34
35 #include "main/glheader.h"
36 #include "main/context.h"
37 #include "main/matrix.h"
38 #include "main/simple_list.h"
39 #include "main/extensions.h"
40 #include "main/framebuffer.h"
41 #include "main/imports.h"
42 #include "main/points.h"
43
44 #include "swrast/swrast.h"
45 #include "swrast_setup/swrast_setup.h"
46 #include "tnl/tnl.h"
47 #include "vbo/vbo.h"
48
49 #include "tnl/t_pipeline.h"
50
51 #include "drivers/common/driverfuncs.h"
52
53 #include "i810screen.h"
54 #include "i810_dri.h"
55
56 #include "i810state.h"
57 #include "i810tex.h"
58 #include "i810span.h"
59 #include "i810tris.h"
60 #include "i810vb.h"
61 #include "i810ioctl.h"
62
63 #include "drirenderbuffer.h"
64 #include "utils.h"
65
66 #ifndef I810_DEBUG
67 int I810_DEBUG = (0);
68 #endif
69
70 PUBLIC const char __driConfigOptions[] = { 0 };
71 const GLuint __driNConfigOptions = 0;
72
73 #define DRIVER_DATE "20050821"
74
75 static const GLubyte *i810GetString( GLcontext *ctx, GLenum name )
76 {
77 static char buffer[128];
78
79 switch (name) {
80 case GL_VENDOR:
81 return (GLubyte *)"Keith Whitwell";
82 case GL_RENDERER: {
83 i810ContextPtr imesa = I810_CONTEXT(ctx);
84 const char * chipset;
85
86 switch (imesa->i810Screen->deviceID) {
87 case PCI_CHIP_I810: chipset = "i810"; break;
88 case PCI_CHIP_I810_DC100: chipset = "i810 DC-100"; break;
89 case PCI_CHIP_I810_E: chipset = "i810E"; break;
90 case PCI_CHIP_I815: chipset = "i815"; break;
91 default: chipset = "Unknown i810-class Chipset"; break;
92 }
93
94 (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 );
95 return (GLubyte *) buffer;
96 }
97 default:
98 return 0;
99 }
100 }
101
102 static void i810BufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
103 {
104 GET_CURRENT_CONTEXT(ctx);
105 i810ContextPtr imesa = I810_CONTEXT(ctx);
106
107 /* Need to lock to make sure the driDrawable is uptodate. This
108 * information is used to resize Mesa's software buffers, so it has
109 * to be correct.
110 */
111 LOCK_HARDWARE(imesa);
112 *width = imesa->driDrawable->w;
113 *height = imesa->driDrawable->h;
114 UNLOCK_HARDWARE(imesa);
115 }
116
117 /* Extension strings exported by the i810 driver.
118 */
119 static const struct dri_extension card_extensions[] =
120 {
121 { "GL_ARB_multitexture", NULL },
122 { "GL_ARB_texture_env_add", NULL },
123 { "GL_ARB_texture_env_combine", NULL },
124 { "GL_ARB_texture_env_crossbar", NULL },
125 { "GL_ARB_texture_mirrored_repeat", NULL },
126 { "GL_EXT_stencil_wrap", NULL },
127 { "GL_EXT_texture_edge_clamp", NULL },
128 { "GL_EXT_texture_env_combine", NULL },
129 { "GL_EXT_texture_lod_bias", NULL },
130 { "GL_EXT_texture_rectangle", NULL },
131 { "GL_MESA_ycbcr_texture", NULL },
132 { "GL_NV_blend_square", NULL },
133 { "GL_SGIS_generate_mipmap", NULL },
134 { NULL, NULL }
135 };
136
137 extern const struct tnl_pipeline_stage _i810_render_stage;
138
139 static const struct tnl_pipeline_stage *i810_pipeline[] = {
140 &_tnl_vertex_transform_stage,
141 &_tnl_normal_transform_stage,
142 &_tnl_lighting_stage,
143 &_tnl_fog_coordinate_stage,
144 &_tnl_texgen_stage,
145 &_tnl_texture_transform_stage,
146 /* REMOVE: point attenuation stage */
147 #if 1
148 &_i810_render_stage, /* ADD: unclipped rastersetup-to-dma */
149 #endif
150 &_tnl_render_stage,
151 0,
152 };
153
154 static const struct dri_debug_control debug_control[] =
155 {
156 { "fall", DEBUG_FALLBACKS },
157 { "tex", DEBUG_TEXTURE },
158 { "ioctl", DEBUG_IOCTL },
159 { "prim", DEBUG_PRIMS },
160 { "vert", DEBUG_VERTS },
161 { "state", DEBUG_STATE },
162 { "verb", DEBUG_VERBOSE },
163 { "dri", DEBUG_DRI },
164 { "dma", DEBUG_DMA },
165 { "san", DEBUG_SANITY },
166 { "sync", DEBUG_SYNC },
167 { "sleep", DEBUG_SLEEP },
168 { NULL, 0 }
169 };
170
171 GLboolean
172 i810CreateContext( const __GLcontextModes *mesaVis,
173 __DRIcontext *driContextPriv,
174 void *sharedContextPrivate )
175 {
176 GLcontext *ctx, *shareCtx;
177 i810ContextPtr imesa;
178 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
179 i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
180 I810SAREAPtr saPriv = (I810SAREAPtr)
181 (((GLubyte *)sPriv->pSAREA) + i810Screen->sarea_priv_offset);
182 struct dd_function_table functions;
183
184 /* Allocate i810 context */
185 imesa = (i810ContextPtr) CALLOC_STRUCT(i810_context_t);
186 if (!imesa) {
187 return GL_FALSE;
188 }
189
190 driContextPriv->driverPrivate = imesa;
191
192 imesa->i810Screen = i810Screen;
193 imesa->driScreen = sPriv;
194 imesa->sarea = saPriv;
195 imesa->glBuffer = NULL;
196
197 /* Init default driver functions then plug in our I810-specific functions
198 * (the texture functions are especially important)
199 */
200 _mesa_init_driver_functions( &functions );
201 i810InitIoctlFuncs( &functions );
202 i810InitTextureFuncs( &functions );
203
204
205 /* Allocate the Mesa context */
206 if (sharedContextPrivate)
207 shareCtx = ((i810ContextPtr) sharedContextPrivate)->glCtx;
208 else
209 shareCtx = NULL;
210 imesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
211 &functions, (void*) imesa);
212 if (!imesa->glCtx) {
213 FREE(imesa);
214 return GL_FALSE;
215 }
216
217 (void) memset( imesa->texture_heaps, 0, sizeof( imesa->texture_heaps ) );
218 make_empty_list( & imesa->swapped );
219
220 imesa->nr_heaps = 1;
221 imesa->texture_heaps[0] = driCreateTextureHeap( 0, imesa,
222 i810Screen->textureSize,
223 12,
224 I810_NR_TEX_REGIONS,
225 imesa->sarea->texList,
226 (unsigned *) & imesa->sarea->texAge, /* XXX we shouldn't cast! */
227 & imesa->swapped,
228 sizeof( struct i810_texture_object_t ),
229 (destroy_texture_object_t *) i810DestroyTexObj );
230
231
232
233 /* Set the maximum texture size small enough that we can guarentee
234 * that both texture units can bind a maximal texture and have them
235 * in memory at once.
236 */
237
238
239
240 ctx = imesa->glCtx;
241 ctx->Const.MaxTextureUnits = 2;
242 ctx->Const.MaxTextureImageUnits = 2;
243 ctx->Const.MaxTextureCoordUnits = 2;
244
245
246 /* FIXME: driCalcualteMaxTextureLevels assumes that mipmaps are tightly
247 * FIXME: packed, but they're not in Intel graphics hardware.
248 */
249 driCalculateMaxTextureLevels( imesa->texture_heaps,
250 imesa->nr_heaps,
251 & ctx->Const,
252 4,
253 11, /* max 2D texture size is 2048x2048 */
254 0, /* 3D textures unsupported */
255 0, /* cube textures unsupported. */
256 0, /* texture rectangles unsupported. */
257 12,
258 GL_FALSE,
259 0 );
260
261 ctx->Const.MinLineWidth = 1.0;
262 ctx->Const.MinLineWidthAA = 1.0;
263 ctx->Const.MaxLineWidth = 3.0;
264 ctx->Const.MaxLineWidthAA = 3.0;
265 ctx->Const.LineWidthGranularity = 1.0;
266
267 ctx->Const.MinPointSize = 1.0;
268 ctx->Const.MinPointSizeAA = 1.0;
269 ctx->Const.MaxPointSize = 3.0;
270 ctx->Const.MaxPointSizeAA = 3.0;
271 ctx->Const.PointSizeGranularity = 1.0;
272
273 /* reinitialize the context point state.
274 * It depend on constants in __GLcontextRec::Const
275 */
276 _mesa_init_point(ctx);
277
278 ctx->Driver.GetBufferSize = i810BufferSize;
279 ctx->Driver.GetString = i810GetString;
280
281 /* Who owns who?
282 */
283 ctx->DriverCtx = (void *) imesa;
284 imesa->glCtx = ctx;
285
286 /* Initialize the software rasterizer and helper modules.
287 */
288 _swrast_CreateContext( ctx );
289 _vbo_CreateContext( ctx );
290 _tnl_CreateContext( ctx );
291 _swsetup_CreateContext( ctx );
292
293 /* Install the customized pipeline:
294 */
295 _tnl_destroy_pipeline( ctx );
296 _tnl_install_pipeline( ctx, i810_pipeline );
297
298 /* Configure swrast and T&L to match hardware characteristics:
299 */
300 _swrast_allow_pixel_fog( ctx, GL_FALSE );
301 _swrast_allow_vertex_fog( ctx, GL_TRUE );
302 _tnl_allow_pixel_fog( ctx, GL_FALSE );
303 _tnl_allow_vertex_fog( ctx, GL_TRUE );
304
305 /* Dri stuff
306 */
307 imesa->hHWContext = driContextPriv->hHWContext;
308 imesa->driFd = sPriv->fd;
309 imesa->driHwLock = &sPriv->pSAREA->lock;
310
311 imesa->stipple_in_hw = 1;
312 imesa->RenderIndex = ~0;
313 imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
314 imesa->upload_cliprects = GL_TRUE;
315
316 imesa->CurrentTexObj[0] = 0;
317 imesa->CurrentTexObj[1] = 0;
318
319 _math_matrix_ctr( &imesa->ViewportMatrix );
320
321 driInitExtensions( ctx, card_extensions, GL_TRUE );
322 /* XXX these should really go right after _mesa_init_driver_functions() */
323 i810InitStateFuncs( ctx );
324 i810InitTriFuncs( ctx );
325 i810InitSpanFuncs( ctx );
326 i810InitVB( ctx );
327 i810InitState( ctx );
328
329 #if DO_DEBUG
330 I810_DEBUG = driParseDebugString( getenv( "I810_DEBUG" ),
331 debug_control );
332 I810_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
333 debug_control );
334 #endif
335
336 return GL_TRUE;
337 }
338
339 void
340 i810DestroyContext(__DRIcontext *driContextPriv)
341 {
342 i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
343
344 assert(imesa); /* should never be null */
345 if (imesa) {
346 GLboolean release_texture_heaps;
347
348
349 release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1);
350 _swsetup_DestroyContext( imesa->glCtx );
351 _tnl_DestroyContext( imesa->glCtx );
352 _vbo_DestroyContext( imesa->glCtx );
353 _swrast_DestroyContext( imesa->glCtx );
354
355 i810FreeVB( imesa->glCtx );
356
357 /* free the Mesa context */
358 imesa->glCtx->DriverCtx = NULL;
359 _mesa_destroy_context(imesa->glCtx);
360 if ( release_texture_heaps ) {
361 /* This share group is about to go away, free our private
362 * texture object data.
363 */
364 unsigned int i;
365
366 for ( i = 0 ; i < imesa->nr_heaps ; i++ ) {
367 driDestroyTextureHeap( imesa->texture_heaps[ i ] );
368 imesa->texture_heaps[ i ] = NULL;
369 }
370
371 assert( is_empty_list( & imesa->swapped ) );
372 }
373
374 FREE(imesa);
375 }
376 }
377
378
379 void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
380 {
381 __DRIdrawable *dPriv = imesa->driDrawable;
382
383 imesa->numClipRects = dPriv->numClipRects;
384 imesa->pClipRects = dPriv->pClipRects;
385 imesa->drawX = dPriv->x;
386 imesa->drawY = dPriv->y;
387
388 i810EmitDrawingRectangle( imesa );
389 imesa->upload_cliprects = GL_TRUE;
390 }
391
392
393 void i810XMesaSetBackClipRects( i810ContextPtr imesa )
394 {
395 __DRIdrawable *dPriv = imesa->driDrawable;
396
397 if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0)
398 {
399 imesa->numClipRects = dPriv->numClipRects;
400 imesa->pClipRects = dPriv->pClipRects;
401 imesa->drawX = dPriv->x;
402 imesa->drawY = dPriv->y;
403 } else {
404 imesa->numClipRects = dPriv->numBackClipRects;
405 imesa->pClipRects = dPriv->pBackClipRects;
406 imesa->drawX = dPriv->backX;
407 imesa->drawY = dPriv->backY;
408 }
409
410 i810EmitDrawingRectangle( imesa );
411 imesa->upload_cliprects = GL_TRUE;
412 }
413
414
415 static void i810XMesaWindowMoved( i810ContextPtr imesa )
416 {
417 /* Determine current color drawing buffer */
418 switch (imesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0]) {
419 case BUFFER_FRONT_LEFT:
420 i810XMesaSetFrontClipRects( imesa );
421 break;
422 case BUFFER_BACK_LEFT:
423 i810XMesaSetBackClipRects( imesa );
424 break;
425 default:
426 /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
427 i810XMesaSetFrontClipRects( imesa );
428 }
429 }
430
431
432 GLboolean
433 i810UnbindContext(__DRIcontext *driContextPriv)
434 {
435 i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
436 if (imesa) {
437 imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
438 if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0;
439 if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1;
440 }
441
442 return GL_TRUE;
443 }
444
445
446 GLboolean
447 i810MakeCurrent(__DRIcontext *driContextPriv,
448 __DRIdrawable *driDrawPriv,
449 __DRIdrawable *driReadPriv)
450 {
451 if (driContextPriv) {
452 i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
453
454 /* Shouldn't the readbuffer be stored also?
455 */
456 imesa->driDrawable = driDrawPriv;
457
458 _mesa_make_current(imesa->glCtx,
459 (GLframebuffer *) driDrawPriv->driverPrivate,
460 (GLframebuffer *) driReadPriv->driverPrivate);
461
462 /* Are these necessary?
463 */
464 i810XMesaWindowMoved( imesa );
465 }
466 else {
467 _mesa_make_current(NULL, NULL, NULL);
468 }
469
470 return GL_TRUE;
471 }
472
473 static void
474 i810UpdatePageFlipping( i810ContextPtr imesa )
475 {
476 GLcontext *ctx = imesa->glCtx;
477 int front = 0;
478
479 /* Determine current color drawing buffer */
480 switch (ctx->DrawBuffer->_ColorDrawBufferIndexes[0]) {
481 case BUFFER_FRONT_LEFT:
482 front = 1;
483 break;
484 case BUFFER_BACK_LEFT:
485 front = 0;
486 break;
487 default:
488 return;
489 }
490
491 if ( imesa->sarea->pf_current_page == 1 )
492 front ^= 1;
493
494 driFlipRenderbuffers(ctx->WinSysDrawBuffer, front);
495
496 if (front) {
497 imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->fbOffset | imesa->i810Screen->backPitchBits;
498 } else {
499 imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->backOffset | imesa->i810Screen->backPitchBits;
500 }
501
502 imesa->dirty |= I810_UPLOAD_BUFFERS;
503 }
504
505 void i810GetLock( i810ContextPtr imesa, GLuint flags )
506 {
507 __DRIdrawable *dPriv = imesa->driDrawable;
508 __DRIscreen *sPriv = imesa->driScreen;
509 I810SAREAPtr sarea = imesa->sarea;
510 int me = imesa->hHWContext;
511 unsigned i;
512
513 drmGetLock(imesa->driFd, imesa->hHWContext, flags);
514
515 /* If the window moved, may need to set a new cliprect now.
516 *
517 * NOTE: This releases and regains the hw lock, so all state
518 * checking must be done *after* this call:
519 */
520 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
521
522
523 /* If we lost context, need to dump all registers to hardware.
524 * Note that we don't care about 2d contexts, even if they perform
525 * accelerated commands, so the DRI locking in the X server is even
526 * more broken than usual.
527 */
528 if (sarea->ctxOwner != me) {
529 driUpdateFramebufferSize(imesa->glCtx, dPriv);
530 imesa->upload_cliprects = GL_TRUE;
531 imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS;
532 if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0;
533 if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1;
534 sarea->ctxOwner = me;
535 }
536
537 /* Shared texture managment - if another client has played with
538 * texture space, figure out which if any of our textures have been
539 * ejected, and update our global LRU.
540 */
541 for ( i = 0 ; i < imesa->nr_heaps ; i++ ) {
542 DRI_AGE_TEXTURES( imesa->texture_heaps[ i ] );
543 }
544
545 if (imesa->lastStamp != dPriv->lastStamp) {
546 i810UpdatePageFlipping( imesa );
547 i810XMesaWindowMoved( imesa );
548 imesa->lastStamp = dPriv->lastStamp;
549 }
550 }
551
552
553 void
554 i810SwapBuffers( __DRIdrawable *dPriv )
555 {
556 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
557 i810ContextPtr imesa;
558 GLcontext *ctx;
559 imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;
560 ctx = imesa->glCtx;
561 if (ctx->Visual.doubleBufferMode) {
562 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
563 if ( imesa->sarea->pf_active ) {
564 i810PageFlip( dPriv );
565 } else {
566 i810CopyBuffer( dPriv );
567 }
568 }
569 }
570 else {
571 /* XXX this shouldn't be an error but we can't handle it for now */
572 _mesa_problem(NULL, "i810SwapBuffers: drawable has no context!\n");
573 }
574 }
575