intel: Update renderbuffers unconditionally in intelSetTexBuffer2()
[mesa.git] / src / mesa / drivers / dri / intel / intel_clear.c
index 28281b38615d008ac08864bbc083497f719a9aeb..3c2211886606222d2a7ec33e14ce8bdc29dc4a57 100644 (file)
  **************************************************************************/
 
 #include "main/glheader.h"
-#include "main/enums.h"
-#include "main/image.h"
 #include "main/mtypes.h"
-#include "main/attrib.h"
-#include "main/blend.h"
-#include "main/bufferobj.h"
-#include "main/buffers.h"
-#include "main/depth.h"
-#include "main/enable.h"
-#include "main/macros.h"
-#include "main/matrix.h"
-#include "main/texstate.h"
-#include "main/shaders.h"
-#include "main/stencil.h"
-#include "main/varray.h"
-#include "glapi/dispatch.h"
 #include "swrast/swrast.h"
+#include "drivers/common/meta.h"
 
 #include "intel_context.h"
 #include "intel_blit.h"
-#include "intel_chipset.h"
 #include "intel_clear.h"
 #include "intel_fbo.h"
-#include "intel_pixel.h"
+#include "intel_regions.h"
 
 #define FILE_DEBUG_FLAG DEBUG_BLIT
 
