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.
draw_flush(cell->draw);
if ((blend != NULL) && (blend->code.store == NULL)) {
draw_flush(cell->draw);
if ((blend != NULL) && (blend->code.store == NULL)) {
- cell_generate_alpha_blend(blend, &cell->blend_color);
+ cell_generate_alpha_blend(blend);
*/
static int
emit_alpha_factor_calculation(struct spe_function *f,
*/
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;
- alpha.f = const_alpha;
-
switch (factor) {
case PIPE_BLENDFACTOR_ONE:
factor_reg = -1;
switch (factor) {
case PIPE_BLENDFACTOR_ONE:
factor_reg = -1;
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
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);
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:
break;
case PIPE_BLENDFACTOR_ZERO:
static void
emit_color_factor_calculation(struct spe_function *f,
unsigned sF, unsigned mask,
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 *src,
const int *dst,
+ const int *const_color,
- union {
- float f[4];
- unsigned u[4];
- } color;
- 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;
factor[0] = -1;
factor[1] = -1;
factor[2] = -1;
break;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
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);
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:
}
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];
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:
break;
case PIPE_BLENDFACTOR_ZERO:
* Generate code to perform alpha blending on the SPE
*/
void
* 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;
{
struct pipe_blend_state *const b = &cb->base;
struct spe_function *const f = &cb->code;
spe_allocate_register(f, 9),
spe_allocate_register(f, 10),
};
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];
unsigned func[4];
unsigned sF[4];
unsigned dF[4];
* the alpha factor, calculate the alpha factor.
*/
if (((b->colormask & 8) != 0) && need_alpha_factor) {
* 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
frag[3], pixel[3]);
/* If the alpha destination blend factor is the same as the alpha source
*/
dst_factor[3] = (dF[3] == sF[3])
? src_factor[3]
*/
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],
emit_color_factor_calculation(f,
b->rgb_src_factor,
b->colormask,
emit_color_factor_calculation(f,
b->rgb_src_factor,
b->colormask,
- blend_color,
- frag, pixel, src_factor);
+ frag, pixel, const_color, src_factor);
emit_color_factor_calculation(f,
b->rgb_dst_factor,
b->colormask,
emit_color_factor_calculation(f,
b->rgb_dst_factor,
b->colormask,
- blend_color,
- frag, pixel, dst_factor);
+ frag, pixel, const_color, dst_factor);
cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa);
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 */
#endif /* CELL_STATE_PER_FRAGMENT_H */
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,
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 {
qword frag_mask);
struct spu_framebuffer {
boolean read_fb;
blend_func blend;
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;
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct cell_command_texture texture;
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],
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],