intel: Mark frontbuffer dirty in intel_prepare_render()
[mesa.git] / src / mesa / drivers / dri / intel / intel_context.c
index 0adee6131ed143353c9ebc2afd60c5cccacbae37..8a38ac12aa0d8dc7e1fd4f9f2a5c773b3d91ed79 100644 (file)
@@ -63,7 +63,7 @@ int INTEL_DEBUG = (0);
 #endif
 
 
-#define DRIVER_DATE                     "20091221 DEVELOPMENT"
+#define DRIVER_DATE                     "20100330 DEVELOPMENT"
 #define DRIVER_DATE_GEM                 "GEM " DRIVER_DATE
 
 
@@ -159,10 +159,10 @@ intelGetString(GLcontext * ctx, GLenum name)
          chipset = "Intel(R) B43";
          break;
       case PCI_CHIP_ILD_G:
-         chipset = "Intel(R) IGDNG_D";
+         chipset = "Intel(R) Ironlake Desktop";
          break;
       case PCI_CHIP_ILM_G:
-         chipset = "Intel(R) IGDNG_M";
+         chipset = "Intel(R) Ironlake Mobile";
          break;
       default:
          chipset = "Unknown Intel Chipset";
@@ -195,9 +195,22 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
    __DRIscreen *screen;
    int i, count;
    unsigned int attachments[10];
-   uint32_t name;
    const char *region_name;
 
+   /* If we're rendering to the fake front buffer, make sure all the
+    * pending drawing has landed on the real front buffer.  Otherwise
+    * when we eventually get to DRI2GetBuffersWithFormat the stale
+    * real front buffer contents will get copied to the new fake front
+    * buffer.
+    */
+   if (intel->is_front_buffer_rendering)
+      intel_flush(&intel->ctx, GL_FALSE);
+
+   /* Set this up front, so that in case our buffers get invalidated
+    * while we're getting new buffers, we don't clobber the stamp and
+    * thus ignore the invalidate. */
+   drawable->lastStamp = drawable->dri2.stamp;
+
    if (INTEL_DEBUG & DEBUG_DRI)
       fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
 
@@ -324,11 +337,8 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
        if (rb == NULL)
          continue;
 
-       if (rb->region) {
-         dri_bo_flink(rb->region->buffer, &name);
-         if (name == buffers[i].name)
+       if (rb->region && rb->region->name == buffers[i].name)
             continue;
-       }
 
        if (INTEL_DEBUG & DEBUG_DRI)
          fprintf(stderr,
@@ -352,7 +362,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
        if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
          depth_region = region;
 
-       intel_renderbuffer_set_region(rb, region);
+       intel_renderbuffer_set_region(intel, rb, region);
        intel_region_release(&region);
 
        if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
@@ -360,54 +370,61 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
          if (rb != NULL) {
             struct intel_region *stencil_region = NULL;
 
-            if (rb->region) {
-               dri_bo_flink(rb->region->buffer, &name);
-               if (name == buffers[i].name)
+            if (rb->region && rb->region->name == buffers[i].name)
                   continue;
-            }
 
             intel_region_reference(&stencil_region, region);
-            intel_renderbuffer_set_region(rb, stencil_region);
+            intel_renderbuffer_set_region(intel, rb, stencil_region);
             intel_region_release(&stencil_region);
          }
        }
    }
 
-   drawable->validBuffers = GL_TRUE;
    driUpdateFramebufferSize(&intel->ctx, drawable);
 }
 
+void
+intel_prepare_render(struct intel_context *intel)
+{
+   __DRIcontext *driContext = intel->driContext;
+   __DRIdrawable *drawable;
+
+   drawable = driContext->driDrawablePriv;
+   if (drawable->dri2.stamp != driContext->dri2.draw_stamp) {
+      if (drawable->lastStamp != drawable->dri2.stamp)
+        intel_update_renderbuffers(driContext, drawable);
+      intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
+      driContext->dri2.draw_stamp = drawable->dri2.stamp;
+   }
+
+   drawable = driContext->driReadablePriv;
+   if (drawable->dri2.stamp != driContext->dri2.read_stamp) {
+      if (drawable->lastStamp != drawable->dri2.stamp)
+        intel_update_renderbuffers(driContext, drawable);
+      driContext->dri2.read_stamp = drawable->dri2.stamp;
+   }
+
+   /* If we're currently rendering to the front buffer, the rendering
+    * that will happen next will probably dirty the front buffer.  So
+    * mark it as dirty here.
+    */
+   if (intel->is_front_buffer_rendering)
+      intel->front_buffer_dirty = GL_TRUE;
+}
+
 void
 intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
     struct intel_context *intel = intel_context(ctx);
     __DRIcontext *driContext = intel->driContext;
