cell: begin new blending code (both codegen and fallback paths)

This commit is contained in:
Brian Paul 2008-09-11 10:08:06 -06:00
parent 6092a05704
commit add86031db
2 changed files with 585 additions and 69 deletions

View File

@ -231,6 +231,370 @@ gen_alpha_test(const struct pipe_depth_stencil_alpha_state *dsa,
/**
* Generate SPE code to implement the given blend mode for a quad of pixels.
* \param f SPE function to append instruction onto.
* \param fragR_reg register with fragment red values (float) (in/out)
* \param fragG_reg register with fragment green values (float) (in/out)
* \param fragB_reg register with fragment blue values (float) (in/out)
* \param fragA_reg register with fragment alpha values (float) (in/out)
* \param fbRGBA_reg register with packed framebuffer colors (integer) (in)
*/
static void
gen_blend(const struct pipe_blend_state *blend,
struct spe_function *f,
enum pipe_format color_format,
int fragR_reg, int fragG_reg, int fragB_reg, int fragA_reg,
int fbRGBA_reg)
{
int term1R_reg = spe_allocate_available_register(f);
int term1G_reg = spe_allocate_available_register(f);
int term1B_reg = spe_allocate_available_register(f);
int term1A_reg = spe_allocate_available_register(f);
int term2R_reg = spe_allocate_available_register(f);
int term2G_reg = spe_allocate_available_register(f);
int term2B_reg = spe_allocate_available_register(f);
int term2A_reg = spe_allocate_available_register(f);
int fbR_reg = spe_allocate_available_register(f);
int fbG_reg = spe_allocate_available_register(f);
int fbB_reg = spe_allocate_available_register(f);
int fbA_reg = spe_allocate_available_register(f);
int one_reg = spe_allocate_available_register(f);
int tmp_reg = spe_allocate_available_register(f);
ASSERT(blend->blend_enable);
/* Unpack/convert framebuffer colors from four 32-bit packed colors
* (fbRGBA) to four float RGBA vectors (fbR, fbG, fbB, fbA).
* Each 8-bit color component is expanded into a float in [0.0, 1.0].
*/
{
int mask_reg = spe_allocate_available_register(f);
/* mask = {0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff} */
spe_fsmbi(f, mask_reg, 0x1111);
/* XXX there may be more clever ways to implement the following code */
switch (color_format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
/* fbB = fbB & mask */
spe_and(f, fbB_reg, fbRGBA_reg, mask_reg);
/* mask = mask << 8 */
spe_roti(f, mask_reg, mask_reg, 8);
/* fbG = fbRGBA & mask */
spe_and(f, fbB_reg, fbRGBA_reg, mask_reg);
/* fbG = fbG >> 8 */
spe_roti(f, fbB_reg, fbB_reg, -8);
/* mask = mask << 8 */
spe_roti(f, mask_reg, mask_reg, 8);
/* fbR = fbRGBA & mask */
spe_and(f, fbR_reg, fbRGBA_reg, mask_reg);
/* fbR = fbR >> 16 */
spe_roti(f, fbB_reg, fbB_reg, -16);
/* mask = mask << 8 */
spe_roti(f, mask_reg, mask_reg, 8);
/* fbA = fbRGBA & mask */
spe_and(f, fbA_reg, fbRGBA_reg, mask_reg);
/* fbA = fbA >> 24 */
spe_roti(f, fbA_reg, fbA_reg, -24);
break;
case PIPE_FORMAT_B8G8R8A8_UNORM:
/* fbA = fbA & mask */
spe_and(f, fbA_reg, fbRGBA_reg, mask_reg);
/* mask = mask << 8 */
spe_roti(f, mask_reg, mask_reg, 8);
/* fbR = fbRGBA & mask */
spe_and(f, fbR_reg, fbRGBA_reg, mask_reg);
/* fbR = fbR >> 8 */
spe_roti(f, fbR_reg, fbR_reg, -8);
/* mask = mask << 8 */
spe_roti(f, mask_reg, mask_reg, 8);
/* fbG = fbRGBA & mask */
spe_and(f, fbG_reg, fbRGBA_reg, mask_reg);
/* fbG = fbG >> 16 */
spe_roti(f, fbG_reg, fbG_reg, -16);
/* mask = mask << 8 */
spe_roti(f, mask_reg, mask_reg, 8);
/* fbB = fbRGBA & mask */
spe_and(f, fbB_reg, fbRGBA_reg, mask_reg);
/* fbB = fbB >> 24 */
spe_roti(f, fbB_reg, fbB_reg, -24);
break;
default:
ASSERT(0);
}
/* convert int[4] in [0,255] to float[4] in [0.0, 1.0] */
spe_cuflt(f, fbR_reg, fbR_reg, 8);
spe_cuflt(f, fbG_reg, fbG_reg, 8);
spe_cuflt(f, fbB_reg, fbB_reg, 8);
spe_cuflt(f, fbA_reg, fbA_reg, 8);
spe_release_register(f, mask_reg);
}
/*
* Compute Src RGB terms
*/
switch (blend->rgb_src_factor) {
case PIPE_BLENDFACTOR_ONE:
spe_move(f, term1R_reg, fragR_reg);
spe_move(f, term1G_reg, fragG_reg);
spe_move(f, term1B_reg, fragB_reg);
break;
case PIPE_BLENDFACTOR_ZERO:
spe_zero(f, term1R_reg);
spe_zero(f, term1G_reg);
spe_zero(f, term1B_reg);
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
spe_fm(f, term1R_reg, fragR_reg, fragR_reg);
spe_fm(f, term1G_reg, fragG_reg, fragG_reg);
spe_fm(f, term1B_reg, fragB_reg, fragB_reg);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
spe_fm(f, term1R_reg, fragR_reg, fragA_reg);
spe_fm(f, term1G_reg, fragG_reg, fragA_reg);
spe_fm(f, term1B_reg, fragB_reg, fragA_reg);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Src Alpha term
*/
switch (blend->alpha_src_factor) {
case PIPE_BLENDFACTOR_ONE:
spe_move(f, term1A_reg, fragA_reg);
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
spe_fm(f, term1A_reg, fragA_reg, fragA_reg);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
spe_fm(f, term1A_reg, fragA_reg, fragA_reg);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Dest RGB terms
*/
switch (blend->rgb_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
spe_move(f, term2R_reg, fbR_reg);
spe_move(f, term2G_reg, fbG_reg);
spe_move(f, term2B_reg, fbB_reg);
break;
case PIPE_BLENDFACTOR_ZERO:
spe_zero(f, term2R_reg);
spe_zero(f, term2G_reg);
spe_zero(f, term2B_reg);
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
spe_fm(f, term2R_reg, fbR_reg, fragR_reg);
spe_fm(f, term2G_reg, fbG_reg, fragG_reg);
spe_fm(f, term2B_reg, fbB_reg, fragB_reg);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
spe_fm(f, term2R_reg, fbR_reg, fragA_reg);
spe_fm(f, term2G_reg, fbG_reg, fragA_reg);
spe_fm(f, term2B_reg, fbB_reg, fragA_reg);
break;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
/* one = {1.0, 1.0, 1.0, 1.0} */
spe_load_float(f, one_reg, 1.0f);
/* tmp = one - fragA */
spe_fs(f, tmp_reg, one_reg, fragA_reg);
/* term = fb * tmp */
spe_fm(f, term2R_reg, fbR_reg, tmp_reg);
spe_fm(f, term2G_reg, fbG_reg, tmp_reg);
spe_fm(f, term2B_reg, fbB_reg, tmp_reg);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Dest Alpha term
*/
switch (blend->alpha_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
spe_move(f, term2A_reg, fbA_reg);
break;
case PIPE_BLENDFACTOR_ZERO:
spe_zero(f, term2A_reg);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
spe_fm(f, term2A_reg, fbA_reg, fragA_reg);
break;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
/* one = {1.0, 1.0, 1.0, 1.0} */
spe_load_float(f, one_reg, 1.0f);
/* tmp = one - fragA */
spe_fs(f, tmp_reg, one_reg, fragA_reg);
/* termA = fbA * tmp */
spe_fm(f, term2A_reg, fbA_reg, tmp_reg);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Combine Src/Dest RGB terms
*/
switch (blend->rgb_func) {
case PIPE_BLEND_ADD:
spe_fa(f, fragR_reg, term1R_reg, term2R_reg);
spe_fa(f, fragG_reg, term1G_reg, term2G_reg);
spe_fa(f, fragB_reg, term1B_reg, term2B_reg);
break;
case PIPE_BLEND_SUBTRACT:
spe_fs(f, fragR_reg, term1R_reg, term2R_reg);
spe_fs(f, fragG_reg, term1G_reg, term2G_reg);
spe_fs(f, fragB_reg, term1B_reg, term2B_reg);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Combine Src/Dest A term
*/
switch (blend->alpha_func) {
case PIPE_BLEND_ADD:
spe_fa(f, fragA_reg, term1A_reg, term2A_reg);
break;
case PIPE_BLEND_SUBTRACT:
spe_fs(f, fragA_reg, term1A_reg, term2A_reg);
break;
/* XXX more cases */
default:
ASSERT(0);
}
spe_release_register(f, term1R_reg);
spe_release_register(f, term1G_reg);
spe_release_register(f, term1B_reg);
spe_release_register(f, term1A_reg);
spe_release_register(f, term2R_reg);
spe_release_register(f, term2G_reg);
spe_release_register(f, term2B_reg);
spe_release_register(f, term2A_reg);
spe_release_register(f, fbR_reg);
spe_release_register(f, fbG_reg);
spe_release_register(f, fbB_reg);
spe_release_register(f, fbA_reg);
spe_release_register(f, one_reg);
spe_release_register(f, tmp_reg);
}
static void
gen_logicop(const struct pipe_blend_state *blend,
struct spe_function *f,
int fragRGBA_reg, int fbRGBA_reg)
{
/* XXX to-do */
/* operate on 32-bit packed pixels, not float colors */
}
static void
gen_colormask(uint colormask,
struct spe_function *f,
int fragRGBA_reg, int fbRGBA_reg)
{
/* XXX to-do */
/* operate on 32-bit packed pixels, not float colors */
}
/**
* Generate code to pack a quad of float colors into a four 32-bit integers.
*
* \param f SPE function to append instruction onto.
* \param color_format the dest color packing format
* \param r_reg register containing four red values (in/clobbered)
* \param g_reg register containing four green values (in/clobbered)
* \param b_reg register containing four blue values (in/clobbered)
* \param a_reg register containing four alpha values (in/clobbered)
* \param rgba_reg register to store the packed RGBA colors (out)
*/
static void
gen_pack_colors(struct spe_function *f,
enum pipe_format color_format,
int r_reg, int g_reg, int b_reg, int a_reg,
int rgba_reg)
{
/* Convert float[4] in [0.0,1.0] to int[4] in [0,~0], with clamping */
spe_cfltu(f, r_reg, r_reg, 32);
spe_cfltu(f, g_reg, g_reg, 32);
spe_cfltu(f, b_reg, b_reg, 32);
spe_cfltu(f, a_reg, a_reg, 32);
/* Shift the most significant bytes to least the significant positions.
* I.e.: reg = reg >> 24
*/
spe_rotmi(f, r_reg, r_reg, -24);
spe_rotmi(f, g_reg, g_reg, -24);
spe_rotmi(f, b_reg, b_reg, -24);
spe_rotmi(f, a_reg, a_reg, -24);
/* Shift the color bytes according to the surface format */
if (color_format == PIPE_FORMAT_A8R8G8B8_UNORM) {
spe_roti(f, g_reg, g_reg, 8); /* green <<= 8 */
spe_roti(f, r_reg, r_reg, 16); /* red <<= 16 */
spe_roti(f, a_reg, a_reg, 24); /* alpha <<= 24 */
}
else if (color_format == PIPE_FORMAT_B8G8R8A8_UNORM) {
spe_roti(f, r_reg, r_reg, 8); /* red <<= 8 */
spe_roti(f, g_reg, g_reg, 16); /* green <<= 16 */
spe_roti(f, b_reg, b_reg, 24); /* blue <<= 24 */
}
else {
ASSERT(0);
}
/* Merge red, green, blue, alpha registers to make packed RGBA colors.
* Eg: after shifting according to color_format we might have:
* R = {0x00ff0000, 0x00110000, 0x00220000, 0x00330000}
* G = {0x0000ff00, 0x00004400, 0x00005500, 0x00006600}
* B = {0x000000ff, 0x00000077, 0x00000088, 0x00000099}
* A = {0xff000000, 0xaa000000, 0xbb000000, 0xcc000000}
* OR-ing all those together gives us four packed colors:
* RGBA = {0xffffffff, 0xaa114477, 0xbb225588, 0xcc336699}
*/
spe_or(f, rgba_reg, r_reg, g_reg);
spe_or(f, rgba_reg, rgba_reg, b_reg);
spe_or(f, rgba_reg, rgba_reg, a_reg);
}
/**
* Generate SPE code to implement the fragment operations (alpha test,
* depth test, stencil test, blending, colormask, and final
@ -257,6 +621,7 @@ gen_fragment_function(struct cell_context *cell, struct spe_function *f)
const struct pipe_depth_stencil_alpha_state *dsa =
&cell->depth_stencil->base;
const struct pipe_blend_state *blend = &cell->blend->base;
const enum pipe_format color_format = cell->framebuffer.cbufs[0]->format;
/* For SPE function calls: reg $3 = first param, $4 = second param, etc. */
const int x_reg = 3; /* uint */
@ -443,64 +808,31 @@ gen_fragment_function(struct cell_context *cell, struct spe_function *f)
if (blend->blend_enable) {
/* convert packed tile colors in fbRGBA_reg to float[4] vectors */
// gen_blend_code(blend, f, mask_reg, ... );
gen_blend(blend, f, color_format,
fragR_reg, fragG_reg, fragB_reg, fragA_reg, fbRGBA_reg);
}
/*
* Write fragment colors to framebuffer/tile.
* This involves converting the fragment colors from float[4] to the
* tile's specific format and obeying the quad/pixel mask.
*/
{
const enum pipe_format color_format = cell->framebuffer.cbufs[0]->format;
int rgba_reg = spe_allocate_available_register(f);
/* Convert float[4] in [0.0,1.0] to int[4] in [0,~0], with clamping */
spe_cfltu(f, fragR_reg, fragR_reg, 32);
spe_cfltu(f, fragG_reg, fragG_reg, 32);
spe_cfltu(f, fragB_reg, fragB_reg, 32);
spe_cfltu(f, fragA_reg, fragA_reg, 32);
/* Pack four float colors as four 32-bit int colors */
gen_pack_colors(f, color_format,
fragR_reg, fragG_reg, fragB_reg, fragA_reg,
rgba_reg);
/* Shift most the significant bytes to least the significant positions.
* I.e.: reg = reg >> 24
*/
spe_rotmi(f, fragR_reg, fragR_reg, -24);
spe_rotmi(f, fragG_reg, fragG_reg, -24);
spe_rotmi(f, fragB_reg, fragB_reg, -24);
spe_rotmi(f, fragA_reg, fragA_reg, -24);
/* Shift the color bytes according to the surface format */
if (color_format == PIPE_FORMAT_A8R8G8B8_UNORM) {
spe_roti(f, fragG_reg, fragG_reg, 8); /* green <<= 8 */
spe_roti(f, fragR_reg, fragR_reg, 16); /* red <<= 16 */
spe_roti(f, fragA_reg, fragA_reg, 24); /* alpha <<= 24 */
}
else if (color_format == PIPE_FORMAT_B8G8R8A8_UNORM) {
spe_roti(f, fragR_reg, fragR_reg, 8); /* red <<= 8 */
spe_roti(f, fragG_reg, fragG_reg, 16); /* green <<= 16 */
spe_roti(f, fragB_reg, fragB_reg, 24); /* blue <<= 24 */
}
else {
ASSERT(0);
if (blend->logicop_enable) {
gen_logicop(blend, f, rgba_reg, fbRGBA_reg);
}
if (blend->colormask != 0xf) {
gen_colormask(blend->colormask, f, rgba_reg, fbRGBA_reg);
}
/* Merge red, green, blue, alpha registers to make packed RGBA colors.
* Eg: after shifting according to color_format we might have:
* R = {0x00ff0000, 0x00110000, 0x00220000, 0x00330000}
* G = {0x0000ff00, 0x00004400, 0x00005500, 0x00006600}
* B = {0x000000ff, 0x00000077, 0x00000088, 0x00000099}
* A = {0xff000000, 0xaa000000, 0xbb000000, 0xcc000000}
* OR-ing all those together gives us four packed colors:
* RGBA = {0xffffffff, 0xaa114477, 0xbb225588, 0xcc336699}
*/
spe_or(f, rgba_reg, fragR_reg, fragG_reg);
spe_or(f, rgba_reg, rgba_reg, fragB_reg);
spe_or(f, rgba_reg, rgba_reg, fragA_reg);
/* Mix fragment colors with framebuffer colors using the quad/pixel mask:
* if (mask[i])

View File

@ -39,9 +39,11 @@
/**
* Called by rasterizer for each quad after the shader has run. This
* is a fallback/debug function. In reality we'll use a generated
* function produced by the PPU. But this function is useful for
* Called by rasterizer for each quad after the shader has run. Do
* all the per-fragment operations including alpha test, z test,
* stencil test, blend, colormask and logicops. This is a
* fallback/debug function. In reality we'll use a generated function
* produced by the PPU. But this function is useful for
* debug/validation.
*/
void
@ -49,13 +51,13 @@ spu_fallback_fragment_ops(uint x, uint y,
tile_t *colorTile,
tile_t *depthStencilTile,
vector float fragZ,
vector float fragRed,
vector float fragGreen,
vector float fragBlue,
vector float fragAlpha,
vector float fragR,
vector float fragG,
vector float fragB,
vector float fragA,
vector unsigned int mask)
{
vector float frag_soa[4], frag_aos[4];
vector float frag_aos[4];
unsigned int c0, c1, c2, c3;
/* do alpha test */
@ -65,24 +67,24 @@ spu_fallback_fragment_ops(uint x, uint y,
switch (spu.depth_stencil_alpha.alpha.func) {
case PIPE_FUNC_LESS:
amask = spu_cmpgt(ref, fragAlpha); /* mask = (fragAlpha < ref) */
amask = spu_cmpgt(ref, fragA); /* mask = (fragA < ref) */
break;
case PIPE_FUNC_GREATER:
amask = spu_cmpgt(fragAlpha, ref); /* mask = (fragAlpha > ref) */
amask = spu_cmpgt(fragA, ref); /* mask = (fragA > ref) */
break;
case PIPE_FUNC_GEQUAL:
amask = spu_cmpgt(ref, fragAlpha);
amask = spu_cmpgt(ref, fragA);
amask = spu_nor(amask, amask);
break;
case PIPE_FUNC_LEQUAL:
amask = spu_cmpgt(fragAlpha, ref);
amask = spu_cmpgt(fragA, ref);
amask = spu_nor(amask, amask);
break;
case PIPE_FUNC_EQUAL:
amask = spu_cmpeq(ref, fragAlpha);
amask = spu_cmpeq(ref, fragA);
break;
case PIPE_FUNC_NOTEQUAL:
amask = spu_cmpeq(ref, fragAlpha);
amask = spu_cmpeq(ref, fragA);
amask = spu_nor(amask, amask);
break;
case PIPE_FUNC_ALWAYS:
@ -174,7 +176,189 @@ spu_fallback_fragment_ops(uint x, uint y,
}
}
/* XXX do blending here */
if (spu.blend.blend_enable) {
vector float term1r, term1g, term1b, term1a;
vector float term2r, term2g, term2b, term2a;
vector float fbRGBA[4];
vector float one, tmp;
/* get colors from framebuffer */
{
vector float fc[4];
uint c0, c1, c2, c3;
#if 0
c0 = colorTile->ui[y+0][x+0];
c1 = colorTile->ui[y+0][x+1];
c2 = colorTile->ui[y+1][x+0];
c3 = colorTile->ui[y+1][x+1];
#else
c0 = colorTile->ui[y][x*2+0];
c1 = colorTile->ui[y][x*2+1];
c2 = colorTile->ui[y][x*2+2];
c3 = colorTile->ui[y][x*2+3];
#endif
switch (spu.fb.color_format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
fc[0] = spu_unpack_B8G8R8A8(c0);
fc[1] = spu_unpack_B8G8R8A8(c1);
fc[2] = spu_unpack_B8G8R8A8(c2);
fc[3] = spu_unpack_B8G8R8A8(c3);
break;
case PIPE_FORMAT_A8R8G8B8_UNORM:
fc[0] = spu_unpack_A8R8G8B8(c0);
fc[1] = spu_unpack_A8R8G8B8(c1);
fc[2] = spu_unpack_A8R8G8B8(c2);
fc[3] = spu_unpack_A8R8G8B8(c3);
break;
default:
ASSERT(0);
}
_transpose_matrix4x4(fbRGBA, fc);
}
/*
* Compute Src RGB terms
*/
switch (spu.blend.rgb_src_factor) {
case PIPE_BLENDFACTOR_ONE:
term1r = fragR;
term1g = fragG;
term1b = fragB;
break;
case PIPE_BLENDFACTOR_ZERO:
term1r =
term1g =
term1b = spu_splats(0.0f);
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
term1r = spu_mul(fragR, fragR);
term1g = spu_mul(fragG, fragG);
term1b = spu_mul(fragB, fragB);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
term1r = spu_mul(fragR, fragA);
term1g = spu_mul(fragG, fragA);
term1b = spu_mul(fragB, fragA);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Src Alpha term
*/
switch (spu.blend.alpha_src_factor) {
case PIPE_BLENDFACTOR_ONE:
term1a = fragA;
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
term1a = spu_splats(0.0f);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
term1a = spu_mul(fragA, fragA);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Dest RGB terms
*/
switch (spu.blend.rgb_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
term2r = fragR;
term2g = fragG;
term2b = fragB;
break;
case PIPE_BLENDFACTOR_ZERO:
term2r =
term2g =
term2b = spu_splats(0.0f);
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
term2r = spu_mul(fbRGBA[0], fragR);
term2g = spu_mul(fbRGBA[1], fragG);
term2b = spu_mul(fbRGBA[2], fragB);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
term2r = spu_mul(fbRGBA[0], fragA);
term2g = spu_mul(fbRGBA[1], fragA);
term2b = spu_mul(fbRGBA[2], fragA);
break;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
one = spu_splats(1.0f);
tmp = spu_sub(one, fragA);
term2r = spu_mul(fbRGBA[0], tmp);
term2g = spu_mul(fbRGBA[1], tmp);
term2b = spu_mul(fbRGBA[2], tmp);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Dest Alpha term
*/
switch (spu.blend.alpha_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
term2a = fragA;
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
term2a = spu_splats(0.0f);
break;
case PIPE_BLENDFACTOR_SRC_ALPHA:
term2a = spu_mul(fbRGBA[3], fragA);
break;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
one = spu_splats(1.0f);
tmp = spu_sub(one, fragA);
term2a = spu_mul(fbRGBA[3], tmp);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Combine Src/Dest RGB terms
*/
switch (spu.blend.rgb_func) {
case PIPE_BLEND_ADD:
fragR = spu_add(term1r, term2r);
fragG = spu_add(term1g, term2g);
fragB = spu_add(term1b, term2b);
break;
case PIPE_BLEND_SUBTRACT:
fragR = spu_sub(term1r, term2r);
fragG = spu_sub(term1g, term2g);
fragB = spu_sub(term1b, term2b);
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Combine Src/Dest A term
*/
switch (spu.blend.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 */
default:
ASSERT(0);
}
}
/* XXX do colormask test here */
@ -190,17 +374,17 @@ spu_fallback_fragment_ops(uint x, uint y,
#if 0
{
vector float frag_soa[4];
frag_soa[0] = fragRed;
frag_soa[1] = fragGreen;
frag_soa[2] = fragBlue;
frag_soa[3] = fragAlpha;
frag_soa[0] = fragR;
frag_soa[1] = fragG;
frag_soa[2] = fragB;
frag_soa[3] = fragA;
_transpose_matrix4x4(frag_aos, frag_soa);
}
#else
/* short-cut relying on function parameter layout: */
_transpose_matrix4x4(frag_aos, &fragRed);
(void) fragGreen;
(void) fragBlue;
_transpose_matrix4x4(frag_aos, &fragR);
(void) fragG;
(void) fragB;
#endif
switch (spu.fb.color_format) {
@ -238,7 +422,7 @@ spu_fallback_fragment_ops(uint x, uint y,
if (spu_extract(mask, 2))
colorTile->ui[y+1][x+0] = c2;
if (spu_extract(mask, 3))
colorTile->ui[y+1][x+1] = c3;
colorTile->ui[y+1][x+1] = c3;
#else
/*
* Quad layout:
@ -253,6 +437,6 @@ spu_fallback_fragment_ops(uint x, uint y,
if (spu_extract(mask, 2))
colorTile->ui[y][x*2+2] = c2;
if (spu_extract(mask, 3))
colorTile->ui[y][x*2+3] = c3;
colorTile->ui[y][x*2+3] = c3;
#endif
}