Tizen 2.0 Release
[profile/ivi/osmesa.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 }