Remove leftover __DRI{screen,drawable,context}Private references
[mesa.git] / src / mesa / drivers / dri / unichrome / via_context.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file via_context.c
27 *
28 * \author John Sheng (presumably of either VIA Technologies or S3 Graphics)
29 * \author Others at VIA Technologies?
30 * \author Others at S3 Graphics?
31 */
32
33 #include "main/glheader.h"
34 #include "main/context.h"
35 #include "main/formats.h"
36 #include "main/matrix.h"
37 #include "main/state.h"
38 #include "main/simple_list.h"
39 #include "main/extensions.h"
40 #include "main/framebuffer.h"
41 #include "main/renderbuffer.h"
42
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "tnl/tnl.h"
46 #include "vbo/vbo.h"
47
48 #include "tnl/t_pipeline.h"
49
50 #include "drivers/common/driverfuncs.h"
51
52 #include "via_screen.h"
53 #include "via_dri.h"
54
55 #include "via_state.h"
56 #include "via_tex.h"
57 #include "via_span.h"
58 #include "via_tris.h"
59 #include "via_ioctl.h"
60 #include "via_fb.h"
61
62 #include <stdio.h>
63 #include "main/macros.h"
64 #include "drirenderbuffer.h"
65
66 #define need_GL_ARB_point_parameters
67 #define need_GL_EXT_fog_coord
68 #define need_GL_EXT_secondary_color
69 #include "main/remap_helper.h"
70
71 #define DRIVER_DATE "20060710"
72
73 #include "vblank.h"
74 #include "utils.h"
75
76 GLuint VIA_DEBUG = 0;
77
78 /**
79 * Return various strings for \c glGetString.
80 *
81 * \sa glGetString
82 */
83 static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
84 {
85 static char buffer[128];
86 unsigned offset;
87
88
89 switch (name) {
90 case GL_VENDOR:
91 return (GLubyte *)"VIA Technology";
92
93 case GL_RENDERER: {
94 static const char * const chipset_names[] = {
95 "UniChrome",
96 "CastleRock (CLE266)",
97 "UniChrome (KM400)",
98 "UniChrome (K8M800)",
99 "UniChrome (PM8x0/CN400)",
100 };
101 struct via_context *vmesa = VIA_CONTEXT(ctx);
102 unsigned id = vmesa->viaScreen->deviceID;
103
104 offset = driGetRendererString( buffer,
105 chipset_names[(id > VIA_PM800) ? 0 : id],
106 DRIVER_DATE, 0 );
107 return (GLubyte *)buffer;
108 }
109
110 default:
111 return NULL;
112 }
113 }
114
115
116 /**
117 * Calculate a width that satisfies the hardware's alignment requirements.
118 * On the Unichrome hardware, each scanline must be aligned to a multiple of
119 * 16 pixels.
120 *
121 * \param width Minimum buffer width, in pixels.
122 *
123 * \returns A pixel width that meets the alignment requirements.
124 */
125 static INLINE unsigned
126 buffer_align( unsigned width )
127 {
128 return (width + 0x0f) & ~0x0f;
129 }
130
131
132 static void
133 viaDeleteRenderbuffer(struct gl_renderbuffer *rb)
134 {
135 /* Don't free() since we're contained in via_context struct. */
136 }
137
138 static GLboolean
139 viaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
140 GLenum internalFormat, GLuint width, GLuint height)
141 {
142 rb->Width = width;
143 rb->Height = height;
144 rb->InternalFormat = internalFormat;
145 return GL_TRUE;
146 }
147
148
149 static void
150 viaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format,
151 __DRIdrawable *dPriv)
152 {
153 const GLuint name = 0;
154 struct gl_renderbuffer *rb = & vrb->Base;
155
156 vrb->dPriv = dPriv;
157 _mesa_init_renderbuffer(rb, name);
158
159 /* Make sure we're using a null-valued GetPointer routine */
160 assert(rb->GetPointer(NULL, rb, 0, 0) == NULL);
161
162 rb->InternalFormat = format;
163
164 if (format == GL_RGBA) {
165 /* Color */
166 rb->_BaseFormat = GL_RGBA;
167 rb->Format = MESA_FORMAT_ARGB8888;
168 rb->DataType = GL_UNSIGNED_BYTE;
169 }
170 else if (format == GL_DEPTH_COMPONENT16) {
171 /* Depth */
172 rb->_BaseFormat = GL_DEPTH_COMPONENT;
173 /* we always Get/Put 32-bit Z values */
174 rb->Format = MESA_FORMAT_Z16;
175 rb->DataType = GL_UNSIGNED_INT;
176 }
177 else if (format == GL_DEPTH_COMPONENT24) {
178 /* Depth */
179 rb->_BaseFormat = GL_DEPTH_COMPONENT;
180 /* we always Get/Put 32-bit Z values */
181 rb->Format = MESA_FORMAT_Z32;
182 rb->DataType = GL_UNSIGNED_INT;
183 }
184 else {
185 /* Stencil */
186 ASSERT(format == GL_STENCIL_INDEX8_EXT);
187 rb->_BaseFormat = GL_STENCIL_INDEX;
188 rb->Format = MESA_FORMAT_S8;
189 rb->DataType = GL_UNSIGNED_BYTE;
190 }
191
192 rb->Delete = viaDeleteRenderbuffer;
193 rb->AllocStorage = viaRenderbufferStorage;
194 }
195
196
197 /**
198 * Calculate the framebuffer parameters for all buffers (front, back, depth,
199 * and stencil) associated with the specified context.
200 *
201 * \warning
202 * This function also calls \c AllocateBuffer to actually allocate the
203 * buffers.
204 *
205 * \sa AllocateBuffer
206 */
207 static GLboolean
208 calculate_buffer_parameters(struct via_context *vmesa,
209 struct gl_framebuffer *fb,
210 __DRIdrawable *dPriv)
211 {
212 const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
213 const unsigned extra = 32;
214 unsigned w;
215 unsigned h;
216
217 /* Normally, the renderbuffer would be added to the framebuffer just once
218 * when the framebuffer was created. The VIA driver is a bit funny
219 * though in that the front/back/depth renderbuffers are in the per-context
220 * state!
221 * That should be fixed someday.
222 */
223
224 if (!vmesa->front.Base.InternalFormat) {
225 /* do one-time init for the renderbuffers */
226 viaInitRenderbuffer(&vmesa->front, GL_RGBA, dPriv);
227 viaSetSpanFunctions(&vmesa->front, &fb->Visual);
228 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base);
229
230 if (fb->Visual.doubleBufferMode) {
231 viaInitRenderbuffer(&vmesa->back, GL_RGBA, dPriv);
232 viaSetSpanFunctions(&vmesa->back, &fb->Visual);
233 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base);
234 }
235
236 if (vmesa->glCtx->Visual.depthBits > 0) {
237 viaInitRenderbuffer(&vmesa->depth,
238 (vmesa->glCtx->Visual.depthBits == 16
239 ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24),
240 dPriv);
241 viaSetSpanFunctions(&vmesa->depth, &fb->Visual);
242 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base);
243 }
244
245 if (vmesa->glCtx->Visual.stencilBits > 0) {
246 viaInitRenderbuffer(&vmesa->stencil, GL_STENCIL_INDEX8_EXT,
247 dPriv);
248 viaSetSpanFunctions(&vmesa->stencil, &fb->Visual);
249 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base);
250 }
251 }
252
253 assert(vmesa->front.Base.InternalFormat);
254 assert(vmesa->front.Base.AllocStorage);
255 if (fb->Visual.doubleBufferMode) {
256 assert(vmesa->back.Base.AllocStorage);
257 }
258 if (fb->Visual.depthBits) {
259 assert(vmesa->depth.Base.AllocStorage);
260 }
261
262
263 /* Allocate front-buffer */
264 if (vmesa->drawType == GLX_PBUFFER_BIT) {
265 w = vmesa->driDrawable->w;
266 h = vmesa->driDrawable->h;
267
268 vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
269 vmesa->front.pitch = buffer_align( w ) << shift; /* bytes, not pixels */
270 vmesa->front.size = vmesa->front.pitch * h;
271
272 if (vmesa->front.map)
273 via_free_draw_buffer(vmesa, &vmesa->front);
274 if (!via_alloc_draw_buffer(vmesa, &vmesa->front))
275 return GL_FALSE;
276
277 } else {
278 w = vmesa->viaScreen->width;
279 h = vmesa->viaScreen->height;
280
281 vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
282 vmesa->front.pitch = buffer_align( w ) << shift; /* bytes, not pixels */
283 vmesa->front.size = vmesa->front.pitch * h;
284 if (getenv("ALTERNATE_SCREEN"))
285 vmesa->front.offset = vmesa->front.size;
286 else
287 vmesa->front.offset = 0;
288 vmesa->front.map = (char *) vmesa->driScreen->pFB;
289 }
290
291
292 /* Allocate back-buffer */
293 if (vmesa->hasBack) {
294 vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel;
295 vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift);
296 vmesa->back.pitch += extra;
297 vmesa->back.pitch = MIN2(vmesa->back.pitch, vmesa->front.pitch);
298 vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
299 if (vmesa->back.map)
300 via_free_draw_buffer(vmesa, &vmesa->back);
301 if (!via_alloc_draw_buffer(vmesa, &vmesa->back))
302 return GL_FALSE;
303 }
304 else {
305 if (vmesa->back.map)
306 via_free_draw_buffer(vmesa, &vmesa->back);
307 (void) memset( &vmesa->back, 0, sizeof( vmesa->back ) );
308 }
309
310
311 /* Allocate depth-buffer */
312 if ( vmesa->hasStencil || vmesa->hasDepth ) {
313 vmesa->depth.bpp = vmesa->depthBits;
314 if (vmesa->depth.bpp == 24)
315 vmesa->depth.bpp = 32;
316
317 vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) *
318 (vmesa->depth.bpp/8)) + extra;
319 vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
320
321 if (vmesa->depth.map)
322 via_free_draw_buffer(vmesa, &vmesa->depth);
323 if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) {
324 return GL_FALSE;
325 }
326 }
327 else {
328 if (vmesa->depth.map)
329 via_free_draw_buffer(vmesa, &vmesa->depth);
330 (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
331 }
332
333 /* stencil buffer is same as depth buffer */
334 vmesa->stencil.handle = vmesa->depth.handle;
335 vmesa->stencil.size = vmesa->depth.size;
336 vmesa->stencil.offset = vmesa->depth.offset;
337 vmesa->stencil.index = vmesa->depth.index;
338 vmesa->stencil.pitch = vmesa->depth.pitch;
339 vmesa->stencil.bpp = vmesa->depth.bpp;
340 vmesa->stencil.map = vmesa->depth.map;
341 vmesa->stencil.orig = vmesa->depth.orig;
342 vmesa->stencil.origMap = vmesa->depth.origMap;
343
344 if( vmesa->viaScreen->width == vmesa->driDrawable->w &&
345 vmesa->viaScreen->height == vmesa->driDrawable->h ) {
346 vmesa->doPageFlip = vmesa->allowPageFlip;
347 if (vmesa->hasBack) {
348 assert(vmesa->back.pitch == vmesa->front.pitch);
349 }
350 }
351 else
352 vmesa->doPageFlip = GL_FALSE;
353
354 return GL_TRUE;
355 }
356
357
358 void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
359 GLuint width, GLuint height)
360 {
361 struct via_context *vmesa = VIA_CONTEXT(ctx);
362
363 calculate_buffer_parameters(vmesa, drawbuffer, vmesa->driDrawable);
364
365 _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
366 }
367
368 /* Extension strings exported by the Unichrome driver.
369 */
370 static const struct dri_extension card_extensions[] =
371 {
372 { "GL_ARB_multitexture", NULL },
373 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
374 { "GL_ARB_texture_env_add", NULL },
375 { "GL_ARB_texture_env_combine", NULL },
376 /* { "GL_ARB_texture_env_dot3", NULL }, */
377 { "GL_ARB_texture_mirrored_repeat", NULL },
378 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
379 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
380 { "GL_EXT_stencil_wrap", NULL },
381 { "GL_EXT_texture_env_combine", NULL },
382 /* { "GL_EXT_texture_env_dot3", NULL }, */
383 { "GL_EXT_texture_lod_bias", NULL },
384 { "GL_NV_blend_square", NULL },
385 { NULL, NULL }
386 };
387
388 extern const struct tnl_pipeline_stage _via_fastrender_stage;
389 extern const struct tnl_pipeline_stage _via_render_stage;
390
391 static const struct tnl_pipeline_stage *via_pipeline[] = {
392 &_tnl_vertex_transform_stage,
393 &_tnl_normal_transform_stage,
394 &_tnl_lighting_stage,
395 &_tnl_fog_coordinate_stage,
396 &_tnl_texgen_stage,
397 &_tnl_texture_transform_stage,
398 /* REMOVE: point attenuation stage */
399 #if 1
400 &_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */
401 #endif
402 &_tnl_render_stage,
403 0,
404 };
405
406
407 static const struct dri_debug_control debug_control[] =
408 {
409 { "fall", DEBUG_FALLBACKS },
410 { "tex", DEBUG_TEXTURE },
411 { "ioctl", DEBUG_IOCTL },
412 { "prim", DEBUG_PRIMS },
413 { "vert", DEBUG_VERTS },
414 { "state", DEBUG_STATE },
415 { "verb", DEBUG_VERBOSE },
416 { "dri", DEBUG_DRI },
417 { "dma", DEBUG_DMA },
418 { "san", DEBUG_SANITY },
419 { "sync", DEBUG_SYNC },
420 { "sleep", DEBUG_SLEEP },
421 { "pix", DEBUG_PIXEL },
422 { "2d", DEBUG_2D },
423 { NULL, 0 }
424 };
425
426
427 static GLboolean
428 AllocateDmaBuffer(struct via_context *vmesa)
429 {
430 if (vmesa->dma)
431 via_free_dma_buffer(vmesa);
432
433 if (!via_alloc_dma_buffer(vmesa))
434 return GL_FALSE;
435
436 vmesa->dmaLow = 0;
437 vmesa->dmaCliprectAddr = ~0;
438 return GL_TRUE;
439 }
440
441 static void
442 FreeBuffer(struct via_context *vmesa)
443 {
444 if (vmesa->front.map && vmesa->drawType == GLX_PBUFFER_BIT)
445 via_free_draw_buffer(vmesa, &vmesa->front);
446
447 if (vmesa->back.map)
448 via_free_draw_buffer(vmesa, &vmesa->back);
449
450 if (vmesa->depth.map)
451 via_free_draw_buffer(vmesa, &vmesa->depth);
452
453 if (vmesa->breadcrumb.map)
454 via_free_draw_buffer(vmesa, &vmesa->breadcrumb);
455
456 if (vmesa->dma)
457 via_free_dma_buffer(vmesa);
458 }
459
460
461 GLboolean
462 viaCreateContext(const __GLcontextModes *visual,
463 __DRIcontext *driContextPriv,
464 void *sharedContextPrivate)
465 {
466 GLcontext *ctx, *shareCtx;
467 struct via_context *vmesa;
468 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
469 viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
470 drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
471 (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
472 struct dd_function_table functions;
473
474 /* Allocate via context */
475 vmesa = (struct via_context *) CALLOC_STRUCT(via_context);
476 if (!vmesa) {
477 return GL_FALSE;
478 }
479
480 /* Parse configuration files.
481 */
482 driParseConfigFiles (&vmesa->optionCache, &viaScreen->optionCache,
483 sPriv->myNum, "unichrome");
484
485 /* pick back buffer */
486 vmesa->hasBack = visual->doubleBufferMode;
487
488 switch(visual->depthBits) {
489 case 0:
490 vmesa->hasDepth = GL_FALSE;
491 vmesa->depthBits = 0;
492 vmesa->depth_max = 1.0;
493 break;
494 case 16:
495 vmesa->hasDepth = GL_TRUE;
496 vmesa->depthBits = visual->depthBits;
497 vmesa->have_hw_stencil = GL_FALSE;
498 vmesa->depth_max = (GLfloat)0xffff;
499 vmesa->depth_clear_mask = 0xf << 28;
500 vmesa->ClearDepth = 0xffff;
501 vmesa->polygon_offset_scale = 1.0 / vmesa->depth_max;
502 break;
503 case 24:
504 vmesa->hasDepth = GL_TRUE;
505 vmesa->depthBits = visual->depthBits;
506 vmesa->depth_max = (GLfloat) 0xffffff;
507 vmesa->depth_clear_mask = 0xe << 28;
508 vmesa->ClearDepth = 0xffffff00;
509
510 assert(visual->haveStencilBuffer);
511 assert(visual->stencilBits == 8);
512
513 vmesa->have_hw_stencil = GL_TRUE;
514 vmesa->stencilBits = visual->stencilBits;
515 vmesa->stencil_clear_mask = 0x1 << 28;
516 vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
517 break;
518 case 32:
519 vmesa->hasDepth = GL_TRUE;
520 vmesa->depthBits = visual->depthBits;
521 assert(!visual->haveStencilBuffer);
522 vmesa->have_hw_stencil = GL_FALSE;
523 vmesa->depth_max = (GLfloat)0xffffffff;
524 vmesa->depth_clear_mask = 0xf << 28;
525 vmesa->ClearDepth = 0xffffffff;
526 vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
527 break;
528 default:
529 assert(0);
530 break;
531 }
532
533 make_empty_list(&vmesa->freed_tex_buffers);
534 make_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]);
535 make_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]);
536 make_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]);
537
538 _mesa_init_driver_functions(&functions);
539 viaInitTextureFuncs(&functions);
540
541 /* Allocate the Mesa context */
542 if (sharedContextPrivate)
543 shareCtx = ((struct via_context *) sharedContextPrivate)->glCtx;
544 else
545 shareCtx = NULL;
546
547 vmesa->glCtx = _mesa_create_context(visual, shareCtx, &functions,
548 (void*) vmesa);
549
550 vmesa->shareCtx = shareCtx;
551
552 if (!vmesa->glCtx) {
553 FREE(vmesa);
554 return GL_FALSE;
555 }
556 driContextPriv->driverPrivate = vmesa;
557
558 ctx = vmesa->glCtx;
559
560 if (driQueryOptionb(&vmesa->optionCache, "excess_mipmap"))
561 ctx->Const.MaxTextureLevels = 11;
562 else
563 ctx->Const.MaxTextureLevels = 10;
564
565 ctx->Const.MaxTextureUnits = 2;
566 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
567 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
568
569 ctx->Const.MinLineWidth = 1.0;
570 ctx->Const.MinLineWidthAA = 1.0;
571 ctx->Const.MaxLineWidth = 1.0;
572 ctx->Const.MaxLineWidthAA = 1.0;
573 ctx->Const.LineWidthGranularity = 1.0;
574
575 ctx->Const.MinPointSize = 1.0;
576 ctx->Const.MinPointSizeAA = 1.0;
577 ctx->Const.MaxPointSize = 1.0;
578 ctx->Const.MaxPointSizeAA = 1.0;
579 ctx->Const.PointSizeGranularity = 1.0;
580
581 ctx->Const.MaxDrawBuffers = 1;
582
583 ctx->Driver.GetString = viaGetString;
584
585 ctx->DriverCtx = (void *)vmesa;
586 vmesa->glCtx = ctx;
587
588 /* Initialize the software rasterizer and helper modules.
589 */
590 _swrast_CreateContext(ctx);
591 _vbo_CreateContext(ctx);
592 _tnl_CreateContext(ctx);
593 _swsetup_CreateContext(ctx);
594
595 /* Install the customized pipeline:
596 */
597 _tnl_destroy_pipeline(ctx);
598 _tnl_install_pipeline(ctx, via_pipeline);
599
600 /* Configure swrast and T&L to match hardware characteristics:
601 */
602 _swrast_allow_pixel_fog(ctx, GL_FALSE);
603 _swrast_allow_vertex_fog(ctx, GL_TRUE);
604 _tnl_allow_pixel_fog(ctx, GL_FALSE);
605 _tnl_allow_vertex_fog(ctx, GL_TRUE);
606
607 vmesa->hHWContext = driContextPriv->hHWContext;
608 vmesa->driFd = sPriv->fd;
609 vmesa->driHwLock = &sPriv->pSAREA->lock;
610
611 vmesa->viaScreen = viaScreen;
612 vmesa->driScreen = sPriv;
613 vmesa->sarea = saPriv;
614
615 vmesa->renderIndex = ~0;
616 vmesa->setupIndex = ~0;
617 vmesa->hwPrimitive = GL_POLYGON+1;
618
619 /* KW: Hardwire this. Was previously set bogusly in
620 * viaCreateBuffer. Needs work before PBUFFER can be used:
621 */
622 vmesa->drawType = GLX_WINDOW_BIT;
623
624
625 _math_matrix_ctr(&vmesa->ViewportMatrix);
626
627 /* Do this early, before VIA_FLUSH_DMA can be called:
628 */
629 if (!AllocateDmaBuffer(vmesa)) {
630 fprintf(stderr ,"AllocateDmaBuffer fail\n");
631 FreeBuffer(vmesa);
632 FREE(vmesa);
633 return GL_FALSE;
634 }
635
636 /* Allocate a small piece of fb memory for synchronization:
637 */
638 vmesa->breadcrumb.bpp = 32;
639 vmesa->breadcrumb.pitch = buffer_align( 64 ) << 2;
640 vmesa->breadcrumb.size = vmesa->breadcrumb.pitch;
641
642 if (!via_alloc_draw_buffer(vmesa, &vmesa->breadcrumb)) {
643 fprintf(stderr ,"AllocateDmaBuffer fail\n");
644 FreeBuffer(vmesa);
645 FREE(vmesa);
646 return GL_FALSE;
647 }
648
649 driInitExtensions( ctx, card_extensions, GL_TRUE );
650 viaInitStateFuncs(ctx);
651 viaInitTriFuncs(ctx);
652 viaInitSpanFuncs(ctx);
653 viaInitIoctlFuncs(ctx);
654 viaInitState(ctx);
655
656 if (getenv("VIA_DEBUG"))
657 VIA_DEBUG = driParseDebugString( getenv( "VIA_DEBUG" ),
658 debug_control );
659
660 if (getenv("VIA_NO_RAST") ||
661 driQueryOptionb(&vmesa->optionCache, "no_rast"))
662 FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
663
664 if (getenv("VIA_PAGEFLIP"))
665 vmesa->allowPageFlip = 1;
666
667 (*sPriv->systemTime->getUST)( &vmesa->swap_ust );
668
669
670 vmesa->regMMIOBase = (GLuint *)((unsigned long)viaScreen->reg);
671 vmesa->pnGEMode = (GLuint *)((unsigned long)viaScreen->reg + 0x4);
672 vmesa->regEngineStatus = (GLuint *)((unsigned long)viaScreen->reg + 0x400);
673 vmesa->regTranSet = (GLuint *)((unsigned long)viaScreen->reg + 0x43C);
674 vmesa->regTranSpace = (GLuint *)((unsigned long)viaScreen->reg + 0x440);
675 vmesa->agpBase = viaScreen->agpBase;
676
677
678 return GL_TRUE;
679 }
680
681 void
682 viaDestroyContext(__DRIcontext *driContextPriv)
683 {
684 GET_CURRENT_CONTEXT(ctx);
685 struct via_context *vmesa =
686 (struct via_context *)driContextPriv->driverPrivate;
687 struct via_context *current = ctx ? VIA_CONTEXT(ctx) : NULL;
688
689 assert(vmesa); /* should never be null */
690
691 if (vmesa->driDrawable) {
692 viaWaitIdle(vmesa, GL_FALSE);
693
694 if (vmesa->doPageFlip) {
695 LOCK_HARDWARE(vmesa);
696 if (vmesa->pfCurrentOffset != 0) {
697 fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
698 viaResetPageFlippingLocked(vmesa);
699 }
700 UNLOCK_HARDWARE(vmesa);
701 }
702 }
703
704 /* check if we're deleting the currently bound context */
705 if (vmesa == current) {
706 VIA_FLUSH_DMA(vmesa);
707 _mesa_make_current(NULL, NULL, NULL);
708 }
709
710 _swsetup_DestroyContext(vmesa->glCtx);
711 _tnl_DestroyContext(vmesa->glCtx);
712 _vbo_DestroyContext(vmesa->glCtx);
713 _swrast_DestroyContext(vmesa->glCtx);
714 /* free the Mesa context */
715 _mesa_destroy_context(vmesa->glCtx);
716 /* release our data */
717 FreeBuffer(vmesa);
718
719 assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]));
720 assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]));
721 assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]));
722 assert (is_empty_list(&vmesa->freed_tex_buffers));
723
724 driDestroyOptionCache(&vmesa->optionCache);
725
726 FREE(vmesa);
727 }
728
729
730 void viaXMesaWindowMoved(struct via_context *vmesa)
731 {
732 __DRIdrawable *const drawable = vmesa->driDrawable;
733 __DRIdrawable *const readable = vmesa->driReadable;
734 struct via_renderbuffer * draw_buffer;
735 struct via_renderbuffer * read_buffer;
736 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
737
738 if (!drawable)
739 return;
740
741 draw_buffer = (struct via_renderbuffer *) drawable->driverPrivate;
742 read_buffer = (struct via_renderbuffer *) readable->driverPrivate;
743
744 switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0]) {
745 case BUFFER_BACK_LEFT:
746 if (drawable->numBackClipRects == 0) {
747 vmesa->numClipRects = drawable->numClipRects;
748 vmesa->pClipRects = drawable->pClipRects;
749 }
750 else {
751 vmesa->numClipRects = drawable->numBackClipRects;
752 vmesa->pClipRects = drawable->pBackClipRects;
753 }
754 break;
755 case BUFFER_FRONT_LEFT:
756 vmesa->numClipRects = drawable->numClipRects;
757 vmesa->pClipRects = drawable->pClipRects;
758 break;
759 default:
760 vmesa->numClipRects = 0;
761 break;
762 }
763
764 if ((draw_buffer->drawW != drawable->w)
765 || (draw_buffer->drawH != drawable->h)) {
766 calculate_buffer_parameters(vmesa, vmesa->glCtx->DrawBuffer,
767 drawable);
768 }
769
770 draw_buffer->drawX = drawable->x;
771 draw_buffer->drawY = drawable->y;
772 draw_buffer->drawW = drawable->w;
773 draw_buffer->drawH = drawable->h;
774
775 if (drawable != readable) {
776 if ((read_buffer->drawW != readable->w)
777 || (read_buffer->drawH != readable->h)) {
778 calculate_buffer_parameters(vmesa, vmesa->glCtx->ReadBuffer,
779 readable);
780 }
781
782 read_buffer->drawX = readable->x;
783 read_buffer->drawY = readable->y;
784 read_buffer->drawW = readable->w;
785 read_buffer->drawH = readable->h;
786 }
787
788 vmesa->front.orig = (vmesa->front.offset +
789 draw_buffer->drawY * vmesa->front.pitch +
790 draw_buffer->drawX * bytePerPixel);
791
792 vmesa->front.origMap = (vmesa->front.map +
793 draw_buffer->drawY * vmesa->front.pitch +
794 draw_buffer->drawX * bytePerPixel);
795
796 vmesa->back.orig = (vmesa->back.offset +
797 draw_buffer->drawY * vmesa->back.pitch +
798 draw_buffer->drawX * bytePerPixel);
799
800 vmesa->back.origMap = (vmesa->back.map +
801 draw_buffer->drawY * vmesa->back.pitch +
802 draw_buffer->drawX * bytePerPixel);
803
804 vmesa->depth.orig = (vmesa->depth.offset +
805 draw_buffer->drawY * vmesa->depth.pitch +
806 draw_buffer->drawX * bytePerPixel);
807
808 vmesa->depth.origMap = (vmesa->depth.map +
809 draw_buffer->drawY * vmesa->depth.pitch +
810 draw_buffer->drawX * bytePerPixel);
811
812 viaCalcViewport(vmesa->glCtx);
813 }
814
815 GLboolean
816 viaUnbindContext(__DRIcontext *driContextPriv)
817 {
818 return GL_TRUE;
819 }
820
821 GLboolean
822 viaMakeCurrent(__DRIcontext *driContextPriv,
823 __DRIdrawable *driDrawPriv,
824 __DRIdrawable *driReadPriv)
825 {
826 if (VIA_DEBUG & DEBUG_DRI) {
827 fprintf(stderr, "driContextPriv = %016lx\n", (unsigned long)driContextPriv);
828 fprintf(stderr, "driDrawPriv = %016lx\n", (unsigned long)driDrawPriv);
829 fprintf(stderr, "driReadPriv = %016lx\n", (unsigned long)driReadPriv);
830 }
831
832 if (driContextPriv) {
833 struct via_context *vmesa =
834 (struct via_context *)driContextPriv->driverPrivate;
835 GLcontext *ctx = vmesa->glCtx;
836 struct gl_framebuffer *drawBuffer, *readBuffer;
837
838 drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
839 readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
840
841 if ((vmesa->driDrawable != driDrawPriv)
842 || (vmesa->driReadable != driReadPriv)) {
843 if (driDrawPriv->swap_interval == (unsigned)-1) {
844 driDrawPriv->vblFlags =
845 vmesa->viaScreen->irqEnabled ?
846 driGetDefaultVBlankFlags(&vmesa->optionCache) :
847 VBLANK_FLAG_NO_IRQ;
848
849 driDrawableInitVBlank(driDrawPriv);
850 }
851
852 vmesa->driDrawable = driDrawPriv;
853 vmesa->driReadable = driReadPriv;
854
855 if ((drawBuffer->Width != driDrawPriv->w)
856 || (drawBuffer->Height != driDrawPriv->h)) {
857 _mesa_resize_framebuffer(ctx, drawBuffer,
858 driDrawPriv->w, driDrawPriv->h);
859 drawBuffer->Initialized = GL_TRUE;
860 }
861
862 if (!calculate_buffer_parameters(vmesa, drawBuffer, driDrawPriv)) {
863 return GL_FALSE;
864 }
865
866 if (driDrawPriv != driReadPriv) {
867 if ((readBuffer->Width != driReadPriv->w)
868 || (readBuffer->Height != driReadPriv->h)) {
869 _mesa_resize_framebuffer(ctx, readBuffer,
870 driReadPriv->w, driReadPriv->h);
871 readBuffer->Initialized = GL_TRUE;
872 }
873
874 if (!calculate_buffer_parameters(vmesa, readBuffer, driReadPriv)) {
875 return GL_FALSE;
876 }
877 }
878 }
879
880 _mesa_make_current(vmesa->glCtx, drawBuffer, readBuffer);
881
882 ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
883
884 viaXMesaWindowMoved(vmesa);
885 ctx->Driver.Scissor(vmesa->glCtx,
886 vmesa->glCtx->Scissor.X,
887 vmesa->glCtx->Scissor.Y,
888 vmesa->glCtx->Scissor.Width,
889 vmesa->glCtx->Scissor.Height);
890 }
891 else {
892 _mesa_make_current(NULL, NULL, NULL);
893 }
894
895 return GL_TRUE;
896 }
897
898 void viaGetLock(struct via_context *vmesa, GLuint flags)
899 {
900 __DRIdrawable *dPriv = vmesa->driDrawable;
901 __DRIscreen *sPriv = vmesa->driScreen;
902
903 drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
904
905 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
906 if (dPriv != vmesa->driReadable) {
907 DRI_VALIDATE_DRAWABLE_INFO(sPriv, vmesa->driReadable);
908 }
909
910 if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
911 vmesa->sarea->ctxOwner = vmesa->hHWContext;
912 vmesa->newEmitState = ~0;
913 }
914
915 if (vmesa->lastStamp != dPriv->lastStamp) {
916 viaXMesaWindowMoved(vmesa);
917 driUpdateFramebufferSize(vmesa->glCtx, dPriv);
918 vmesa->newEmitState = ~0;
919 vmesa->lastStamp = dPriv->lastStamp;
920 }
921
922 if (vmesa->doPageFlip &&
923 vmesa->pfCurrentOffset != vmesa->sarea->pfCurrentOffset) {
924 fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
925 viaResetPageFlippingLocked(vmesa);
926 }
927 }
928
929
930 void
931 viaSwapBuffers(__DRIdrawable *drawablePrivate)
932 {
933 __DRIdrawable *dPriv = (__DRIdrawable *)drawablePrivate;
934
935 if (dPriv &&
936 dPriv->driContextPriv &&
937 dPriv->driContextPriv->driverPrivate) {
938 struct via_context *vmesa =
939 (struct via_context *)dPriv->driContextPriv->driverPrivate;
940 GLcontext *ctx = vmesa->glCtx;
941
942 _mesa_notifySwapBuffers(ctx);
943
944 if (ctx->Visual.doubleBufferMode) {
945 if (vmesa->doPageFlip) {
946 viaPageFlip(dPriv);
947 }
948 else {
949 viaCopyBuffer(dPriv);
950 }
951 }
952 else
953 VIA_FLUSH_DMA(vmesa);
954 }
955 else {
956 _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
957 }
958 }