cell: Change code-gen for CONST_COLOR blend factor
authorIan Romanick <idr@us.ibm.com>
Fri, 21 Mar 2008 18:15:49 +0000 (11:15 -0700)
committerIan Romanick <idr@us.ibm.com>
Fri, 21 Mar 2008 22:57:01 +0000 (15:57 -0700)
Previously the constant color blend factor was compiled into the
generated code.  This meant that the code had to be regenerated each
time the constant color was changed.  This doesn't fit with the model
used in Gallium.

As-is, the code could be better.  The constant color is loaded for
every quad processed, even if it is not used.  Also, if a lot of (1-x)
blend factors are used, 1.0 will be loaded and reloaded into registers
many times.

src/gallium/drivers/cell/ppu/cell_pipe_state.c
src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
src/gallium/drivers/cell/spu/spu_main.h
src/gallium/drivers/cell/spu/spu_tri.c

index 86fcdcff1f68fea59ea17039c4a24e9719b046c7..d956d6fad4d9865ea5b3f0c391dc5e7c30ab9878 100644 (file)
@@ -63,7 +63,7 @@ cell_bind_blend_state(struct pipe_context *pipe, void *state)
    draw_flush(cell->draw);
 
    if ((blend != NULL) && (blend->code.store == NULL)) {
-      cell_generate_alpha_blend(blend, &cell->blend_color);
+      cell_generate_alpha_blend(blend);
    }
 
    cell->blend = blend;
