From 600499cf888fee9a91ff3106beca939ea0c7b2bd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 21 Mar 2008 11:15:49 -0700 Subject: [PATCH] cell: Change code-gen for CONST_COLOR blend factor 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. --- .../drivers/cell/ppu/cell_pipe_state.c | 2 +- .../cell/ppu/cell_state_per_fragment.c | 93 ++++++++++--------- .../cell/ppu/cell_state_per_fragment.h | 3 +- src/gallium/drivers/cell/spu/spu_main.h | 2 + src/gallium/drivers/cell/spu/spu_tri.c | 2 + 5 files changed, 53 insertions(+), 49 deletions(-) diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 86fcdcff1f6..d956d6fad4d 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -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; diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index f353aeab0a8..c750b1d89dc 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -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); } diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h index 541c3b3be07..f699247f9e4 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h @@ -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 */ diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 56d0968676b..49f5d99674a 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -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; diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index c4272d6e93c..e6a1ce01dfd 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -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); -- 2.30.2