-    void (*old_viewport)(GLcontext *ctx, GLint x, GLint y,
-                        GLsizei w, GLsizei h);
-
-    if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
-       /* If we're rendering to the fake front buffer, make sure all the pending
-       * drawing has landed on the real front buffer.  Otherwise when we
-       * eventually get to DRI2GetBuffersWithFormat the stale real front
-       * buffer contents will get copied to the new fake front buffer.
-       */
-       if (intel->is_front_buffer_rendering) {
-         intel_flush(ctx, GL_FALSE);
-       }
 
-       intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
-       if (driContext->driDrawablePriv != driContext->driReadablePriv)
-         intel_update_renderbuffers(driContext, driContext->driReadablePriv);
+    if (!intel->using_dri2_swapbuffers &&
+       !intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
+       dri2InvalidateDrawable(driContext->driDrawablePriv);
+       dri2InvalidateDrawable(driContext->driReadablePriv);
     }
-
-    old_viewport = ctx->Driver.Viewport;
-    ctx->Driver.Viewport = NULL;
-    intel->driDrawable = driContext->driDrawablePriv;
-    intel_draw_buffer(ctx, intel->ctx.DrawBuffer);
-    ctx->Driver.Viewport = old_viewport;
 }
 
-
 static const struct dri_debug_control debug_control[] = {
    { "tex",   DEBUG_TEXTURE},
    { "state", DEBUG_STATE},
@@ -434,6 +451,7 @@ static const struct dri_debug_control debug_control[] = {
    { "sing",  DEBUG_SINGLE_THREAD },
    { "thre",  DEBUG_SINGLE_THREAD },
    { "wm",    DEBUG_WM },
+   { "glsl_force", DEBUG_GLSL_FORCE },
    { "urb",   DEBUG_URB },
    { "vs",    DEBUG_VS },
    { NULL,    0 }
@@ -461,6 +479,7 @@ void
 intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
 {
    struct intel_context *intel = intel_context(ctx);
+    __DRIcontext *driContext = intel->driContext;
 
    if (intel->Fallback)
       _swrast_flush(ctx);
@@ -477,19 +496,12 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
       if (screen->dri2.loader &&
           (screen->dri2.loader->base.version >= 2)
          && (screen->dri2.loader->flushFrontBuffer != NULL) &&
-          intel->driDrawable && intel->driDrawable->loaderPrivate) {
-        (*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable,
-                                                 intel->driDrawable->loaderPrivate);
-
-        /* Only clear the dirty bit if front-buffer rendering is no longer
-         * enabled.  This is done so that the dirty bit can only be set in
-         * glDrawBuffer.  Otherwise the dirty bit would have to be set at
-         * each of N places that do rendering.  This has worse performances,
-         * but it is much easier to get correct.
-         */
-        if (!intel->is_front_buffer_rendering) {
-           intel->front_buffer_dirty = GL_FALSE;
-        }
+          driContext->driDrawablePriv &&
+         driContext->driDrawablePriv->loaderPrivate) {
+        (*screen->dri2.loader->flushFrontBuffer)(driContext->driDrawablePriv,
+                                                 driContext->driDrawablePriv->loaderPrivate);
+
+        intel->front_buffer_dirty = GL_FALSE;
       }
    }
 }
@@ -573,6 +585,7 @@ intelInitDriverFunctions(struct dd_function_table *functions)
 
 GLboolean
 intelInitContext(struct intel_context *intel,
+                int api,
                  const __GLcontextModes * mesaVis,
                  __DRIcontext * driContextPriv,
                  void *sharedContextPrivate,
@@ -581,23 +594,38 @@ intelInitContext(struct intel_context *intel,
    GLcontext *ctx = &intel->ctx;
    GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
-   intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
+   struct intel_screen *intelScreen = sPriv->private;
    int bo_reuse_mode;
 
-   if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx,
-                                 functions, (void *) intel)) {
-      _mesa_printf("%s: failed to init mesa context\n", __FUNCTION__);
+   /* we can't do anything without a connection to the device */
+   if (intelScreen->bufmgr == NULL)
+      return GL_FALSE;
+
+   if (!_mesa_initialize_context_for_api(&intel->ctx, api, mesaVis, shareCtx,
+                                        functions, (void *) intel)) {
+      printf("%s: failed to init mesa context\n", __FUNCTION__);
       return GL_FALSE;
    }
 
    driContextPriv->driverPrivate = intel;
    intel->intelScreen = intelScreen;
-   intel->driScreen = sPriv;
    intel->driContext = driContextPriv;
    intel->driFd = sPriv->fd;
 
-   if (IS_965(intel->intelScreen->deviceID)) {
+   if (IS_GEN6(intel->intelScreen->deviceID)) {
+      intel->gen = 6;
+      intel->needs_ff_sync = GL_TRUE;
+      intel->has_luminance_srgb = GL_TRUE;
+   } else if (IS_GEN5(intel->intelScreen->deviceID)) {
+      intel->gen = 5;
+      intel->needs_ff_sync = GL_TRUE;
+      intel->has_luminance_srgb = GL_TRUE;
+   } else if (IS_965(intel->intelScreen->deviceID)) {
       intel->gen = 4;
+      if (IS_G4X(intel->intelScreen->deviceID)) {
+         intel->has_luminance_srgb = GL_TRUE;
+         intel->is_g4x = GL_TRUE;
+      }
    } else if (IS_9XX(intel->intelScreen->deviceID)) {
       intel->gen = 3;
       if (IS_945(intel->intelScreen->deviceID)) {
@@ -607,18 +635,8 @@ intelInitContext(struct intel_context *intel,
       intel->gen = 2;
    }
 
-   if (IS_IGDNG(intel->intelScreen->deviceID)) {
-      intel->is_ironlake = GL_TRUE;
-      intel->needs_ff_sync = GL_TRUE;
-      intel->has_luminance_srgb = GL_TRUE;
-   } else if (IS_G4X(intel->intelScreen->deviceID)) {
-      intel->has_luminance_srgb = GL_TRUE;
-      intel->is_g4x = GL_TRUE;
-   }
-
    driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
-                       intel->driScreen->myNum,
-                      (intel->gen >= 4) ? "i965" : "i915");
+                       sPriv->myNum, (intel->gen >= 4) ? "i965" : "i915");
    if (intelScreen->deviceID == PCI_CHIP_I865_G)
       intel->maxBatchSize = 4096;
    else
@@ -718,13 +736,17 @@ intelInitContext(struct intel_context *intel,
 
    intel->RenderIndex = ~0;
 
-   if (intel->gen >= 4 && !intel->intelScreen->irq_active) {
-      _mesa_printf("IRQs not active.  Exiting\n");
-      exit(1);
+   switch (ctx->API) {
+   case API_OPENGL:
+      intelInitExtensions(ctx);
+      break;
+   case API_OPENGLES:
+      break;
+   case API_OPENGLES2:
+      intelInitExtensionsES2(ctx);
+      break;
    }
 
-   intelInitExtensions(ctx);
-
    INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
    if (INTEL_DEBUG & DEBUG_BUFMGR)
       dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
@@ -742,12 +764,6 @@ intelInitContext(struct intel_context *intel,
    }
    intel->use_texture_tiling = driQueryOptionb(&intel->optionCache,
                                               "texture_tiling");
-   if (intel->use_texture_tiling &&
-       !intel->intelScreen->kernel_exec_fencing) {
-      fprintf(stderr, "No kernel support for execution fencing, "
-             "disabling texture tiling\n");
-      intel->use_texture_tiling = GL_FALSE;
-   }
    intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
 
    intel->prim.primitive = ~0;
@@ -837,14 +853,6 @@ intelDestroyContext(__DRIcontext * driContextPriv)
 GLboolean
 intelUnbindContext(__DRIcontext * driContextPriv)
 {
-   struct intel_context *intel =
-      (struct intel_context *) driContextPriv->driverPrivate;
-
-   /* Deassociate the context with the drawables.
-    */
-   intel->driDrawable = NULL;
-   intel->driReadDrawable = NULL;
-
    return GL_TRUE;
 }
 
@@ -872,22 +880,11 @@ intelMakeCurrent(__DRIcontext * driContextPriv,
    if (driContextPriv) {
       struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
       struct gl_framebuffer *readFb = driReadPriv->driverPrivate;
-      intel_update_renderbuffers(driContextPriv, driDrawPriv);
-      if (driDrawPriv != driReadPriv)
-        intel_update_renderbuffers(driContextPriv, driReadPriv);
-
-      /* set GLframebuffer size to match window, if needed */
-      driUpdateFramebufferSize(&intel->ctx, driDrawPriv);
-
-      if (driReadPriv != driDrawPriv) {
-        driUpdateFramebufferSize(&intel->ctx, driReadPriv);
-      }
 
+      driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
+      driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
+      intel_prepare_render(intel);
       _mesa_make_current(&intel->ctx, fb, readFb);
-      intel->driReadDrawable = driReadPriv;
-      intel->driDrawable = driDrawPriv;
-      intel_draw_buffer(&intel->ctx, fb);
    }
    else {
       _mesa_make_current(NULL, NULL, NULL);