Merge branch '7.8'
[mesa.git] / src / gallium / drivers / cell / spu / spu_per_fragment_op.c
index d252fa6dc1846f0fd078d2553083f169abf77294..3b9566042a1d1369f19c6f819b6dedecd7666251 100644 (file)
 #define LINEAR_QUAD_LAYOUT 1
 
 
+static INLINE vector float
+spu_min(vector float a, vector float b)
+{
+   vector unsigned int m;
+   m = spu_cmpgt(a, b);    /* m = a > b ? ~0 : 0 */
+   return spu_sel(a, b, m);
+}
+
+
+static INLINE vector float
+spu_max(vector float a, vector float b)
+{
+   vector unsigned int m;
+   m = spu_cmpgt(a, b);    /* m = a > b ? ~0 : 0 */
+   return spu_sel(b, a, m);
+}
+
+
 /**
  * Called by rasterizer for each quad after the shader has run.  Do
  * all the per-fragment operations including alpha test, z test,
@@ -57,8 +75,7 @@ spu_fallback_fragment_ops(uint x, uint y,
                           vector float fragG,
                           vector float fragB,
                           vector float fragA,
-                          vector unsigned int mask,
-                          uint facing)
+                          vector unsigned int mask)
 {
    vector float frag_aos[4];
    unsigned int fbc0, fbc1, fbc2, fbc3 ; /* framebuffer/tile colors */
