Merge remote branch 'origin/gallium-0.2' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / unichrome / via_context.c
index fa143186c1bdc375a26bdc4b9140555c185ff2e8..f5bdb65eb081527b5975cf8eba34ddba22d28625 100644 (file)
  * \author Others at S3 Graphics?
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "matrix.h"
-#include "state.h"
-#include "simple_list.h"
-#include "extensions.h"
-#include "framebuffer.h"
-#include "renderbuffer.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/matrix.h"
+#include "main/state.h"
+#include "main/simple_list.h"
+#include "main/extensions.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "tnl/tnl.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 
 #include "tnl/t_pipeline.h"
 
 #include "via_fb.h"
 
 #include <stdio.h>
-#include "macros.h"
+#include "main/macros.h"
 #include "drirenderbuffer.h"
 
 #define need_GL_ARB_multisample
 #define need_GL_ARB_point_parameters
+#define need_GL_ARB_vertex_buffer_object
 #define need_GL_EXT_fog_coord
 #define need_GL_EXT_secondary_color
 #include "extension_helper.h"
@@ -122,7 +123,7 @@ static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
  * 
  * \returns A pixel width that meets the alignment requirements.
  */
-static __inline__ unsigned
+static INLINE unsigned
 buffer_align( unsigned width )
 {
     return (width + 0x0f) & ~0x0f;
@@ -147,10 +148,13 @@ viaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
 
 
 static void
-viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
+viaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format,
+                   __DRIdrawablePrivate *dPriv)
 {
    const GLuint name = 0;
+   struct gl_renderbuffer *rb = & vrb->Base;
 
+   vrb->dPriv = dPriv;
    _mesa_init_renderbuffer(rb, name);
 
    /* Make sure we're using a null-valued GetPointer routine */
@@ -198,8 +202,9 @@ viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
  * \sa AllocateBuffer
  */
 static GLboolean
-calculate_buffer_parameters( struct via_context *vmesa,
-                             struct gl_framebuffer *fb )
+calculate_buffer_parameters(struct via_context *vmesa,
+                           struct gl_framebuffer *fb,
+                           __DRIdrawablePrivate *dPriv)
 {
    const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
    const unsigned extra = 32;
@@ -215,26 +220,28 @@ calculate_buffer_parameters( struct via_context *vmesa,
 
    if (!vmesa->front.Base.InternalFormat) {
       /* do one-time init for the renderbuffers */
-      viaInitRenderbuffer(&vmesa->front.Base, GL_RGBA);
+      viaInitRenderbuffer(&vmesa->front, GL_RGBA, dPriv);
       viaSetSpanFunctions(&vmesa->front, &fb->Visual);
       _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base);
 
       if (fb->Visual.doubleBufferMode) {
-         viaInitRenderbuffer(&vmesa->back.Base, GL_RGBA);
+         viaInitRenderbuffer(&vmesa->back, GL_RGBA, dPriv);
          viaSetSpanFunctions(&vmesa->back, &fb->Visual);
          _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base);
       }
 
       if (vmesa->glCtx->Visual.depthBits > 0) {
-         viaInitRenderbuffer(&vmesa->depth.Base, 
+         viaInitRenderbuffer(&vmesa->depth,
                              (vmesa->glCtx->Visual.depthBits == 16
-                              ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24));
+                              ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24),
+                            dPriv);
          viaSetSpanFunctions(&vmesa->depth, &fb->Visual);
          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base);
       }
 
       if (vmesa->glCtx->Visual.stencilBits > 0) {
-         viaInitRenderbuffer(&vmesa->stencil.Base, GL_STENCIL_INDEX8_EXT);
+         viaInitRenderbuffer(&vmesa->stencil, GL_STENCIL_INDEX8_EXT,
+                            dPriv);
          viaSetSpanFunctions(&vmesa->stencil, &fb->Visual);
          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base);
       }
