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