util: Move DRI parse_debug_string() to util
[mesa.git] / src / mesa / drivers / dri / i915 / intel_context.c
index d25358b39a7e985358c0645c7cf5f664f59fe42f..3f429f25d105cb43b7c883ee4a1cb03479228fab 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2003 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "intel_mipmap_tree.h"
 
 #include "utils.h"
-#include "../glsl/ralloc.h"
+#include "util/debug.h"
+#include "util/ralloc.h"
 
-#ifndef INTEL_DEBUG
 int INTEL_DEBUG = (0);
-#endif
 
+const char *const i915_vendor_string = "Intel Open Source Technology Center";
+
+const char *
+i915_get_renderer_string(unsigned deviceID)
+{
+   const char *chipset;
+   static char buffer[128];
+
+   switch (deviceID) {
+#undef CHIPSET
+#define CHIPSET(id, symbol, str) case id: chipset = str; break;
+#include "pci_ids/i915_pci_ids.h"
+   default:
+      chipset = "Unknown Intel Chipset";
+      break;
+   }
+
+   (void) driGetRendererString(buffer, chipset, 0);
+   return buffer;
+}
 
 static const GLubyte *
 intelGetString(struct gl_context * ctx, GLenum name)
 {
    const struct intel_context *const intel = intel_context(ctx);
-   const char *chipset;
-   static char buffer[128];
 
    switch (name) {
    case GL_VENDOR:
-      return (GLubyte *) "Intel Open Source Technology Center";
-      break;
+      return (GLubyte *) i915_vendor_string;
 
    case GL_RENDERER:
-      switch (intel->intelScreen->deviceID) {
-#undef CHIPSET
-#define CHIPSET(id, symbol, str) case id: chipset = str; break;
-#include "pci_ids/i915_pci_ids.h"
-      default:
-         chipset = "Unknown Intel Chipset";
-         break;
-      }
-
-      (void) driGetRendererString(buffer, chipset, 0);
-      return (GLubyte *) buffer;
+      return
+         (GLubyte *) i915_get_renderer_string(intel->intelScreen->deviceID);
 
    default:
       return NULL;
    }
 }
 
+#define flushFront(screen)      ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer)
+
 static void
 intel_flush_front(struct gl_context *ctx)
 {
@@ -102,11 +111,10 @@ intel_flush_front(struct gl_context *ctx)
     __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
 
     if (intel->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      if (screen->dri2.loader->flushFrontBuffer != NULL &&
+      if (flushFront(screen) && 
           driDrawable &&
           driDrawable->loaderPrivate) {
-         screen->dri2.loader->flushFrontBuffer(driDrawable,
-                                               driDrawable->loaderPrivate);
+         flushFront(screen)(driDrawable, driDrawable->loaderPrivate);
 
         /* We set the dirty bit in intel_prepare_render() if we're
          * front buffer rendering once we get there.
@@ -116,6 +124,9 @@ intel_flush_front(struct gl_context *ctx)
    }
 }
 
+static void
+intel_update_image_buffers(struct intel_context *intel, __DRIdrawable *drawable);
+
 static unsigned
 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
 {
@@ -135,15 +146,58 @@ intel_process_dri2_buffer(struct intel_context *intel,
                          struct intel_renderbuffer *rb,
                          const char *buffer_name);
 
-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_dri2_buffers(struct intel_context *intel, __DRIdrawable *drawable)
 {
-   struct gl_framebuffer *fb = drawable->driverPrivate;
-   struct intel_renderbuffer *rb;
-   struct intel_context *intel = context->driverPrivate;
    __DRIbuffer *buffers = NULL;
    int i, count;
    const char *region_name;
+   struct intel_renderbuffer *rb;
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+
+   intel_query_dri2_buffers(intel, drawable, &buffers, &count);
+
+   if (buffers == NULL)
+      return;
+
+   for (i = 0; i < count; i++) {
+      switch (buffers[i].attachment) {
+      case __DRI_BUFFER_FRONT_LEFT:
+         rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+         region_name = "dri2 front buffer";
+         break;
+
+      case __DRI_BUFFER_FAKE_FRONT_LEFT:
+         rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+         region_name = "dri2 fake front buffer";
+         break;
+
+      case __DRI_BUFFER_BACK_LEFT:
+         rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+         region_name = "dri2 back buffer";
+         break;
+
+      case __DRI_BUFFER_DEPTH:
+      case __DRI_BUFFER_HIZ:
+      case __DRI_BUFFER_DEPTH_STENCIL:
+      case __DRI_BUFFER_STENCIL:
+      case __DRI_BUFFER_ACCUM:
+      default:
+         fprintf(stderr,
+                 "unhandled buffer attach event, attachment type %d\n",
+                 buffers[i].attachment);
+         return;
+      }
+
+      intel_process_dri2_buffer(intel, drawable, &buffers[i], rb, region_name);
+   }
+}
+
+void
+intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+{
+   struct intel_context *intel = context->driverPrivate;
+   __DRIscreen *screen = intel->intelScreen->driScrnPriv;
 
    /* 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
@@ -153,42 +207,10 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
    if (unlikely(INTEL_DEBUG & DEBUG_DRI))
       fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
 
-   intel_query_dri2_buffers(intel, drawable, &buffers, &count);
-
-   if (buffers == NULL)
-      return;
-
-   for (i = 0; i < count; i++) {
-       switch (buffers[i].attachment) {
-       case __DRI_BUFFER_FRONT_LEFT:
-          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-          region_name = "dri2 front buffer";
-          break;
-
-       case __DRI_BUFFER_FAKE_FRONT_LEFT:
-          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-          region_name = "dri2 fake front buffer";
-          break;
-
-       case __DRI_BUFFER_BACK_LEFT:
-          rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
-          region_name = "dri2 back buffer";
-          break;
-
-       case __DRI_BUFFER_DEPTH:
-       case __DRI_BUFFER_HIZ:
-       case __DRI_BUFFER_DEPTH_STENCIL:
-       case __DRI_BUFFER_STENCIL:
-       case __DRI_BUFFER_ACCUM:
-       default:
-          fprintf(stderr,
-                  "unhandled buffer attach event, attachment type %d\n",
-                  buffers[i].attachment);
-          return;
-       }
-
-       intel_process_dri2_buffer(intel, drawable, &buffers[i], rb, region_name);
-   }
+   if (screen->image.loader)
+      intel_update_image_buffers(intel, drawable);
+   else
+      intel_update_dri2_buffers(intel, drawable);
 
    driUpdateFramebufferSize(&intel->ctx, drawable);
 }
@@ -222,7 +244,7 @@ intel_prepare_render(struct intel_context *intel)
     * that will happen next will probably dirty the front buffer.  So
     * mark it as dirty here.
     */
-   if (intel->is_front_buffer_rendering)
+   if (_mesa_is_front_buffer_drawing(intel->ctx.DrawBuffer))
       intel->front_buffer_dirty = true;
 
    /* Wait for the swapbuffers before the one we just emitted, so we
@@ -250,13 +272,12 @@ intel_prepare_render(struct intel_context *intel)
 }
 
 static void
-intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+intel_noninvalidate_viewport(struct gl_context *ctx)
 {
     struct intel_context *intel = intel_context(ctx);
     __DRIcontext *driContext = intel->driContext;
 
-    if (intel->saved_viewport)
-       intel->saved_viewport(ctx, x, y, w, h);
+    intelCalcViewport(ctx);
 
     if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
        dri2InvalidateDrawable(driContext->driDrawablePriv);
@@ -264,7 +285,13 @@ intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
     }
 }
 
-static const struct dri_debug_control debug_control[] = {
+static void
+intel_viewport(struct gl_context *ctx)
+{
+    intelCalcViewport(ctx);
+}
+
+static const struct debug_control debug_control[] = {
    { "tex",   DEBUG_TEXTURE},
    { "state", DEBUG_STATE},
    { "blit",  DEBUG_BLIT},
@@ -330,7 +357,7 @@ intel_glFlush(struct gl_context *ctx)
 
    intel_flush(ctx);
    intel_flush_front(ctx);
-   if (intel->is_front_buffer_rendering)
+   if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer))
       intel->need_throttle = true;
 }
 
@@ -372,6 +399,7 @@ intelInitContext(struct intel_context *intel,
                  int api,
                  unsigned major_version,
                  unsigned minor_version,
+                 uint32_t flags,
                  const struct gl_config * mesaVis,
                  __DRIcontext * driContextPriv,
                  void *sharedContextPrivate,
@@ -383,31 +411,24 @@ intelInitContext(struct intel_context *intel,
    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    struct intel_screen *intelScreen = sPriv->driverPrivate;
    int bo_reuse_mode;
-   struct gl_config visual;
 
    /* Can't rely on invalidate events, fall back to glViewport hack */
-   if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
-      intel->saved_viewport = functions->Viewport;
+   if (!driContextPriv->driScreenPriv->dri2.useInvalidate)
+      functions->Viewport = intel_noninvalidate_viewport;
+   else
       functions->Viewport = intel_viewport;
-   }
-
-   if (mesaVis == NULL) {
-      memset(&visual, 0, sizeof visual);
-      mesaVis = &visual;
-   }
 
    intel->intelScreen = intelScreen;
 
    if (!_mesa_initialize_context(&intel->ctx, api, mesaVis, shareCtx,
                                  functions)) {
       *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
-      printf("%s: failed to init mesa context\n", __FUNCTION__);
+      printf("%s: failed to init mesa context\n", __func__);
       return false;
    }
 
    driContextPriv->driverPrivate = intel;
    intel->driContext = driContextPriv;
-   intel->driFd = sPriv->fd;
 
    intel->gen = intelScreen->gen;
 
@@ -454,8 +475,8 @@ intelInitContext(struct intel_context *intel,
 
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
-   ctx->Const.MaxLineWidth = 5.0;
-   ctx->Const.MaxLineWidthAA = 5.0;
+   ctx->Const.MaxLineWidth = 7.0;
+   ctx->Const.MaxLineWidthAA = 7.0;
    ctx->Const.LineWidthGranularity = 0.5;
 
    ctx->Const.MinPointSize = 1.0;
@@ -486,14 +507,13 @@ intelInitContext(struct intel_context *intel,
 
    _mesa_meta_init(ctx);
 
-   intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
    intel->hw_stipple = 1;
 
    intel->RenderIndex = ~0;
 
    intelInitExtensions(ctx);
 
-   INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
+   INTEL_DEBUG = parse_debug_string(getenv("INTEL_DEBUG"), debug_control);
    if (INTEL_DEBUG & DEBUG_BUFMGR)
       dri_bufmgr_set_debug(intel->bufmgr, true);
    if (INTEL_DEBUG & DEBUG_PERF)
@@ -681,8 +701,8 @@ intel_query_dri2_buffers(struct intel_context *intel,
    back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
 
    memset(attachments, 0, sizeof(attachments));
-   if ((intel->is_front_buffer_rendering ||
-       intel->is_front_buffer_reading ||
+   if ((_mesa_is_front_buffer_drawing(fb) ||
+        _mesa_is_front_buffer_reading(fb) ||
        !back_rb) && front_rb) {
       /* If a fake front buffer is in use, then querying for
        * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
@@ -781,3 +801,103 @@ intel_process_dri2_buffer(struct intel_context *intel,
                                                  region);
    intel_region_release(&region);
 }
+
+/**
+ * \brief Query DRI Image loader to obtain a DRIdrawable's buffers.
+ *
+ * To determine which DRI buffers to request, examine the renderbuffers
+ * attached to the drawable's framebuffer. Then request the buffers with
+ * dri3
+ *
+ * This is called from intel_update_renderbuffers().
+ *
+ * \param drawable      Drawable whose buffers are queried.
+ * \param buffers       [out] List of buffers returned by DRI2 query.
+ * \param buffer_count  [out] Number of buffers returned.
+ *
+ * \see intel_update_renderbuffers()
+ */
+
+static void
+intel_update_image_buffer(struct intel_context *intel,
+                          __DRIdrawable *drawable,
+                          struct intel_renderbuffer *rb,
+                          __DRIimage *buffer,
+                          enum __DRIimageBufferMask buffer_type)
+{
+   struct intel_region *region = buffer->region;
+
+   if (!rb || !region)
+      return;
+
+   unsigned num_samples = rb->Base.Base.NumSamples;
+
+   if (rb->mt &&
+       rb->mt->region &&
+       rb->mt->region == region)
+      return;
+
+   intel_miptree_release(&rb->mt);
+   rb->mt = intel_miptree_create_for_image_buffer(intel,
+                                                  buffer_type,
+                                                  intel_rb_format(rb),
+                                                  num_samples,
+                                                  region);
+}
+
+
+static void
+intel_update_image_buffers(struct intel_context *intel, __DRIdrawable *drawable)
+{
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+   __DRIscreen *screen = intel->intelScreen->driScrnPriv;
+   struct intel_renderbuffer *front_rb;
+   struct intel_renderbuffer *back_rb;
+   struct __DRIimageList images;
+   unsigned int format;
+   uint32_t buffer_mask = 0;
+
+   front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+   back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+
+   if (back_rb)
+      format = intel_rb_format(back_rb);
+   else if (front_rb)
+      format = intel_rb_format(front_rb);
+   else
+      return;
+
+   if (front_rb && (_mesa_is_front_buffer_drawing(fb) ||
+                    _mesa_is_front_buffer_reading(fb) || !back_rb)) {
+      buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
+   }
+
+   if (back_rb)
+      buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
+
+   (*screen->image.loader->getBuffers) (drawable,
+                                        driGLFormatToImageFormat(format),
+                                        &drawable->dri2.stamp,
+                                        drawable->loaderPrivate,
+                                        buffer_mask,
+                                        &images);
+
+   if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
+      drawable->w = images.front->width;
+      drawable->h = images.front->height;
+      intel_update_image_buffer(intel,
+                                drawable,
+                                front_rb,
+                                images.front,
+                                __DRI_IMAGE_BUFFER_FRONT);
+   }
+   if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
+      drawable->w = images.back->width;
+      drawable->h = images.back->height;
+      intel_update_image_buffer(intel,
+                                drawable,
+                                back_rb,
+                                images.back,
+                                __DRI_IMAGE_BUFFER_BACK);
+   }
+}