@@ -243,11 +250,9 @@ calculate_buffer_parameters( struct via_context *vmesa,
    assert(vmesa->front.Base.InternalFormat);
    assert(vmesa->front.Base.AllocStorage);
    if (fb->Visual.doubleBufferMode) {
-      assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
-      assert(vmesa->front.Base.AllocStorage);
+      assert(vmesa->back.Base.AllocStorage);
    }
    if (fb->Visual.depthBits) {
-      assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
       assert(vmesa->depth.Base.AllocStorage);
    }
 
@@ -352,19 +357,11 @@ void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
 {
     struct via_context *vmesa = VIA_CONTEXT(ctx);
 
-    calculate_buffer_parameters( vmesa, drawbuffer );
+    calculate_buffer_parameters(vmesa, drawbuffer, vmesa->driDrawable);
 
     _mesa_resize_framebuffer(ctx, drawbuffer, width, height);
 }
 
-static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
-{
-    GET_CURRENT_CONTEXT(ctx);
-    struct via_context *vmesa = VIA_CONTEXT(ctx);       
-    *width = vmesa->driDrawable->w;
-    *height = vmesa->driDrawable->h;
-}
-
 /* Extension strings exported by the Unichrome driver.
  */
 const struct dri_extension card_extensions[] =
@@ -376,6 +373,7 @@ const struct dri_extension card_extensions[] =
     { "GL_ARB_texture_env_combine",        NULL },
 /*    { "GL_ARB_texture_env_dot3",           NULL }, */
     { "GL_ARB_texture_mirrored_repeat",    NULL },
+    { "GL_ARB_vertex_buffer_object",       GL_ARB_vertex_buffer_object_functions },
     { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
     { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
     { "GL_EXT_stencil_wrap",               NULL },
@@ -579,7 +577,6 @@ viaCreateContext(const __GLcontextModes *visual,
     ctx->Const.MaxPointSizeAA = 1.0;
     ctx->Const.PointSizeGranularity = 1.0;
 
-    ctx->Driver.GetBufferSize = viaBufferSize;
     ctx->Driver.GetString = viaGetString;
 
     ctx->DriverCtx = (void *)vmesa;
@@ -588,7 +585,7 @@ viaCreateContext(const __GLcontextModes *visual,
     /* Initialize the software rasterizer and helper modules.
      */
     _swrast_CreateContext(ctx);
-    _ac_CreateContext(ctx);
+    _vbo_CreateContext(ctx);
     _tnl_CreateContext(ctx);
     _swsetup_CreateContext(ctx);
 
@@ -604,9 +601,6 @@ viaCreateContext(const __GLcontextModes *visual,
     _tnl_allow_pixel_fog(ctx, GL_FALSE);
     _tnl_allow_vertex_fog(ctx, GL_TRUE);
 
-/*     vmesa->display = dpy; */
-    vmesa->display = sPriv->display;
-    
     vmesa->hHWContext = driContextPriv->hHWContext;
     vmesa->driFd = sPriv->fd;
     vmesa->driHwLock = &sPriv->pSAREA->lock;
@@ -664,14 +658,10 @@ viaCreateContext(const __GLcontextModes *visual,
         driQueryOptionb(&vmesa->optionCache, "no_rast"))
        FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
 
-    vmesa->vblank_flags =
-       vmesa->viaScreen->irqEnabled ?
-        driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
-
     if (getenv("VIA_PAGEFLIP"))
        vmesa->allowPageFlip = 1;
 
-    (*dri_interface->getUST)( &vmesa->swap_ust );
+    (*sPriv->systemTime->getUST)( &vmesa->swap_ust );
 
 
     vmesa->regMMIOBase = (GLuint *)((unsigned long)viaScreen->reg);
@@ -689,100 +679,132 @@ void
 viaDestroyContext(__DRIcontextPrivate *driContextPriv)
 {
     GET_CURRENT_CONTEXT(ctx);
-    struct via_context *vmesa = 
+    struct via_context *vmesa =
        (struct via_context *)driContextPriv->driverPrivate;
     struct via_context *current = ctx ? VIA_CONTEXT(ctx) : NULL;
+
     assert(vmesa); /* should never be null */
 
+    if (vmesa->driDrawable) {
+       viaWaitIdle(vmesa, GL_FALSE);
+
+       if (vmesa->doPageFlip) {
+         LOCK_HARDWARE(vmesa);
+         if (vmesa->pfCurrentOffset != 0) {
+            fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
+            viaResetPageFlippingLocked(vmesa);
+         }
+         UNLOCK_HARDWARE(vmesa);
+       }
+    }
+
     /* check if we're deleting the currently bound context */
     if (vmesa == current) {
       VIA_FLUSH_DMA(vmesa);
       _mesa_make_current(NULL, NULL, NULL);
     }
 
-    if (vmesa) {
-        viaWaitIdle(vmesa, GL_FALSE);
-       if (vmesa->doPageFlip) {
-          LOCK_HARDWARE(vmesa);
-          if (vmesa->pfCurrentOffset != 0) {
-             fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
-             viaResetPageFlippingLocked(vmesa);
-          }
-          UNLOCK_HARDWARE(vmesa);
-       }
-       
-       _swsetup_DestroyContext(vmesa->glCtx);
-        _tnl_DestroyContext(vmesa->glCtx);
-        _ac_DestroyContext(vmesa->glCtx);
-        _swrast_DestroyContext(vmesa->glCtx);
-        /* free the Mesa context */
-       _mesa_destroy_context(vmesa->glCtx);
-       /* release our data */
-       FreeBuffer(vmesa);
+    _swsetup_DestroyContext(vmesa->glCtx);
+    _tnl_DestroyContext(vmesa->glCtx);
+    _vbo_DestroyContext(vmesa->glCtx);
+    _swrast_DestroyContext(vmesa->glCtx);
+    /* free the Mesa context */
+    _mesa_destroy_context(vmesa->glCtx);
+    /* release our data */
+    FreeBuffer(vmesa);
 
-       assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]));
-       assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]));
-       assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]));
-       assert (is_empty_list(&vmesa->freed_tex_buffers));
+    assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]));
+    assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]));
+    assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]));
+    assert (is_empty_list(&vmesa->freed_tex_buffers));
 
