Merge branch 'mesa_7_5_branch'
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fallback.c
index 4ea660a51a37a5ab8e17da8d64b0f4fab9d93572..d27c6c24ca50258d647484846fc1f4a6d62891fa 100644 (file)
@@ -37,6 +37,9 @@
 #include "tnl/tnl.h"
 #include "brw_context.h"
 #include "brw_fallback.h"
+#include "intel_chipset.h"
+#include "intel_fbo.h"
+#include "intel_regions.h"
 
 #include "glapi/glapi.h"
 
 
 static GLboolean do_check_fallback(struct brw_context *brw)
 {
+   struct intel_context *intel = &brw->intel;
    GLcontext *ctx = &brw->intel.ctx;
    GLuint i;
 
-   /* BRW_NEW_METAOPS
-    */
-   if (brw->metaops.active)
-      return GL_FALSE;
-
    if (brw->intel.no_rast) {
       DBG("FALLBACK: rasterization disabled\n");
       return GL_TRUE;
    }
 
    /* _NEW_RENDERMODE
-    *
-    * XXX: need to save/restore RenderMode in metaops state, or
-    * somehow move to a new attribs pointer:
     */
    if (ctx->RenderMode != GL_RENDER) {
       DBG("FALLBACK: render mode\n");
@@ -70,7 +66,7 @@ static GLboolean do_check_fallback(struct brw_context *brw)
    /* _NEW_TEXTURE:
     */
    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
-      struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
       if (texUnit->_ReallyEnabled) {
         struct intel_texture_object *intelObj = intel_texture_object(texUnit->_Current);
         struct gl_texture_image *texImage = intelObj->base.Image[0][intelObj->firstLevel];
@@ -83,12 +79,39 @@ static GLboolean do_check_fallback(struct brw_context *brw)
    
    /* _NEW_STENCIL 
     */
-   if (brw->attribs.Stencil->Enabled && 
-       !brw->intel.hw_stencil) {
+   if (ctx->Stencil._Enabled &&
+       (ctx->DrawBuffer->Name == 0 && !brw->intel.hw_stencil)) {
       DBG("FALLBACK: stencil\n");
       return GL_TRUE;
    }
 
+   /* _NEW_BUFFERS */
+   if (IS_965(intel->intelScreen->deviceID) &&
+       !IS_G4X(intel->intelScreen->deviceID)) {
+      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+        struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+        struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+        /* The original gen4 hardware couldn't set up WM surfaces pointing
+         * at an offset within a tile, which can happen when rendering to
+         * anything but the base level of a texture or the +X face/0 depth.
+         * This was fixed with the 4 Series hardware.
+         *
+         * For these original chips, you would have to make the depth and
+         * color destination surfaces include information on the texture
+         * type, LOD, face, and various limits to use them as a destination.
+         * I would have done this, but there's also a nasty requirement that
+         * the depth and the color surfaces all be of the same LOD, which
+         * may be a worse requirement than this alignment.  (Also, we may
+         * want to just demote the texture to untiled, instead).
+         */
+        if (irb->region && irb->region->tiling != I915_TILING_NONE &&
+            (irb->region->draw_offset & 4095)) {
+           DBG("FALLBACK: non-tile-aligned destination for tiled FBO\n");
+           return GL_TRUE;
+        }
+      }
+   }
 
    return GL_FALSE;
 }
@@ -101,7 +124,7 @@ static void check_fallback(struct brw_context *brw)
 const struct brw_tracked_state brw_check_fallback = {
    .dirty = {
       .mesa = _NEW_BUFFERS | _NEW_RENDERMODE | _NEW_TEXTURE | _NEW_STENCIL,
-      .brw  = BRW_NEW_METAOPS,
+      .brw  = 0,
       .cache = 0
    },
    .prepare = check_fallback