dri/nouveau: Enable NV_fog_distance on NV10 and NV20 hardware
[mesa.git] / src / mesa / drivers / dri / intel / intel_fbo.c
index 1669af2c2a7e1d25b2171974b5d728cfa1cf9288..4537f1fb97b1b1ce0a6e6ca4d4ac00ae8b12280e 100644 (file)
@@ -173,6 +173,9 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
 
    if (irb->Base.Format == MESA_FORMAT_S8) {
       /*
+       * The stencil buffer is W tiled. However, we request from the kernel a
+       * non-tiled buffer because the GTT is incapable of W fencing.
+       *
        * The stencil buffer has quirky pitch requirements.  From Vol 2a,
        * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
        *    The pitch must be set to 2x the value computed based on width, as
@@ -180,15 +183,14 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
        * To accomplish this, we resort to the nasty hack of doubling the drm
        * region's cpp and halving its height.
        *
-       * If we neglect to double the pitch, then drm_intel_gem_bo_map_gtt()
-       * maps the memory incorrectly.
+       * If we neglect to double the pitch, then render corruption occurs.
        */
       irb->region = intel_region_alloc(intel->intelScreen,
-                                      I915_TILING_Y,
+                                      I915_TILING_NONE,
                                       cpp * 2,
-                                      width,
-                                      height / 2,
-                                      GL_TRUE);
+                                      ALIGN(width, 64),
+                                      ALIGN((height + 1) / 2, 64),
+                                      true);
       if (!irb->region)
        return false;
 
@@ -228,7 +230,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
 
    } else {
       irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp,
-                                      width, height, GL_TRUE);
+                                      width, height, true);
       if (!irb->region)
         return false;
 
@@ -238,7 +240,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
                                              irb->region->cpp,
                                              irb->region->width,
                                              irb->region->height,
-                                             GL_TRUE);
+                                             true);
         if (!irb->hiz_region) {
            intel_region_release(&irb->region);
            return false;
@@ -246,7 +248,7 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
       }
    }
 
-   return GL_TRUE;
+   return true;
 }
 
 
@@ -267,6 +269,17 @@ intel_image_target_renderbuffer_storage(struct gl_context *ctx,
    if (image == NULL)
       return;
 
+   /* __DRIimage is opaque to the core so it has to be checked here */
+   switch (image->format) {
+   case MESA_FORMAT_RGBA8888_REV:
+      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
+            "glEGLImageTargetRenderbufferStorage(unsupported image format");
+      return;
+      break;
+   default:
+      break;
+   }
+
    irb = intel_renderbuffer(rb);
    intel_region_reference(&irb->region, image->region);
 
@@ -294,7 +307,7 @@ intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
    rb->Height = height;
    rb->InternalFormat = internalFormat;
 
-   return GL_TRUE;
+   return true;
 }
 
 
@@ -306,7 +319,7 @@ intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
 
    _mesa_resize_framebuffer(ctx, fb, width, height);
 
-   fb->Initialized = GL_TRUE; /* XXX remove someday */
+   fb->Initialized = true; /* XXX remove someday */
 
    if (fb->Name != 0) {
       return;
@@ -331,7 +344,7 @@ intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
                         GLenum internalFormat, GLuint width, GLuint height)
 {
    _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
-   return GL_FALSE;
+   return false;
 }
 
 /**
@@ -435,7 +448,7 @@ intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
                        struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
 {
    if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
-      intel_draw_buffer(ctx, fb);
+      intel_draw_buffer(ctx);
    }
    else {
       /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
@@ -456,7 +469,7 @@ intel_framebuffer_renderbuffer(struct gl_context * ctx,
    intel_flush(ctx);
 
    _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
-   intel_draw_buffer(ctx, fb);
+   intel_draw_buffer(ctx);
 }
 
 static bool
@@ -464,27 +477,30 @@ intel_update_tex_wrapper_regions(struct intel_context *intel,
                                 struct intel_renderbuffer *irb,
                                 struct intel_texture_image *intel_image);
 
-static GLboolean
+static bool
 intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, 
                     struct gl_texture_image *texImage)
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_texture_image *intel_image = intel_texture_image(texImage);
+   int width, height, depth;
 
    if (!intel_span_supports_format(texImage->TexFormat)) {
       DBG("Render to texture BAD FORMAT %s\n",
          _mesa_get_format_name(texImage->TexFormat));
-      return GL_FALSE;
+      return false;
    } else {
       DBG("Render to texture %s\n", _mesa_get_format_name(texImage->TexFormat));
    }
 
+   intel_miptree_get_dimensions_for_image(texImage, &width, &height, &depth);
+
    irb->Base.Format = texImage->TexFormat;
    irb->Base.DataType = intel_mesa_format_to_rb_datatype(texImage->TexFormat);
    irb->Base.InternalFormat = texImage->InternalFormat;
    irb->Base._BaseFormat = _mesa_base_tex_format(ctx, irb->Base.InternalFormat);
-   irb->Base.Width = texImage->Width;
-   irb->Base.Height = texImage->Height;
+   irb->Base.Width = width;
+   irb->Base.Height = height;
 
    irb->Base.Delete = intel_delete_renderbuffer;
    irb->Base.AllocStorage = intel_nop_alloc_storage;
@@ -505,17 +521,12 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
 
       /* The tex image shares its embedded depth and stencil renderbuffers with
        * the renderbuffer wrapper. */
-      if (irb->wrapped_depth != intel_image->depth_rb) {
-        _mesa_reference_renderbuffer(&irb->wrapped_depth,
-                                     intel_image->depth_rb);
-      }
-      if (irb->wrapped_stencil != intel_image->stencil_rb) {
-        _mesa_reference_renderbuffer(&irb->wrapped_stencil,
-                                     intel_image->stencil_rb);
-      }
+      _mesa_reference_renderbuffer(&irb->wrapped_depth,
+                                  intel_image->depth_rb);
+      _mesa_reference_renderbuffer(&irb->wrapped_stencil,
+                                  intel_image->stencil_rb);
 
       return true;
-
    } else {
       return intel_update_tex_wrapper_regions(intel, irb, intel_image);
    }
@@ -546,9 +557,9 @@ intel_update_tex_wrapper_regions(struct intel_context *intel,
                             _mesa_get_format_bytes(rb->Format),
                             rb->Width,
                             rb->Height,
-                            GL_TRUE);
+                            true);
       if (!intel_image->mt->hiz_region)
-         return GL_FALSE;
+         return false;
    }
 
    /* Point the renderbuffer's hiz region to the texture's hiz region. */
@@ -556,7 +567,7 @@ intel_update_tex_wrapper_regions(struct intel_context *intel,
       intel_region_reference(&irb->hiz_region, intel_image->mt->hiz_region);
    }
 
-   return GL_TRUE;
+   return true;
 }
 
 
@@ -594,17 +605,15 @@ intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
                                   struct intel_texture_image *intel_image,
                                   int zoffset)
 {
-   struct intel_mipmap_tree *mt = intel_image->mt;
    unsigned int dst_x, dst_y;
 
    /* compute offset of the particular 2D image within the texture region */
    intel_miptree_get_image_offset(intel_image->mt,
-                                 intel_image->level,
-                                 intel_image->face,
+                                 intel_image->base.Base.Level,
+                                 intel_image->base.Base.Face,
                                  zoffset,
                                  &dst_x, &dst_y);
 
-   irb->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp;
    irb->draw_x = dst_x;
    irb->draw_y = dst_y;
 }
@@ -645,6 +654,22 @@ intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
    }
 }
 
+#ifndef I915
+static bool
+need_tile_offset_workaround(struct brw_context *brw,
+                           struct intel_renderbuffer *irb)
+{
+   uint32_t tile_x, tile_y;
+
+   if (brw->has_surface_tile_offset)
+      return false;
+
+   intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
+
+   return tile_x != 0 || tile_y != 0;
+}
+#endif
+
 /**
  * Called by glFramebufferTexture[123]DEXT() (and other places) to
  * prepare for rendering into texture memory.  This might be called
@@ -695,11 +720,10 @@ intel_render_texture(struct gl_context * ctx,
        irb->Base.RefCount);
 
    intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
-   intel_image->used_as_render_target = GL_TRUE;
+   intel_image->used_as_render_target = true;
 
 #ifndef I915
-   if (!brw_context(ctx)->has_surface_tile_offset &&
-       (irb->draw_offset & 4095) != 0) {
+   if (need_tile_offset_workaround(brw_context(ctx), irb)) {
       /* Original gen4 hardware couldn't draw to a non-tile-aligned
        * destination in a miptree unless you actually setup your
        * renderbuffer as a miptree and used the fragile
@@ -708,33 +732,27 @@ intel_render_texture(struct gl_context * ctx,
        * into that.
        */
       struct intel_context *intel = intel_context(ctx);
-      struct intel_mipmap_tree *old_mt = intel_image->mt;
       struct intel_mipmap_tree *new_mt;
+      int width, height, depth;
+
+      intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
 
       new_mt = intel_miptree_create(intel, image->TexObject->Target,
-                                   intel_image->base.TexFormat,
-                                   intel_image->level,
-                                   intel_image->level,
-                                   intel_image->base.Width,
-                                   intel_image->base.Height,
-                                   intel_image->base.Depth,
-                                   GL_TRUE);
-
-      intel_miptree_image_copy(intel,
-                               new_mt,
-                               intel_image->face,
-                              intel_image->level,
-                              old_mt);
-
-      intel_miptree_release(intel, &intel_image->mt);
-      intel_image->mt = new_mt;
+                                   intel_image->base.Base.TexFormat,
+                                   intel_image->base.Base.Level,
+                                   intel_image->base.Base.Level,
+                                    width, height, depth,
+                                   true);
+
+      intel_miptree_copy_teximage(intel, intel_image, new_mt);
       intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
 
       intel_region_reference(&irb->region, intel_image->mt->region);
+      intel_miptree_release(&new_mt);
    }
 #endif
    /* update drawing region, etc */
-   intel_draw_buffer(ctx, fb);
+   intel_draw_buffer(ctx);
 }
 
 
@@ -756,7 +774,7 @@ intel_finish_render_texture(struct gl_context * ctx,
 
    /* Flag that this image may now be validated into the object's miptree. */
    if (intel_image)
-      intel_image->used_as_render_target = GL_FALSE;
+      intel_image->used_as_render_target = false;
 
    /* Since we've (probably) rendered to the texture and will (likely) use
     * it in the texture domain later on in this batchbuffer, flush the
@@ -783,22 +801,21 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
     * The depth and stencil renderbuffers are the same renderbuffer or wrap
     * the same texture.
     */
-   bool depth_stencil_are_same;
-   if (depthRb && stencilRb && depthRb == stencilRb)
-      depth_stencil_are_same = true;
-   else if (depthRb && stencilRb && depthRb != stencilRb
-           && (fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE)
-           && (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE)
-           && (fb->Attachment[BUFFER_DEPTH].Texture->Name
-               == fb->Attachment[BUFFER_STENCIL].Texture->Name))
-      depth_stencil_are_same = true;
-   else
-      depth_stencil_are_same = false;
-
-   if (!intel->has_separate_stencil
-       && depthRb && stencilRb
-       && !depth_stencil_are_same) {
-      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+   if (depthRb && stencilRb) {
+      bool depth_stencil_are_same;
+      if (depthRb == stencilRb)
+        depth_stencil_are_same = true;
+      else if ((fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) &&
+              (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) &&
+              (fb->Attachment[BUFFER_DEPTH].Texture->Name ==
+               fb->Attachment[BUFFER_STENCIL].Texture->Name))
+        depth_stencil_are_same = true;
+      else
+        depth_stencil_are_same = false;
+
+      if (!intel->has_separate_stencil && !depth_stencil_are_same) {
+        fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+      }
    }
 
    for (i = 0; i < Elements(fb->Attachment); i++) {
@@ -878,11 +895,9 @@ intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
 
          struct gl_texture_image *texImage =
             _mesa_select_tex_image(ctx, texObj, target, dstLevel);
-         GLenum internalFormat = texImage->InternalFormat;
 
-         if (intel_copy_texsubimage(intel_context(ctx), target,
+         if (intel_copy_texsubimage(intel_context(ctx),
                                     intel_texture_image(texImage),
-                                    internalFormat,
                                     dstX0, dstY0,
                                     srcX0, srcY0,
                                     srcX1 - srcX0, /* width */