@@ -68,7 +85,7 @@ spu_fallback_fragment_ops(uint x, uint y,
     * Do alpha test
     */
    if (spu.depth_stencil_alpha.alpha.enabled) {
-      vector float ref = spu_splats(spu.depth_stencil_alpha.alpha.ref);
+      vector float ref = spu_splats(spu.depth_stencil_alpha.alpha.ref_value);
       vector unsigned int amask;
 
       switch (spu.depth_stencil_alpha.alpha.func) {
@@ -121,14 +138,14 @@ spu_fallback_fragment_ops(uint x, uint y,
 
       if (spu.depth_stencil_alpha.stencil[0].enabled) {
          /* do stencil test */
-         ASSERT(spu.fb.depth_format == PIPE_FORMAT_S8Z24_UNORM);
+         ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED);
 
       }
       else if (spu.depth_stencil_alpha.depth.enabled) {
          /* do depth test */
 
-         ASSERT(spu.fb.depth_format == PIPE_FORMAT_S8Z24_UNORM ||
-                spu.fb.depth_format == PIPE_FORMAT_X8Z24_UNORM);
+         ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
+                spu.fb.depth_format == PIPE_FORMAT_Z24X8_UNORM);
 
          vector unsigned int ifragZ;
          vector unsigned int zmask;
@@ -190,9 +207,9 @@ spu_fallback_fragment_ops(uint x, uint y,
     * If we'll need the current framebuffer/tile colors for blending
     * or logicop or colormask, fetch them now.
     */
-   if (spu.blend.blend_enable ||
+   if (spu.blend.rt[0].blend_enable ||
        spu.blend.logicop_enable ||
-       spu.blend.colormask != 0xf) {
+       spu.blend.rt[0].colormask != 0xf) {
 
 #if LINEAR_QUAD_LAYOUT /* See comments/diagram below */
       fbc0 = colorTile->ui[y][x*2+0];
@@ -211,7 +228,7 @@ spu_fallback_fragment_ops(uint x, uint y,
    /*
     * Do blending
     */
-   if (spu.blend.blend_enable) {
+   if (spu.blend.rt[0].blend_enable) {
       /* blending terms, misc regs */
       vector float term1r, term1g, term1b, term1a;
       vector float term2r, term2g, term2b, term2a;
@@ -223,13 +240,13 @@ spu_fallback_fragment_ops(uint x, uint y,
       {
          vector float temp[4]; /* float colors in AOS form */
          switch (spu.fb.color_format) {
-         case PIPE_FORMAT_B8G8R8A8_UNORM:
+         case PIPE_FORMAT_A8R8G8B8_UNORM:
             temp[0] = spu_unpack_B8G8R8A8(fbc0);
             temp[1] = spu_unpack_B8G8R8A8(fbc1);
             temp[2] = spu_unpack_B8G8R8A8(fbc2);
             temp[3] = spu_unpack_B8G8R8A8(fbc3);
             break;
-         case PIPE_FORMAT_A8R8G8B8_UNORM:
+         case PIPE_FORMAT_B8G8R8A8_UNORM:
             temp[0] = spu_unpack_A8R8G8B8(fbc0);
             temp[1] = spu_unpack_A8R8G8B8(fbc1);
             temp[2] = spu_unpack_A8R8G8B8(fbc2);
@@ -242,9 +259,9 @@ spu_fallback_fragment_ops(uint x, uint y,
       }
 
       /*
-       * Compute Src RGB terms
+       * Compute Src RGB terms (fragment color * factor)
        */
-      switch (spu.blend.rgb_src_factor) {
+      switch (spu.blend.rt[0].rgb_src_factor) {
       case PIPE_BLENDFACTOR_ONE:
          term1r = fragR;
          term1g = fragG;
@@ -265,15 +282,35 @@ spu_fallback_fragment_ops(uint x, uint y,
          term1g = spu_mul(fragG, fragA);
          term1b = spu_mul(fragB, fragA);
          break;
+      case PIPE_BLENDFACTOR_DST_COLOR:
+         term1r = spu_mul(fragR, fbRGBA[0]);
+         term1g = spu_mul(fragG, fbRGBA[1]);
+         term1b = spu_mul(fragB, fbRGBA[1]);
+         break;
+      case PIPE_BLENDFACTOR_DST_ALPHA:
+         term1r = spu_mul(fragR, fbRGBA[3]);
+         term1g = spu_mul(fragG, fbRGBA[3]);
+         term1b = spu_mul(fragB, fbRGBA[3]);
+         break;
+      case PIPE_BLENDFACTOR_CONST_COLOR:
+         term1r = spu_mul(fragR, spu_splats(spu.blend_color.color[0]));
+         term1g = spu_mul(fragG, spu_splats(spu.blend_color.color[1]));
+         term1b = spu_mul(fragB, spu_splats(spu.blend_color.color[2]));
+         break;
+      case PIPE_BLENDFACTOR_CONST_ALPHA:
+         term1r = spu_mul(fragR, spu_splats(spu.blend_color.color[3]));
+         term1g = spu_mul(fragG, spu_splats(spu.blend_color.color[3]));
+         term1b = spu_mul(fragB, spu_splats(spu.blend_color.color[3]));
+         break;
       /* XXX more cases */
       default:
          ASSERT(0);
       }
 
       /*
-       * Compute Src Alpha term
+       * Compute Src Alpha term (fragment alpha * factor)
        */
-      switch (spu.blend.alpha_src_factor) {
+      switch (spu.blend.rt[0].alpha_src_factor) {
       case PIPE_BLENDFACTOR_ONE:
          term1a = fragA;
          break;
@@ -283,19 +320,29 @@ spu_fallback_fragment_ops(uint x, uint y,
       case PIPE_BLENDFACTOR_SRC_ALPHA:
          term1a = spu_mul(fragA, fragA);
          break;
+      case PIPE_BLENDFACTOR_DST_COLOR:
+         /* fall-through */
+      case PIPE_BLENDFACTOR_DST_ALPHA:
+         term1a = spu_mul(fragA, fbRGBA[3]);
+         break;
+      case PIPE_BLENDFACTOR_CONST_COLOR:
+         /* fall-through */
+      case PIPE_BLENDFACTOR_CONST_ALPHA:
+         term1a = spu_mul(fragR, spu_splats(spu.blend_color.color[3]));
+         break;
       /* XXX more cases */
       default:
          ASSERT(0);
       }
 
       /*
-       * Compute Dest RGB terms
+       * Compute Dest RGB terms (framebuffer color * factor)
        */
-      switch (spu.blend.rgb_dst_factor) {
+      switch (spu.blend.rt[0].rgb_dst_factor) {
       case PIPE_BLENDFACTOR_ONE:
-         term2r = fragR;
-         term2g = fragG;
-         term2b = fragB;
+         term2r = fbRGBA[0];
+         term2g = fbRGBA[1];
+         term2b = fbRGBA[2];
          break;
       case PIPE_BLENDFACTOR_ZERO:
          term2r =
@@ -319,17 +366,37 @@ spu_fallback_fragment_ops(uint x, uint y,
          term2g = spu_mul(fbRGBA[1], tmp);
          term2b = spu_mul(fbRGBA[2], tmp);
          break;
-      /* XXX more cases */
+      case PIPE_BLENDFACTOR_DST_COLOR:
+         term2r = spu_mul(fbRGBA[0], fbRGBA[0]);
+         term2g = spu_mul(fbRGBA[1], fbRGBA[1]);
+         term2b = spu_mul(fbRGBA[2], fbRGBA[2]);
+         break;
+      case PIPE_BLENDFACTOR_DST_ALPHA:
+         term2r = spu_mul(fbRGBA[0], fbRGBA[3]);
+         term2g = spu_mul(fbRGBA[1], fbRGBA[3]);
+         term2b = spu_mul(fbRGBA[2], fbRGBA[3]);
+         break;
+      case PIPE_BLENDFACTOR_CONST_COLOR:
+         term2r = spu_mul(fbRGBA[0], spu_splats(spu.blend_color.color[0]));
+         term2g = spu_mul(fbRGBA[1], spu_splats(spu.blend_color.color[1]));
+         term2b = spu_mul(fbRGBA[2], spu_splats(spu.blend_color.color[2]));
+         break;
+      case PIPE_BLENDFACTOR_CONST_ALPHA:
+         term2r = spu_mul(fbRGBA[0], spu_splats(spu.blend_color.color[3]));
+         term2g = spu_mul(fbRGBA[1], spu_splats(spu.blend_color.color[3]));
+         term2b = spu_mul(fbRGBA[2], spu_splats(spu.blend_color.color[3]));
+         break;
+       /* XXX more cases */
       default:
          ASSERT(0);
       }
 
       /*
-       * Compute Dest Alpha term
+       * Compute Dest Alpha term (framebuffer alpha * factor)
        */
-      switch (spu.blend.alpha_dst_factor) {
+      switch (spu.blend.rt[0].alpha_dst_factor) {
       case PIPE_BLENDFACTOR_ONE:
-         term2a = fragA;
+         term2a = fbRGBA[3];
          break;
       case PIPE_BLENDFACTOR_SRC_COLOR:
          term2a = spu_splats(0.0f);
@@ -342,6 +409,16 @@ spu_fallback_fragment_ops(uint x, uint y,
          tmp = spu_sub(one, fragA);
          term2a = spu_mul(fbRGBA[3], tmp);
          break;
+      case PIPE_BLENDFACTOR_DST_COLOR:
+         /* fall-through */
+      case PIPE_BLENDFACTOR_DST_ALPHA:
+         term2a = spu_mul(fbRGBA[3], fbRGBA[3]);
+         break;
+      case PIPE_BLENDFACTOR_CONST_COLOR:
+         /* fall-through */
+      case PIPE_BLENDFACTOR_CONST_ALPHA:
+         term2a = spu_mul(fbRGBA[3], spu_splats(spu.blend_color.color[3]));
+         break;
       /* XXX more cases */
       default:
          ASSERT(0);
@@ -350,7 +427,7 @@ spu_fallback_fragment_ops(uint x, uint y,
       /*
        * Combine Src/Dest RGB terms
        */
-      switch (spu.blend.rgb_func) {
+      switch (spu.blend.rt[0].rgb_func) {
       case PIPE_BLEND_ADD:
          fragR = spu_add(term1r, term2r);
          fragG = spu_add(term1g, term2g);
@@ -361,7 +438,21 @@ spu_fallback_fragment_ops(uint x, uint y,
          fragG = spu_sub(term1g, term2g);
          fragB = spu_sub(term1b, term2b);
          break;
-      /* XXX more cases */
+      case PIPE_BLEND_REVERSE_SUBTRACT:
+         fragR = spu_sub(term2r, term1r);
+         fragG = spu_sub(term2g, term1g);
+         fragB = spu_sub(term2b, term1b);
+         break;
+      case PIPE_BLEND_MIN:
+         fragR = spu_min(term1r, term2r);
+         fragG = spu_min(term1g, term2g);
+         fragB = spu_min(term1b, term2b);
+         break;
+      case PIPE_BLEND_MAX:
+         fragR = spu_max(term1r, term2r);
+         fragG = spu_max(term1g, term2g);
+         fragB = spu_max(term1b, term2b);
+         break;
       default:
          ASSERT(0);
       }
@@ -369,14 +460,22 @@ spu_fallback_fragment_ops(uint x, uint y,
       /*
        * Combine Src/Dest A term
        */
-      switch (spu.blend.alpha_func) {
+      switch (spu.blend.rt[0].alpha_func) {
       case PIPE_BLEND_ADD:
          fragA = spu_add(term1a, term2a);
          break;
       case PIPE_BLEND_SUBTRACT:
          fragA = spu_sub(term1a, term2a);
          break;
-      /* XXX more cases */
+      case PIPE_BLEND_REVERSE_SUBTRACT:
+         fragA = spu_sub(term2a, term1a);
+         break;
+      case PIPE_BLEND_MIN:
+         fragA = spu_min(term1a, term2a);
+         break;
+      case PIPE_BLEND_MAX:
+         fragA = spu_max(term1a, term2a);
+         break;
       default:
          ASSERT(0);
       }
@@ -407,13 +506,13 @@ spu_fallback_fragment_ops(uint x, uint y,
     * Pack fragment float colors into 32-bit RGBA words.
     */
    switch (spu.fb.color_format) {
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
+   case PIPE_FORMAT_B8G8R8A8_UNORM:
       fragc0 = spu_pack_A8R8G8B8(frag_aos[0]);
       fragc1 = spu_pack_A8R8G8B8(frag_aos[1]);
       fragc2 = spu_pack_A8R8G8B8(frag_aos[2]);
       fragc3 = spu_pack_A8R8G8B8(frag_aos[3]);
       break;
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
       fragc0 = spu_pack_B8G8R8A8(frag_aos[0]);
       fragc1 = spu_pack_B8G8R8A8(frag_aos[1]);
       fragc2 = spu_pack_B8G8R8A8(frag_aos[2]);
@@ -428,29 +527,29 @@ spu_fallback_fragment_ops(uint x, uint y,
    /*
     * Do color masking
     */
-   if (spu.blend.colormask != 0xf) {
+   if (spu.blend.rt[0].colormask != 0xf) {
       uint cmask = 0x0; /* each byte corresponds to a color channel */
 
       /* Form bitmask depending on color buffer format and colormask bits */
       switch (spu.fb.color_format) {
-      case PIPE_FORMAT_A8R8G8B8_UNORM:
-         if (spu.blend.colormask & PIPE_MASK_R)
+      case PIPE_FORMAT_B8G8R8A8_UNORM:
+         if (spu.blend.rt[0].colormask & PIPE_MASK_R)
             cmask |= 0x00ff0000; /* red */
-         if (spu.blend.colormask & PIPE_MASK_G)
+         if (spu.blend.rt[0].colormask & PIPE_MASK_G)
             cmask |= 0x0000ff00; /* green */
-         if (spu.blend.colormask & PIPE_MASK_B)
+         if (spu.blend.rt[0].colormask & PIPE_MASK_B)
             cmask |= 0x000000ff; /* blue */
-         if (spu.blend.colormask & PIPE_MASK_A)
+         if (spu.blend.rt[0].colormask & PIPE_MASK_A)
             cmask |= 0xff000000; /* alpha */
          break;
-      case PIPE_FORMAT_B8G8R8A8_UNORM:
-         if (spu.blend.colormask & PIPE_MASK_R)
+      case PIPE_FORMAT_A8R8G8B8_UNORM:
+         if (spu.blend.rt[0].colormask & PIPE_MASK_R)
             cmask |= 0x0000ff00; /* red */
-         if (spu.blend.colormask & PIPE_MASK_G)
+         if (spu.blend.rt[0].colormask & PIPE_MASK_G)
             cmask |= 0x00ff0000; /* green */
-         if (spu.blend.colormask & PIPE_MASK_B)
+         if (spu.blend.rt[0].colormask & PIPE_MASK_B)
             cmask |= 0xff000000; /* blue */
-         if (spu.blend.colormask & PIPE_MASK_A)
+         if (spu.blend.rt[0].colormask & PIPE_MASK_A)
             cmask |= 0x000000ff; /* alpha */
          break;
       default: