Call _mesa_resize_framebuffer() within intelWindowMoved(). Fixes
[mesa.git] / src / mesa / drivers / dri / i915 / intel_context.c
index ba155d53ec99aa1484ac24a3c9943fc2c49d86ee..54b0960c565d3354fa27bea083bf434ea2b7ca71 100644 (file)
@@ -31,6 +31,7 @@
 #include "matrix.h"
 #include "simple_list.h"
 #include "extensions.h"
+#include "framebuffer.h"
 #include "imports.h"
 
 #include "swrast/swrast.h"
 #include "intel_ioctl.h"
 #include "intel_batchbuffer.h"
 
+#include "vblank.h"
 #include "utils.h"
+#include "xmlpool.h" /* for symbolic values of enum-type options */
 #ifndef INTEL_DEBUG
 int INTEL_DEBUG = (0);
 #endif
 
+#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_window_pos
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_equation_separate
+#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_cull_vertex
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_multi_draw_arrays
+#define need_GL_EXT_secondary_color
+#define need_GL_NV_vertex_program
+#include "extension_helper.h"
+
 #ifndef VERBOSE
 int VERBOSE = 0;
 #endif
@@ -72,7 +92,7 @@ int prevLockLine;
  * Mesa's Driver Functions
  ***************************************/
 
-#define DRIVER_DATE                     "20041217"
+#define DRIVER_DATE                     "20050225"
 
 const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
 {
@@ -98,6 +118,10 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
         chipset = "Intel(R) 915G"; break;
       case PCI_CHIP_I915_GM:
         chipset = "Intel(R) 915GM"; break;
+      case PCI_CHIP_I945_G:
+        chipset = "Intel(R) 945G"; break;
+      case PCI_CHIP_I945_GM:
+        chipset = "Intel(R) 945GM"; break;
       default:
         chipset = "Unknown Intel Chipset"; break;
       }
@@ -120,57 +144,65 @@ static void intelBufferSize(GLframebuffer *buffer,
     * to be correct.
     */
    LOCK_HARDWARE(intel);
-   *width = intel->driDrawable->w;
-   *height = intel->driDrawable->h;
+   if (intel->driDrawable) {
+      *width = intel->driDrawable->w;
+      *height = intel->driDrawable->h;
+   }
+   else {
+      *width = 0;
+      *height = 0;
+   }
    UNLOCK_HARDWARE(intel);
 }
 
-static const char * const card_extensions[] =
+
+/**
+ * Extension strings exported by the intel driver.
+ *
+ * \note
+ * It appears that ARB_texture_env_crossbar has "disappeared" compared to the
+ * old i830-specific driver.
+ */
+const struct dri_extension card_extensions[] =
 {
-   "GL_APPLE_client_storage",
-   "GL_ARB_multisample",
-   "GL_ARB_multitexture",
-   "GL_ARB_point_parameters",
-   "GL_ARB_texture_border_clamp",
-   "GL_ARB_texture_compression",
-   "GL_ARB_texture_cube_map",
-   "GL_ARB_texture_env_add",
-   "GL_ARB_texture_env_combine",
-   "GL_ARB_texture_env_dot3",
-   "GL_ARB_texture_mirrored_repeat",
-   "GL_ARB_texture_rectangle",
-   "GL_ARB_vertex_buffer_object",
-   "GL_ARB_vertex_program",
-   "GL_ARB_window_pos",
-   "GL_EXT_abgr",
-   "GL_EXT_bgra",
-   "GL_EXT_blend_color",
-   "GL_EXT_blend_equation_separate",
-   "GL_EXT_blend_func_separate",
-   "GL_EXT_blend_minmax",
-   "GL_EXT_blend_subtract",
-   "GL_EXT_fog_coord",
-   "GL_EXT_multi_draw_arrays",
-   "GL_EXT_secondary_color",
-   "GL_EXT_stencil_wrap",
-   "GL_EXT_texture_edge_clamp",
-   "GL_EXT_texture_env_add",
-   "GL_EXT_texture_env_combine",
-   "GL_EXT_texture_env_dot3",
-   "GL_EXT_texture_filter_anisotropic",
-   "GL_EXT_texture_lod_bias",
-   "GL_3DFX_texture_compression_FXT1",
-   "GL_IBM_texture_mirrored_repeat",
-   "GL_INGR_blend_func_separate",
-   "GL_MESA_pack_invert",
-   "GL_MESA_ycbcr_texture",
-   "GL_NV_texture_rectangle",
-   "GL_NV_vertex_program",
-   "GL_NV_vertex_program1_1",
-   "GL_SGIS_generate_mipmap",
-   "GL_SGIS_texture_border_clamp",
-   "GL_SGIS_texture_edge_clamp",
-   NULL
+    { "GL_ARB_multisample",                GL_ARB_multisample_functions },
+    { "GL_ARB_multitexture",               NULL },
+    { "GL_ARB_point_parameters",           GL_ARB_point_parameters_functions },
+    { "GL_ARB_texture_border_clamp",       NULL },
+    { "GL_ARB_texture_compression",        GL_ARB_texture_compression_functions },
+    { "GL_ARB_texture_cube_map",           NULL },
+    { "GL_ARB_texture_env_add",            NULL },
+    { "GL_ARB_texture_env_combine",        NULL },
+    { "GL_ARB_texture_env_dot3",           NULL },
+    { "GL_ARB_texture_mirrored_repeat",    NULL },
+    { "GL_ARB_texture_rectangle",          NULL },
+    { "GL_ARB_vertex_buffer_object",       GL_ARB_vertex_buffer_object_functions },
+    { "GL_ARB_vertex_program",             GL_ARB_vertex_program_functions },
+    { "GL_ARB_window_pos",                 GL_ARB_window_pos_functions },
+    { "GL_EXT_blend_color",                GL_EXT_blend_color_functions },
+    { "GL_EXT_blend_equation_separate",    GL_EXT_blend_equation_separate_functions },
+    { "GL_EXT_blend_func_separate",        GL_EXT_blend_func_separate_functions },
+    { "GL_EXT_blend_minmax",               GL_EXT_blend_minmax_functions },
+    { "GL_EXT_blend_subtract",             NULL },
+    { "GL_EXT_cull_vertex",                GL_EXT_cull_vertex_functions },
+    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
+    { "GL_EXT_multi_draw_arrays",          GL_EXT_multi_draw_arrays_functions },
+    { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
+    { "GL_EXT_stencil_wrap",               NULL },
+    { "GL_EXT_texture_edge_clamp",         NULL },
+    { "GL_EXT_texture_env_combine",        NULL },
+    { "GL_EXT_texture_env_dot3",           NULL },
+    { "GL_EXT_texture_filter_anisotropic", NULL },
+    { "GL_EXT_texture_lod_bias",           NULL },
+    { "GL_3DFX_texture_compression_FXT1",  NULL },
+    { "GL_APPLE_client_storage",           NULL },
+    { "GL_MESA_pack_invert",               NULL },
+    { "GL_MESA_ycbcr_texture",             NULL },
+    { "GL_NV_blend_square",                NULL },
+    { "GL_NV_vertex_program",              GL_NV_vertex_program_functions },
+    { "GL_NV_vertex_program1_1",           NULL },
+    { "GL_SGIS_generate_mipmap",           NULL },
+    { NULL,                                NULL }
 };
 
 extern const struct tnl_pipeline_stage _intel_render_stage;
@@ -184,6 +216,7 @@ static const struct tnl_pipeline_stage *intel_pipeline[] = {
    &_tnl_texgen_stage,
    &_tnl_texture_transform_stage,
    &_tnl_point_attenuation_stage,
+   &_tnl_arb_vertex_program_stage,
    &_tnl_vertex_program_stage,
 #if 1
    &_intel_render_stage,     /* ADD: unclipped rastersetup-to-dma */
@@ -227,11 +260,11 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
 {
    _mesa_init_driver_functions( functions );
 
-   functions->Flush = intelFlush;
    functions->Clear = intelClear;
+   functions->Flush = intelglFlush;
    functions->Finish = intelFinish;
    functions->GetBufferSize = intelBufferSize;
-   functions->ResizeBuffers = _swrast_alloc_buffers;
+   functions->ResizeBuffers = _mesa_resize_framebuffer;
    functions->GetString = intelGetString;
    functions->UpdateState = intelInvalidateState;
    functions->CopyColorTable = _swrast_CopyColorTable;
@@ -244,6 +277,20 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
    intelInitStateFuncs( functions );
 }
 
+static void intel_emit_invarient_state( GLcontext *ctx )
+{
+   intelContextPtr intel = INTEL_CONTEXT(ctx);
+
+   intel->vtbl.emit_invarient_state( intel );
+   intel->prim.flush = 0;
+
+   /* Make sure this gets to the hardware, even if we have no cliprects:
+    */
+   LOCK_HARDWARE( intel );
+   intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
+   UNLOCK_HARDWARE( intel );
+}
+
 
 
 GLboolean intelInitContext( intelContextPtr intel,
@@ -258,6 +305,7 @@ GLboolean intelInitContext( intelContextPtr intel,
    intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
    drmI830Sarea *saPriv = (drmI830Sarea *)
       (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
+   int fthrottle_mode;
 
    if (!_mesa_initialize_context(&intel->ctx,
                                 mesaVis, shareCtx, 
@@ -274,6 +322,9 @@ GLboolean intelInitContext( intelContextPtr intel,
    (void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
    make_empty_list( & intel->swapped );
 
+   driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
+                       intel->driScreen->myNum, "i915");
+
    ctx->Const.MaxTextureMaxAnisotropy = 2.0;
 
    ctx->Const.MinLineWidth = 1.0;
@@ -337,9 +388,19 @@ GLboolean intelInitContext( intelContextPtr intel,
 
    intel->RenderIndex = ~0;
 
+   fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
+   intel->iw.irq_seq = -1;
+   intel->irqsEmitted = 0;
+
    intel->do_irqs = (intel->intelScreen->irq_active &&
-                    !getenv("INTEL_NO_IRQS"));
+                    fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
+
+   intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
+
+   intel->vblank_flags = (intel->intelScreen->irq_active != 0)
+       ? driGetDefaultVBlankFlags(&intelScreen->optionCache) : VBLANK_FLAG_NO_IRQ;
 
+   (*dri_interface->getUST)(&intel->swap_ust);
    _math_matrix_ctr (&intel->ViewportMatrix);
 
    driInitExtensions( ctx, card_extensions, GL_TRUE );
@@ -358,7 +419,8 @@ GLboolean intelInitContext( intelContextPtr intel,
 /*                       DRI_TEXMGR_DO_TEXTURE_RECT ); */
 
 
-   intel->prim.flush = intelInitBatchBuffer;
+   intelInitBatchBuffer(&intel->ctx);
+   intel->prim.flush = intel_emit_invarient_state;
    intel->prim.primitive = ~0;
 
 
@@ -391,6 +453,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
    if (intel) {
       GLboolean   release_texture_heaps;
 
+      INTEL_FIREVERTICES( intel );
 
       intel->vtbl.destroy( intel );
 
@@ -489,17 +552,43 @@ void intelSetBackClipRects( intelContextPtr intel )
 
 void intelWindowMoved( intelContextPtr intel )
 {
-   switch (intel->ctx.Color._DrawDestMask[0]) {
-   case DD_FRONT_LEFT_BIT:
-      intelSetFrontClipRects( intel );
-      break;
-   case DD_BACK_LEFT_BIT:
-      intelSetBackClipRects( intel );
-      break;
-   default:
-      /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
+   __DRIdrawablePrivate *dPriv = intel->driDrawable;
+
+   if (!intel->ctx.DrawBuffer) {
       intelSetFrontClipRects( intel );
    }
+   else {
+      driUpdateFramebufferSize(&intel->ctx, intel->driDrawable);
+    
+      switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
+      case BUFFER_BIT_FRONT_LEFT:
+        intelSetFrontClipRects( intel );
+        break;
+      case BUFFER_BIT_BACK_LEFT:
+        intelSetBackClipRects( intel );
+        break;
+      default:
+        /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
+        intelSetFrontClipRects( intel );
+      }
+   }
+
+   _mesa_resize_framebuffer(&intel->ctx,
+                           (GLframebuffer*)dPriv->driverPrivate,
+                           dPriv->w, dPriv->h);
+   
+   /* Set state we know depends on drawable parameters:
+    */
+   {
+      GLcontext *ctx = &intel->ctx;
+
+      ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
+                          ctx->Scissor.Width, ctx->Scissor.Height );
+      
+      ctx->Driver.DepthRange( ctx, 
+                             ctx->Viewport.Near,
+                             ctx->Viewport.Far );
+   }
 }
 
 GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
@@ -517,26 +606,58 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
 
       if ( intel->driDrawable != driDrawPriv ) {
         /* Shouldn't the readbuffer be stored also? */
+        driDrawableInitVBlank( driDrawPriv, intel->vblank_flags );
+
         intel->driDrawable = driDrawPriv;
         intelWindowMoved( intel );
       }
 
-      _mesa_make_current2(&intel->ctx,
-                         (GLframebuffer *) driDrawPriv->driverPrivate,
-                         (GLframebuffer *) driReadPriv->driverPrivate);
+      _mesa_make_current(&intel->ctx,
+                        (GLframebuffer *) driDrawPriv->driverPrivate,
+                        (GLframebuffer *) driReadPriv->driverPrivate);
+
+      intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] );
    } else {
-      _mesa_make_current(0,0);
+      _mesa_make_current(NULL, NULL, NULL);
    }
 
    return GL_TRUE;
 }
 
+/**
+ * Use the information in the sarea to update the screen parameters
+ * related to screen rotation.
+ */
+static void
+intelUpdateScreenRotation(intelContextPtr intel,
+                          __DRIscreenPrivate *sPriv,
+                          drmI830Sarea *sarea)
+{
+   intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
+   intelRegion *colorBuf;
+
+   intelUnmapScreenRegions(intelScreen);
+
+   intelUpdateScreenFromSAREA(intelScreen, sarea);
+
+   /* update the current hw offsets for the color and depth buffers */
+   if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT)
+      colorBuf = &intelScreen->back;
+   else
+      colorBuf = &intelScreen->front;
+   intel->vtbl.update_color_z_regions(intel, colorBuf, &intelScreen->depth);
+
+   if (!intelMapScreenRegions(sPriv)) {
+      fprintf(stderr, "ERROR Remapping screen regions!!!\n");
+   }
+}
+
 void intelGetLock( intelContextPtr intel, GLuint flags )
 {
    __DRIdrawablePrivate *dPriv = intel->driDrawable;
    __DRIscreenPrivate *sPriv = intel->driScreen;
+   intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
    drmI830Sarea * sarea = intel->sarea;
-   int me = intel->hHWContext;
    unsigned   i;
 
    drmGetLock(intel->driFd, intel->hHWContext, flags);
@@ -549,32 +670,54 @@ void intelGetLock( intelContextPtr intel, GLuint flags )
    if (dPriv)
       DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
 
+   if (dPriv && intel->lastStamp != dPriv->lastStamp) {
+      intelWindowMoved( intel );
+      intel->lastStamp = dPriv->lastStamp;
+   }
+
    /* If we lost context, need to dump all registers to hardware.
     * Note that we don't care about 2d contexts, even if they perform
     * accelerated commands, so the DRI locking in the X server is even
     * more broken than usual.
     */
 
-   if (sarea->ctxOwner != me) {
-      intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
-      sarea->ctxOwner = me;
+   if (sarea->width != intelScreen->width ||
+       sarea->height != intelScreen->height ||
+       sarea->rotation != intelScreen->current_rotation) {
+      intelUpdateScreenRotation(intel, sPriv, sarea);
+
+      /* This will drop the outstanding batchbuffer on the floor */
+      intel->batch.ptr -= (intel->batch.size - intel->batch.space);
+      intel->batch.space = intel->batch.size;
+      /* lose all primitives */
+      intel->prim.primitive = ~0;
+      intel->prim.start_ptr = 0;
+      intel->prim.flush = 0;
+      intel->vtbl.lost_hardware( intel ); 
+
+      intel->lastStamp = 0; /* force window update */
+
+      /* Release batch buffer
+       */
+      intelDestroyBatchBuffer(&intel->ctx);
+      intelInitBatchBuffer(&intel->ctx);
+      intel->prim.flush = intel_emit_invarient_state;
+
+      /* Still need to reset the global LRU?
+       */
+      intel_driReinitTextureHeap( intel->texture_heaps[0], intel->intelScreen->tex.size );
    }
 
    /* Shared texture managment - if another client has played with
     * texture space, figure out which if any of our textures have been
     * ejected, and update our global LRU.
     */
-
    for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
       DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
    }
-
-   if (dPriv && intel->lastStamp != dPriv->lastStamp) {
-      intelWindowMoved( intel );
-      intel->lastStamp = dPriv->lastStamp;
-   }
 }
 
+
 void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
@@ -583,12 +726,16 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
       intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
       ctx = &intel->ctx;
       if (ctx->Visual.doubleBufferMode) {
+         intelScreenPrivate *screen = intel->intelScreen;
         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
         if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
            intelPageFlip( dPriv );
         } else {
-           intelCopyBuffer( dPriv );
+            intelCopyBuffer( dPriv, NULL );
         }
+         if (screen->current_rotation != 0) {
+            intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
+         }
       }
    } else {
       /* XXX this shouldn't be an error but we can't handle it for now */
@@ -596,6 +743,29 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
    }
 }
 
+void intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
+                        int x, int y, int w, int h )
+{
+   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+      intelContextPtr intel;
+      GLcontext *ctx;
+      intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
+      ctx = &intel->ctx;
+      if (ctx->Visual.doubleBufferMode) {
+         intelScreenPrivate *screen = intel->intelScreen;
+        drm_clip_rect_t rect;
+        rect.x1 = x + dPriv->x;
+        rect.y1 = (dPriv->h - y - h) + dPriv->y;
+        rect.x2 = rect.x1 + w;
+        rect.y2 = rect.y1 + h;
+        _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
+        intelCopyBuffer( dPriv, &rect );
+      }
+   } else {
+      /* XXX this shouldn't be an error but we can't handle it for now */
+      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
+   }
+}
 
 void intelInitState( GLcontext *ctx )
 {
@@ -667,16 +837,27 @@ void intelInitState( GLcontext *ctx )
    ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
                        ctx->Scissor.Width, ctx->Scissor.Height );
    ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
