Merge branch 'mesa_7_6_branch' into mesa_7_7_branch
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm.c
index 14e05be4f6c042eea668eaad9dcba294f513a442..6895f644104a6e0be24507fa6447aebbce2c5625 100644 (file)
@@ -29,7 +29,6 @@
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
              
-#include "main/texformat.h"
 #include "brw_context.h"
 #include "brw_util.h"
 #include "brw_wm.h"
@@ -41,13 +40,13 @@ GLuint brw_wm_nr_args( GLuint opcode )
 {
    switch (opcode) {
    case WM_FRONTFACING:
-      return 0;
    case WM_PIXELXY:
+      return 0;
    case WM_CINTERP:
    case WM_WPOSXY:
+   case WM_DELTAXY:
       return 1;
    case WM_LINTERP:
-   case WM_DELTAXY:
    case WM_PIXELW:
       return 2;
    case WM_FB_WRITE:
@@ -153,8 +152,21 @@ static void do_wm_prog( struct brw_context *brw,
           */
          return;
       }
+      c->instruction = _mesa_calloc(BRW_WM_MAX_INSN * sizeof(*c->instruction));
+      c->prog_instructions = _mesa_calloc(BRW_WM_MAX_INSN *
+                                         sizeof(*c->prog_instructions));
+      c->vreg = _mesa_calloc(BRW_WM_MAX_VREG * sizeof(*c->vreg));
+      c->refs = _mesa_calloc(BRW_WM_MAX_REF * sizeof(*c->refs));
    } else {
+      void *instruction = c->instruction;
+      void *prog_instructions = c->prog_instructions;
+      void *vreg = c->vreg;
+      void *refs = c->refs;
       memset(c, 0, sizeof(*brw->wm.compile_data));
+      c->instruction = instruction;
+      c->prog_instructions = prog_instructions;
+      c->vreg = vreg;
+      c->refs = refs;
    }
    memcpy(&c->key, key, sizeof(*key));
 
@@ -171,9 +183,11 @@ static void do_wm_prog( struct brw_context *brw,
     * differently from "simple" shaders.
     */
    if (fp->isGLSL) {
+      c->dispatch_width = 8;
       brw_wm_glsl_emit(brw, c);
    }
    else {
+      c->dispatch_width = 16;
       brw_wm_non_glsl_emit(brw, c);
    }
 
@@ -202,6 +216,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    /* BRW_NEW_FRAGMENT_PROGRAM */
    const struct brw_fragment_program *fp = 
       (struct brw_fragment_program *)brw->fragment_program;
+   GLboolean uses_depth = (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
    GLuint lookup = 0;
    GLuint line_aa;
    GLuint i;
@@ -215,7 +230,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
        ctx->Color.AlphaEnabled)
       lookup |= IZ_PS_KILL_ALPHATEST_BIT;
 
-   if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPTH))
+   if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
       lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
 
    /* _NEW_DEPTH */
@@ -263,6 +278,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
         
    brw_wm_lookup_iz(line_aa,
                    lookup,
+                   uses_depth,
                    key);
 
 
@@ -284,7 +300,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
          const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
         if (img->InternalFormat == GL_YCBCR_MESA) {
            key->yuvtex_mask |= 1 << i;
-           if (img->TexFormat->MesaFormat == MESA_FORMAT_YCBCR)
+           if (img->TexFormat == MESA_FORMAT_YCBCR)
                key->yuvtex_swap_mask |= 1 << i;
         }
 
@@ -305,6 +321,9 @@ static void brw_wm_populate_key( struct brw_context *brw,
     * from the incoming screen origin relative position we get as part of our
     * payload.
     *
+    * This is only needed for the WM_WPOSXY opcode when the fragment program
+    * uses the gl_FragCoord input.
+    *
     * We could avoid recompiling by including this as a constant referenced by
     * our program, but if we were to do that it would also be nice to handle
     * getting that constant updated at batchbuffer submit time (when we
@@ -313,17 +332,21 @@ static void brw_wm_populate_key( struct brw_context *brw,
     * just avoid using this as key data if the program doesn't use
     * fragment.position.
     *
-    * This pretty much becomes moot with DRI2 and redirected buffers anyway,
-    * as our origins will always be zero then.
+    * For DRI2 the origin_x/y will always be (0,0) but we still need the
+    * drawable height in order to invert the Y axis.
     */
-   if (brw->intel.driDrawable != NULL) {
-      key->origin_x = brw->intel.driDrawable->x;
-      key->origin_y = brw->intel.driDrawable->y;
-      key->drawable_height = brw->intel.driDrawable->h;
+   if (fp->program.Base.InputsRead & FRAG_BIT_WPOS) {
+      if (brw->intel.driDrawable != NULL) {
+         key->origin_x = brw->intel.driDrawable->x;
+         key->origin_y = brw->intel.driDrawable->y;
+         key->drawable_height = brw->intel.driDrawable->h;
+      }
    }
 
+   key->nr_color_regions = brw->state.nr_color_regions;
+
    /* CACHE_NEW_VS_PROG */
-   key->vp_outputs_written = brw->vs.prog_data->outputs_written & DO_SETUP_BITS;
+   key->vp_outputs_written = brw->vs.prog_data->outputs_written;
 
    /* The unique fragment program ID */
    key->program_string_id = fp->id;