Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / gallium / drivers / cell / spu / spu_tri.c
index be9624cf7d9e2fc43c69cccbf34e2230aef56d1a..17e337bbdf6e05d3adae6077fec1ad6be65cf930 100644 (file)
  * Triangle rendering within a tile.
  */
 
+#include <transpose_matrix4x4.h>
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
 #include "pipe/p_util.h"
-#include "spu_blend.h"
 #include "spu_colorpack.h"
 #include "spu_main.h"
 #include "spu_texture.h"
 #include "spu_tile.h"
 #include "spu_tri.h"
-
-#include "spu_ztest.h"
+#include "spu_per_fragment_op.h"
 
 
 /** Masks are uint[4] vectors with each element being 0 or 0xffffffff */
@@ -262,18 +261,17 @@ do_depth_test(int x, int y, mask_t quadmask)
    float4 zvals;
    mask_t mask;
 
+   if (spu.fb.depth_format == PIPE_FORMAT_NONE)
+      return quadmask;
+
    zvals.v = eval_z((float) x, (float) y);
 
-   if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
-      int ix = (x - setup.cliprect_minx) / 4;
-      int iy = (y - setup.cliprect_miny) / 2;
-      mask = spu_z16_test_less(zvals.v, &spu.ztile.us8[iy][ix], x>>1, quadmask);
-   }
-   else {
-      int ix = (x - setup.cliprect_minx) / 2;
-      int iy = (y - setup.cliprect_miny) / 2;
-      mask = spu_z32_test_less(zvals.v, &spu.ztile.ui4[iy][ix], quadmask);
-   }
+   mask = (mask_t) spu_do_depth_stencil(x - setup.cliprect_minx,
+                                       y - setup.cliprect_miny,
+                                       (qword) quadmask, 
+                                       (qword) zvals.v,
+                                       (qword) spu_splats((unsigned char) 0x0ffu),
+                                       (qword) spu_splats((unsigned int) 0x01u));
 
    if (spu_extract(spu_orx(mask), 0))
       spu.cur_ztile_status = TILE_STATUS_DIRTY;
@@ -299,7 +297,7 @@ emit_quad( int x, int y, mask_t mask )
    sp->quad.first->run(sp->quad.first, &setup.quad);
 #else
 
-   if (spu.depth_stencil.depth.enabled) {
+   if (spu.read_depth) {
       mask = do_depth_test(x, y, mask);
    }
 
@@ -307,12 +305,11 @@ emit_quad( int x, int y, mask_t mask )
    if (spu_extract(spu_orx(mask), 0)) {
       const int ix = x - setup.cliprect_minx;
       const int iy = y - setup.cliprect_miny;
-      const vector unsigned char shuffle = spu.color_shuffle;
       vector float colors[4];
 
       spu.cur_ctile_status = TILE_STATUS_DIRTY;
 
-      if (spu.texture.start) {
+      if (spu.texture[0].start) {
          /* texture mapping */
          vector float texcoords[4];
          eval_coeff(2, (float) x, (float) y, texcoords);
@@ -331,27 +328,55 @@ emit_quad( int x, int y, mask_t mask )
          eval_coeff(1, (float) x, (float) y, colors);
       }
 
-#if 1
-      if (spu.blend.blend_enable)
-         blend_quad(ix % TILE_SIZE, iy % TILE_SIZE, colors);
-#endif
 
-      if (spu_extract(mask, 0))
-         spu.ctile.ui[iy][ix] = spu_pack_color_shuffle(colors[0], shuffle);
-      if (spu_extract(mask, 1))
-         spu.ctile.ui[iy][ix+1] = spu_pack_color_shuffle(colors[1], shuffle);
-      if (spu_extract(mask, 2))
-         spu.ctile.ui[iy+1][ix] = spu_pack_color_shuffle(colors[2], shuffle);
-      if (spu_extract(mask, 3))
-         spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(colors[3], shuffle);
+      /* Convert fragment data from AoS to SoA format.
+       */
+      qword soa_frag[4];
+      _transpose_matrix4x4((vec_float4 *) soa_frag, colors);
+
+      /* Read the current framebuffer values.
+       */
+      const qword pix[4] = {
+         (qword) spu_splats(spu.ctile.ui[iy+0][ix+0]),
+         (qword) spu_splats(spu.ctile.ui[iy+0][ix+1]),
+         (qword) spu_splats(spu.ctile.ui[iy+1][ix+0]),
+         (qword) spu_splats(spu.ctile.ui[iy+1][ix+1]),
+      };
+
+      qword soa_pix[4];
+
+      if (spu.read_fb) {
+         /* Convert pixel data from AoS to SoA format.
+          */
+         vec_float4 aos_pix[4] = {
+            spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]),
+            spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]),
+            spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]),
+            spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]),
+         };
+
+         _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix);
+      }
 
-#if 0
-      /* SIMD_Z with swizzled color buffer (someday) */
-      vector unsigned int uicolors = *((vector unsigned int *) &colors);
-      spu.ctile.ui4[iy/2][ix/2] = spu_sel(spu.ctile.ui4[iy/2][ix/2], uicolors, mask);
-#endif
-   }
 
+      struct spu_blend_results result =
+          (*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3],
+                       soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3],
+                       spu.const_blend_color[0], spu.const_blend_color[1],
+                       spu.const_blend_color[2], spu.const_blend_color[3]);
+
+
+      /* Convert final pixel data from SoA to AoS format.
+       */
+      result = (*spu.logicop)(pix[0], pix[1], pix[2], pix[3],
+                              result.r, result.g, result.b, result.a,
+                              (qword) mask);
+
+      spu.ctile.ui[iy+0][ix+0] = spu_extract((vec_uint4) result.r, 0);
+      spu.ctile.ui[iy+0][ix+1] = spu_extract((vec_uint4) result.g, 0);
+      spu.ctile.ui[iy+1][ix+0] = spu_extract((vec_uint4) result.b, 0);
+      spu.ctile.ui[iy+1][ix+1] = spu_extract((vec_uint4) result.a, 0);
+   }
 #endif
 }
 
@@ -434,7 +459,7 @@ static void flush_spans( void )
    }
    ASSERT(spu.cur_ctile_status != TILE_STATUS_DEFINED);
 
-   if (spu.depth_stencil.depth.enabled) {
+   if (spu.read_depth) {
       if (spu.cur_ztile_status == TILE_STATUS_GETTING) {
          /* wait for mfc_get() to complete */
          //printf("SPU: %u: waiting for ztile\n", spu.init.id);