-       driDestroyOptionCache(&vmesa->optionCache);
+    driDestroyOptionCache(&vmesa->optionCache);
 
-       FREE(vmesa);
-    }
+    FREE(vmesa);
 }
 
 
 void viaXMesaWindowMoved(struct via_context *vmesa)
 {
-   __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+   __DRIdrawablePrivate *const drawable = vmesa->driDrawable;
+   __DRIdrawablePrivate *const readable = vmesa->driReadable;
+   struct via_renderbuffer * draw_buffer;
+   struct via_renderbuffer * read_buffer;
    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
 
-   if (!dPriv)
+   if (!drawable)
       return;
+
+   draw_buffer =  (struct via_renderbuffer *) drawable->driverPrivate;
+   read_buffer =  (struct via_renderbuffer *) readable->driverPrivate;
    
-   switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
-   case BUFFER_BIT_BACK_LEFT: 
-      if (dPriv->numBackClipRects == 0) {
-        vmesa->numClipRects = dPriv->numClipRects;
-        vmesa->pClipRects = dPriv->pClipRects;
+   switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0]) {
+   case BUFFER_BACK_LEFT: 
+      if (drawable->numBackClipRects == 0) {
+        vmesa->numClipRects = drawable->numClipRects;
+        vmesa->pClipRects = drawable->pClipRects;
       } 
       else {
-        vmesa->numClipRects = dPriv->numBackClipRects;
-        vmesa->pClipRects = dPriv->pBackClipRects;
+        vmesa->numClipRects = drawable->numBackClipRects;
+        vmesa->pClipRects = drawable->pBackClipRects;
       }
       break;
-   case BUFFER_BIT_FRONT_LEFT:
-      vmesa->numClipRects = dPriv->numClipRects;
-      vmesa->pClipRects = dPriv->pClipRects;
+   case BUFFER_FRONT_LEFT:
+      vmesa->numClipRects = drawable->numClipRects;
+      vmesa->pClipRects = drawable->pClipRects;
       break;
    default:
       vmesa->numClipRects = 0;
       break;
    }
 