-   ctx->Driver.StencilFunc( ctx, 
-                           ctx->Stencil.Function[0],
-                           ctx->Stencil.Ref[0],
-                           ctx->Stencil.ValueMask[0] );
-   ctx->Driver.StencilMask( ctx, ctx->Stencil.WriteMask[0] );
-   ctx->Driver.StencilOp( ctx, 
-                         ctx->Stencil.FailFunc[0],
-                         ctx->Stencil.ZFailFunc[0],
-                         ctx->Stencil.ZPassFunc[0]);
+   ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
+                                    ctx->Stencil.Function[0],
+                                    ctx->Stencil.Ref[0],
+                                    ctx->Stencil.ValueMask[0] );
+   ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
+                                    ctx->Stencil.Function[1],
+                                    ctx->Stencil.Ref[1],
+                                    ctx->Stencil.ValueMask[1] );
+   ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
+   ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
+   ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
+                                  ctx->Stencil.FailFunc[0],
+                                  ctx->Stencil.ZFailFunc[0],
+                                  ctx->Stencil.ZPassFunc[0]);
+   ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
+                                  ctx->Stencil.FailFunc[1],
+                                  ctx->Stencil.ZFailFunc[1],
+                                  ctx->Stencil.ZPassFunc[1]);
 
 
    ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
 }
+
+