-#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |                   \
-                             BUFFER_BIT_FRONT_LEFT |                   \
-                             BUFFER_BIT_COLOR0 |                       \
-                             BUFFER_BIT_COLOR1 |                       \
-                             BUFFER_BIT_COLOR2 |                       \
-                             BUFFER_BIT_COLOR3 |                       \
-                             BUFFER_BIT_COLOR4 |                       \
-                             BUFFER_BIT_COLOR5 |                       \
-                             BUFFER_BIT_COLOR6 |                       \
-                             BUFFER_BIT_COLOR7)
-
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering.  The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-void
-intel_clear_tris(GLcontext *ctx, GLbitfield mask)
-{
-   struct intel_context *intel = intel_context(ctx);
-   GLfloat vertices[4][3];
-   GLfloat color[4][4];
-   GLfloat dst_z;
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   int i;
-   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
-   GLuint saved_shader_program = 0;
-   unsigned int saved_active_texture;
-
-   assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
-                   BUFFER_BIT_STENCIL)) == 0);
-
-   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
-                   GL_CURRENT_BIT |
-                   GL_DEPTH_BUFFER_BIT |
-                   GL_ENABLE_BIT |
-                   GL_STENCIL_BUFFER_BIT |
-                   GL_TRANSFORM_BIT |
-                   GL_CURRENT_BIT);
-   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-   saved_active_texture = ctx->Texture.CurrentUnit;
-
-   /* Disable existing GL state we don't want to apply to a clear. */
-   _mesa_Disable(GL_ALPHA_TEST);
-   _mesa_Disable(GL_BLEND);
-   _mesa_Disable(GL_CULL_FACE);
-   _mesa_Disable(GL_FOG);
-   _mesa_Disable(GL_POLYGON_SMOOTH);
-   _mesa_Disable(GL_POLYGON_STIPPLE);
-   _mesa_Disable(GL_POLYGON_OFFSET_FILL);
-   _mesa_Disable(GL_LIGHTING);
-   _mesa_Disable(GL_CLIP_PLANE0);
-   _mesa_Disable(GL_CLIP_PLANE1);
-   _mesa_Disable(GL_CLIP_PLANE2);
-   _mesa_Disable(GL_CLIP_PLANE3);
-   _mesa_Disable(GL_CLIP_PLANE4);
-   _mesa_Disable(GL_CLIP_PLANE5);
-   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
-      saved_fp_enable = GL_TRUE;
-      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
-   }
-   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
-      saved_vp_enable = GL_TRUE;
-      _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
-   }
-   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
-      saved_shader_program = ctx->Shader.CurrentProgram->Name;
-      _mesa_UseProgramObjectARB(0);
-   }
-
-   if (ctx->Texture._EnabledUnits != 0) {
-      int i;
-
-      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-        _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
-        _mesa_Disable(GL_TEXTURE_1D);
-        _mesa_Disable(GL_TEXTURE_2D);
-        _mesa_Disable(GL_TEXTURE_3D);
-        if (ctx->Extensions.ARB_texture_cube_map)
-           _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
-        if (ctx->Extensions.NV_texture_rectangle)
-           _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
-        if (ctx->Extensions.MESA_texture_array) {
-           _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
-           _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
-        }
-      }
-   }
-
-   intel_meta_set_passthrough_transform(intel);
-
-   for (i = 0; i < 4; i++) {
-      color[i][0] = ctx->Color.ClearColor[0];
-      color[i][1] = ctx->Color.ClearColor[1];
-      color[i][2] = ctx->Color.ClearColor[2];
-      color[i][3] = ctx->Color.ClearColor[3];
-   }
-
-   /* convert clear Z from [0,1] to NDC coord in [-1,1] */
-   dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
-
-   /* Prepare the vertices, which are the same regardless of which buffer we're
-    * drawing to.
-    */
-   vertices[0][0] = fb->_Xmin;
-   vertices[0][1] = fb->_Ymin;
-   vertices[0][2] = dst_z;
-   vertices[1][0] = fb->_Xmax;
-   vertices[1][1] = fb->_Ymin;
-   vertices[1][2] = dst_z;
-   vertices[2][0] = fb->_Xmax;
-   vertices[2][1] = fb->_Ymax;
-   vertices[2][2] = dst_z;
-   vertices[3][0] = fb->_Xmin;
-   vertices[3][1] = fb->_Ymax;
-   vertices[3][2] = dst_z;
-
-   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
-   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
-   _mesa_Enable(GL_COLOR_ARRAY);
-   _mesa_Enable(GL_VERTEX_ARRAY);
-
-   while (mask != 0) {
-      GLuint this_mask = 0;
-      GLuint color_bit;
-
-      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
-      if (color_bit != 0)
-        this_mask |= (1 << (color_bit - 1));
-
-      /* Clear depth/stencil in the same pass as color. */
-      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
-
-      /* Select the current color buffer and use the color write mask if
-       * we have one, otherwise don't write any color channels.
-       */
-      if (this_mask & BUFFER_BIT_FRONT_LEFT)
-        _mesa_DrawBuffer(GL_FRONT_LEFT);
-      else if (this_mask & BUFFER_BIT_BACK_LEFT)
-        _mesa_DrawBuffer(GL_BACK_LEFT);
-      else if (color_bit != 0)
-        _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
-                         (color_bit - BUFFER_COLOR0 - 1));
-      else
-        _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-      /* Control writing of the depth clear value to depth. */
-      if (this_mask & BUFFER_BIT_DEPTH) {
-        _mesa_DepthFunc(GL_ALWAYS);
-        _mesa_Enable(GL_DEPTH_TEST);
-      } else {
-        _mesa_Disable(GL_DEPTH_TEST);
-        _mesa_DepthMask(GL_FALSE);
-      }
-
-      /* Control writing of the stencil clear value to stencil. */
-      if (this_mask & BUFFER_BIT_STENCIL) {
-        _mesa_Enable(GL_STENCIL_TEST);
-        _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-        _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
-                                  ctx->Stencil.WriteMask[0]);
-      } else {
-        _mesa_Disable(GL_STENCIL_TEST);
-      }
-
-      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
-
-      mask &= ~this_mask;
-   }
-
-   intel_meta_restore_transform(intel);
-
-   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
-   if (saved_fp_enable)
-      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
-   if (saved_vp_enable)
-      _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-
-   if (saved_shader_program)
-      _mesa_UseProgramObjectARB(saved_shader_program);
-
-   _mesa_PopClientAttrib();
-   _mesa_PopAttrib();
-}
-
 static const char *buffer_names[] = {
    [BUFFER_FRONT_LEFT] = "front",
    [BUFFER_BACK_LEFT] = "back",
@@ -268,13 +65,17 @@ static void
 intelClear(GLcontext *ctx, GLbitfield mask)
 {
    struct intel_context *intel = intel_context(ctx);
-   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
+   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask[0]);
    GLbitfield tri_mask = 0;
    GLbitfield blit_mask = 0;
    GLbitfield swrast_mask = 0;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLuint i;
 
+   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
+      intel->front_buffer_dirty = GL_TRUE;
+   }
+
    if (0)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