-   if (vmesa->drawW != dPriv->w ||
-       vmesa->drawH != dPriv->h) 
-      calculate_buffer_parameters( vmesa, vmesa->glCtx->DrawBuffer );
+   if ((draw_buffer->drawW != drawable->w) 
+       || (draw_buffer->drawH != drawable->h)) {
+      calculate_buffer_parameters(vmesa, vmesa->glCtx->DrawBuffer,
+                                 drawable);
+   }
+
+   draw_buffer->drawX = drawable->x;
+   draw_buffer->drawY = drawable->y;
+   draw_buffer->drawW = drawable->w;
+   draw_buffer->drawH = drawable->h;
+
+   if (drawable != readable) {
+      if ((read_buffer->drawW != readable->w) 
+         || (read_buffer->drawH != readable->h)) {
+        calculate_buffer_parameters(vmesa, vmesa->glCtx->ReadBuffer,
+                                    readable);
+      }
 
-   vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) / 
-                             bytePerPixel);  
-   vmesa->drawX = dPriv->x - vmesa->drawXoff;
-   vmesa->drawY = dPriv->y;
-   vmesa->drawW = dPriv->w;
-   vmesa->drawH = dPriv->h;
+      read_buffer->drawX = readable->x;
+      read_buffer->drawY = readable->y;
+      read_buffer->drawW = readable->w;
+      read_buffer->drawH = readable->h;
+   }
 
    vmesa->front.orig = (vmesa->front.offset + 
-                       vmesa->drawY * vmesa->front.pitch + 
-                       vmesa->drawX * bytePerPixel);
+                       draw_buffer->drawY * vmesa->front.pitch + 
+                       draw_buffer->drawX * bytePerPixel);
 
    vmesa->front.origMap = (vmesa->front.map + 
-                          vmesa->drawY * vmesa->front.pitch + 
-                          vmesa->drawX * bytePerPixel);
+                       draw_buffer->drawY * vmesa->front.pitch + 
+                       draw_buffer->drawX * bytePerPixel);
+
+   vmesa->back.orig = (vmesa->back.offset +
+                       draw_buffer->drawY * vmesa->back.pitch +
+                       draw_buffer->drawX * bytePerPixel);
+
+   vmesa->back.origMap = (vmesa->back.map +
+                       draw_buffer->drawY * vmesa->back.pitch +
+                       draw_buffer->drawX * bytePerPixel);
 
-   vmesa->back.orig = vmesa->back.offset;
-   vmesa->depth.orig = vmesa->depth.offset;   
-   vmesa->back.origMap = vmesa->back.map;
-   vmesa->depth.origMap = vmesa->depth.map;
+   vmesa->depth.orig = (vmesa->depth.offset +
+                       draw_buffer->drawY * vmesa->depth.pitch +
+                       draw_buffer->drawX * bytePerPixel);   
+
+   vmesa->depth.origMap = (vmesa->depth.map +
+                       draw_buffer->drawY * vmesa->depth.pitch +
+                       draw_buffer->drawX * bytePerPixel);
 
    viaCalcViewport(vmesa->glCtx);
 }
@@ -813,14 +835,44 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
         drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate;
         readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
 
-       if ( vmesa->driDrawable != driDrawPriv ) {
-          driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags,
-                                 &vmesa->vbl_seq );
-          vmesa->driDrawable = driDrawPriv;
-          if ( ! calculate_buffer_parameters( vmesa, drawBuffer ) ) {
-             return GL_FALSE;
-          }
-       }
+       if ((vmesa->driDrawable != driDrawPriv)
+          || (vmesa->driReadable != driReadPriv)) {
+         if (driDrawPriv->swap_interval == (unsigned)-1) {
+            driDrawPriv->vblFlags =
+               vmesa->viaScreen->irqEnabled ?
+               driGetDefaultVBlankFlags(&vmesa->optionCache) :
+               VBLANK_FLAG_NO_IRQ;
+
+            driDrawableInitVBlank(driDrawPriv);
+         }
+
+         vmesa->driDrawable = driDrawPriv;
+         vmesa->driReadable = driReadPriv;
+
+         if ((drawBuffer->Width != driDrawPriv->w) 
+             || (drawBuffer->Height != driDrawPriv->h)) {
+            _mesa_resize_framebuffer(ctx, drawBuffer,
+                                     driDrawPriv->w, driDrawPriv->h);
+            drawBuffer->Initialized = GL_TRUE;
+         }
+
+         if (!calculate_buffer_parameters(vmesa, drawBuffer, driDrawPriv)) {
+            return GL_FALSE;
+         }
+
+         if (driDrawPriv != driReadPriv) {
+            if ((readBuffer->Width != driReadPriv->w)
+                || (readBuffer->Height != driReadPriv->h)) {
+               _mesa_resize_framebuffer(ctx, readBuffer,
+                                        driReadPriv->w, driReadPriv->h);
+               readBuffer->Initialized = GL_TRUE;
+            }
+
+            if (!calculate_buffer_parameters(vmesa, readBuffer, driReadPriv)) {
+               return GL_FALSE;
+            }
+         }
+       }
 
         _mesa_make_current(vmesa->glCtx, drawBuffer, readBuffer);
 
@@ -847,7 +899,10 @@ void viaGetLock(struct via_context *vmesa, GLuint flags)
 
     drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
 
-    DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+    DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+    if (dPriv != vmesa->driReadable) {
+       DRI_VALIDATE_DRAWABLE_INFO(sPriv, vmesa->driReadable);
+    }
 
     if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
        vmesa->sarea->ctxOwner = vmesa->hHWContext;