index f353aeab0a8a1f8c3ed89bb61e8ce1fe75bcc22c..c750b1d89dc9ad94fe5cfde3e4f6d0f3c6d50cd2 100644 (file)
@@ -588,19 +588,13 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa)
  */
 static int
 emit_alpha_factor_calculation(struct spe_function *f,
-                              unsigned factor, float const_alpha,
-                              int src_alpha, int dst_alpha)
+                              unsigned factor,
+                              int src_alpha, int dst_alpha, int const_alpha)
 {
-   union {
-      float f;
-      unsigned u;
-   } alpha;
    int factor_reg;
    int tmp;
 
 
-   alpha.f = const_alpha;
-
    switch (factor) {
    case PIPE_BLENDFACTOR_ONE:
       factor_reg = -1;
@@ -621,13 +615,17 @@ emit_alpha_factor_calculation(struct spe_function *f,
       break;
 
    case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-      const_alpha = 1.0 - const_alpha;
-      /* FALLTHROUGH */
-   case PIPE_BLENDFACTOR_CONST_ALPHA:
       factor_reg = spe_allocate_available_register(f);
 
-      spe_il(f, factor_reg, alpha.u & 0x0ffff);
-      spe_ilh(f, factor_reg, alpha.u >> 16);
+      tmp = spe_allocate_available_register(f);
+      spe_il(f, tmp, 1);
+      spe_cuflt(f, tmp, tmp, 0);
+      spe_fs(f, factor_reg, tmp, const_alpha);
+      spe_release_register(f, tmp);
+      break;
+
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+      factor_reg = const_alpha;
       break;
 
    case PIPE_BLENDFACTOR_ZERO:
@@ -674,24 +672,15 @@ emit_alpha_factor_calculation(struct spe_function *f,
 static void
 emit_color_factor_calculation(struct spe_function *f,
                               unsigned sF, unsigned mask,
-                              const struct pipe_blend_color *blend_color,
                               const int *src,
                               const int *dst,
+                              const int *const_color,
                               int *factor)
 {
-   union {
-      float f[4];
-      unsigned u[4];
-   } color;
    int tmp;
    unsigned i;
 
 
-   color.f[0] = blend_color->color[0];
-   color.f[1] = blend_color->color[1];
-   color.f[2] = blend_color->color[2];
-   color.f[3] = blend_color->color[3];
-
    factor[0] = -1;
    factor[1] = -1;
    factor[2] = -1;
@@ -748,29 +737,40 @@ emit_color_factor_calculation(struct spe_function *f,
       break;
 
    case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-      color.f[0] = 1.0 - color.f[0];
-      color.f[1] = 1.0 - color.f[1];
-      color.f[2] = 1.0 - color.f[2];
-      /* FALLTHROUGH */
-   case PIPE_BLENDFACTOR_CONST_COLOR:
+      tmp = spe_allocate_available_register(f);
+      spe_il(f, tmp, 1);
+      spe_cuflt(f, tmp, tmp, 0);
+
       for (i = 0; i < 3; i++) {
          factor[i] = spe_allocate_available_register(f);
 
-         spe_il(f, factor[i], color.u[i] & 0x0ffff);
-         spe_ilh(f, factor[i], color.u[i] >> 16);
+         spe_fs(f, factor[i], tmp, const_color[i]);
+      }
+      spe_release_register(f, tmp);
+      break;
+
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+      for (i = 0; i < 3; i++) {
+         factor[i] = const_color[i];
       }
       break;
 
    case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-      color.f[3] = 1.0 - color.f[3];
-      /* FALLTHROUGH */
-   case PIPE_BLENDFACTOR_CONST_ALPHA:
       factor[0] = spe_allocate_available_register(f);
       factor[1] = factor[0];
       factor[2] = factor[0];
 
-      spe_il(f, factor[0], color.u[3] & 0x0ffff);
-      spe_ilh(f, factor[0], color.u[3] >> 16);
+      tmp = spe_allocate_available_register(f);
+      spe_il(f, tmp, 1);
+      spe_cuflt(f, tmp, tmp, 0);
+      spe_fs(f, factor[0], tmp, const_color[3]);
+      spe_release_register(f, tmp);
+      break;
+
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+      factor[0] = const_color[3];
+      factor[1] = factor[0];
+      factor[2] = factor[0];
       break;
 
    case PIPE_BLENDFACTOR_ZERO:
@@ -945,8 +945,7 @@ emit_blend_calculation(struct spe_function *f,
  * Generate code to perform alpha blending on the SPE
  */
 void
-cell_generate_alpha_blend(struct cell_blend_state *cb,
-                          const struct pipe_blend_color *blend_color)
+cell_generate_alpha_blend(struct cell_blend_state *cb)
 {
    struct pipe_blend_state *const b = &cb->base;
    struct spe_function *const f = &cb->code;
@@ -972,7 +971,13 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
       spe_allocate_register(f, 9),
       spe_allocate_register(f, 10),
    };
-   const int mask = spe_allocate_register(f, 11);
+   const int const_color[4] = {
+      spe_allocate_register(f, 11),
+      spe_allocate_register(f, 12),
+      spe_allocate_register(f, 13),
+      spe_allocate_register(f, 14),
+   };
+   const int mask = spe_allocate_register(f, 15);
    unsigned func[4];
    unsigned sF[4];
    unsigned dF[4];
@@ -1053,8 +1058,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
     * the alpha factor, calculate the alpha factor.
     */
    if (((b->colormask & 8) != 0) && need_alpha_factor) {
-      src_factor[3] = emit_alpha_factor_calculation(f, sF[3],
-                                                    blend_color->color[3],
+      src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3],
                                                     frag[3], pixel[3]);
 
       /* If the alpha destination blend factor is the same as the alpha source
@@ -1062,8 +1066,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
        */
       dst_factor[3] = (dF[3] == sF[3])
           ? src_factor[3]
-          : emit_alpha_factor_calculation(f, dF[3],
-                                          blend_color->color[3],
+          : emit_alpha_factor_calculation(f, dF[3], const_color[3],
                                           frag[3], pixel[3]);
    }
 
@@ -1080,8 +1083,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
       emit_color_factor_calculation(f,
                                     b->rgb_src_factor,
                                     b->colormask,
-                                    blend_color,
-                                    frag, pixel, src_factor);
+                                    frag, pixel, const_color, src_factor);
    }
 
 
@@ -1101,8 +1103,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
       emit_color_factor_calculation(f,
                                     b->rgb_dst_factor,
                                     b->colormask,
-                                    blend_color,
-                                    frag, pixel, dst_factor);
+                                    frag, pixel, const_color, dst_factor);
    }
 
 
index 541c3b3be07c009c7f4e4b9b28b60de6e27dbdc2..f699247f9e4847383c96f68b407176c879c7e918 100644 (file)
@@ -29,7 +29,6 @@ extern void
 cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa);
 
 extern void
-cell_generate_alpha_blend(struct cell_blend_state *cb,
-                         const struct pipe_blend_color *blend_color);
+cell_generate_alpha_blend(struct cell_blend_state *cb);
 
 #endif /* CELL_STATE_PER_FRAGMENT_H */
index 56d0968676b8ae548b5ac84b3e12e69dc36d62a7..49f5d99674ac50c93436281886f1938ad013f558 100644 (file)
@@ -77,6 +77,7 @@ struct spu_blend_results {
 typedef struct spu_blend_results (*blend_func)(
     qword frag_r, qword frag_g, qword frag_b, qword frag_a,
     qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
+    qword const_r, qword const_g, qword const_b, qword const_a,
     qword frag_mask);
 
 struct spu_framebuffer {
@@ -108,6 +109,7 @@ struct spu_global
    
    boolean read_fb;
    blend_func blend;
+   qword const_blend_color[4] ALIGN16_ATTRIB;
 
    struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
    struct cell_command_texture texture;
index c4272d6e93c4891fefea7222c76b32f9a0380075..e6a1ce01dfd48bdfaeb065713d7340a2af857eee 100644 (file)
@@ -356,6 +356,8 @@ emit_quad( int x, int y, mask_t mask )
       const 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],
                        (qword) mask);