@@ -289,13 +90,17 @@ intelClear(GLcontext *ctx, GLbitfield mask)
       tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
    }
 
+   /* Make sure we have up to date buffers before we start looking at
+    * the tiling bits to determine how to clear. */
+   intel_prepare_render(intel);
+
    /* HW stencil */
    if (mask & BUFFER_BIT_STENCIL) {
       const struct intel_region *stencilRegion
          = intel_get_rb_region(fb, BUFFER_STENCIL);
       if (stencilRegion) {
          /* have hw stencil */
-         if (IS_965(intel->intelScreen->deviceID) ||
+         if (stencilRegion->tiling == I915_TILING_Y ||
             (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
            /* We have to use the 3D engine if we're clearing a partial mask
             * of the stencil buffer, or if we're on a 965 which has a tiled
@@ -312,9 +117,10 @@ intelClear(GLcontext *ctx, GLbitfield mask)
 
    /* HW depth */
    if (mask & BUFFER_BIT_DEPTH) {
+      const struct intel_region *irb = intel_get_rb_region(fb, BUFFER_DEPTH);
+
       /* clear depth with whatever method is used for stencil (see above) */
-      if (IS_965(intel->intelScreen->deviceID) ||
-         tri_mask & BUFFER_BIT_STENCIL)
+      if (irb->tiling == I915_TILING_Y || tri_mask & BUFFER_BIT_STENCIL)
          tri_mask |= BUFFER_BIT_DEPTH;
       else
          blit_mask |= BUFFER_BIT_DEPTH;
@@ -324,24 +130,34 @@ intelClear(GLcontext *ctx, GLbitfield mask)
     * buffer with it.
     */
    if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
-      int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
+      int color_bit = _mesa_ffs(mask & BUFFER_BITS_COLOR);
       if (color_bit != 0) {
         tri_mask |= blit_mask & (1 << (color_bit - 1));
         blit_mask &= ~(1 << (color_bit - 1));
       }
    }
 
+   if (intel->gen >= 6) {
+      /* Blits are in a different ringbuffer so we don't use them. */
+      tri_mask |= blit_mask;
+      blit_mask = 0;
+   }
+
    /* SW fallback clearing */
    swrast_mask = mask & ~tri_mask & ~blit_mask;
 
-   for (i = 0; i < BUFFER_COUNT; i++) {
-      GLuint bufBit = 1 << i;
-      if ((blit_mask | tri_mask) & bufBit) {
+   {
+      /* look for non-Intel renderbuffers (clear them with swrast) */
+      GLbitfield blit_or_tri = blit_mask | tri_mask;
+      while (blit_or_tri) {
+         GLuint i = _mesa_ffs(blit_or_tri) - 1;
+         GLbitfield bufBit = 1 << i;
          if (!fb->Attachment[i].Renderbuffer->ClassID) {
             blit_mask &= ~bufBit;
             tri_mask &= ~bufBit;
             swrast_mask |= bufBit;
          }
+         blit_or_tri ^= bufBit;
       }
    }
 
@@ -366,7 +182,8 @@ intelClear(GLcontext *ctx, GLbitfield mask)
         }
         DBG("\n");
       }
-      intel_clear_tris(ctx, tri_mask);
+
+      _mesa_meta_Clear(&intel->ctx, tri_mask);
    }
 
    if (swrast_mask) {