Go to the source code of this file.
Functions | |
void | cell_generate_depth_stencil_test (struct cell_depth_stencil_alpha_state *cdsa) |
void | cell_generate_alpha_blend (struct cell_blend_state *cb) |
Generate code to perform alpha blending on the SPE. | |
void | cell_generate_logic_op (struct spe_function *f, const struct pipe_blend_state *blend, struct pipe_surface *surf) |
Generate code to perform color conversion and logic op. |
void cell_generate_alpha_blend | ( | struct cell_blend_state * | cb | ) |
Generate code to perform alpha blending on the SPE.
Definition at line 959 of file cell_state_per_fragment.c.
References pipe_blend_state::alpha_dst_factor, pipe_blend_state::alpha_func, pipe_blend_state::alpha_src_factor, cell_blend_state::base, pipe_blend_state::blend_enable, cell_blend_state::code, pipe_blend_state::colormask, emit_alpha_factor_calculation(), emit_blend_calculation(), emit_color_factor_calculation(), PIPE_BLEND_ADD, PIPE_BLEND_MAX, PIPE_BLEND_MIN, PIPE_BLENDFACTOR_CONST_COLOR, PIPE_BLENDFACTOR_DST_COLOR, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_SRC1_COLOR, PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE, PIPE_BLENDFACTOR_SRC_COLOR, PIPE_BLENDFACTOR_ZERO, pipe_blend_state::rgb_dst_factor, pipe_blend_state::rgb_func, pipe_blend_state::rgb_src_factor, spe_allocate_register(), spe_bi(), spe_init_func(), SPE_INST_SIZE, and spe_function::store.
00960 { 00961 struct pipe_blend_state *const b = &cb->base; 00962 struct spe_function *const f = &cb->code; 00963 00964 /* This code generates a maximum of 3 (source alpha factor) 00965 * + 3 (destination alpha factor) + (3 * 6) (source color factor) 00966 * + (3 * 6) (destination color factor) + (4 * 2) (blend equation) 00967 * + 4 (fragment mask) + 1 (return) = 55 instlructions. Round up to 64 to 00968 * make it a happy power-of-two. 00969 */ 00970 spe_init_func(f, SPE_INST_SIZE * 64); 00971 00972 00973 const int frag[4] = { 00974 spe_allocate_register(f, 3), 00975 spe_allocate_register(f, 4), 00976 spe_allocate_register(f, 5), 00977 spe_allocate_register(f, 6), 00978 }; 00979 const int pixel[4] = { 00980 spe_allocate_register(f, 7), 00981 spe_allocate_register(f, 8), 00982 spe_allocate_register(f, 9), 00983 spe_allocate_register(f, 10), 00984 }; 00985 const int const_color[4] = { 00986 spe_allocate_register(f, 11), 00987 spe_allocate_register(f, 12), 00988 spe_allocate_register(f, 13), 00989 spe_allocate_register(f, 14), 00990 }; 00991 unsigned func[4]; 00992 unsigned sF[4]; 00993 unsigned dF[4]; 00994 unsigned i; 00995 int src_factor[4]; 00996 int dst_factor[4]; 00997 00998 00999 /* Does the selected blend mode make use of the source / destination 01000 * color (RGB) blend factors? 01001 */ 01002 boolean need_color_factor = b->blend_enable 01003 && (b->rgb_func != PIPE_BLEND_MIN) 01004 && (b->rgb_func != PIPE_BLEND_MAX); 01005 01006 /* Does the selected blend mode make use of the source / destination 01007 * alpha blend factors? 01008 */ 01009 boolean need_alpha_factor = b->blend_enable 01010 && (b->alpha_func != PIPE_BLEND_MIN) 01011 && (b->alpha_func != PIPE_BLEND_MAX); 01012 01013 01014 if (b->blend_enable) { 01015 sF[0] = b->rgb_src_factor; 01016 sF[1] = sF[0]; 01017 sF[2] = sF[0]; 01018 switch (b->alpha_src_factor & 0x0f) { 01019 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 01020 sF[3] = PIPE_BLENDFACTOR_ONE; 01021 break; 01022 case PIPE_BLENDFACTOR_SRC_COLOR: 01023 case PIPE_BLENDFACTOR_DST_COLOR: 01024 case PIPE_BLENDFACTOR_CONST_COLOR: 01025 case PIPE_BLENDFACTOR_SRC1_COLOR: 01026 sF[3] = b->alpha_src_factor + 1; 01027 break; 01028 default: 01029 sF[3] = b->alpha_src_factor; 01030 } 01031 01032 dF[0] = b->rgb_dst_factor; 01033 dF[1] = dF[0]; 01034 dF[2] = dF[0]; 01035 switch (b->alpha_dst_factor & 0x0f) { 01036 case PIPE_BLENDFACTOR_SRC_COLOR: 01037 case PIPE_BLENDFACTOR_DST_COLOR: 01038 case PIPE_BLENDFACTOR_CONST_COLOR: 01039 case PIPE_BLENDFACTOR_SRC1_COLOR: 01040 dF[3] = b->alpha_dst_factor + 1; 01041 break; 01042 default: 01043 dF[3] = b->alpha_dst_factor; 01044 } 01045 01046 func[0] = b->rgb_func; 01047 func[1] = func[0]; 01048 func[2] = func[0]; 01049 func[3] = b->alpha_func; 01050 } else { 01051 sF[0] = PIPE_BLENDFACTOR_ONE; 01052 sF[1] = PIPE_BLENDFACTOR_ONE; 01053 sF[2] = PIPE_BLENDFACTOR_ONE; 01054 sF[3] = PIPE_BLENDFACTOR_ONE; 01055 dF[0] = PIPE_BLENDFACTOR_ZERO; 01056 dF[1] = PIPE_BLENDFACTOR_ZERO; 01057 dF[2] = PIPE_BLENDFACTOR_ZERO; 01058 dF[3] = PIPE_BLENDFACTOR_ZERO; 01059 01060 func[0] = PIPE_BLEND_ADD; 01061 func[1] = PIPE_BLEND_ADD; 01062 func[2] = PIPE_BLEND_ADD; 01063 func[3] = PIPE_BLEND_ADD; 01064 } 01065 01066 01067 /* If alpha writing is enabled and the alpha blend mode requires use of 01068 * the alpha factor, calculate the alpha factor. 01069 */ 01070 if (((b->colormask & 8) != 0) && need_alpha_factor) { 01071 src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3], 01072 frag[3], pixel[3]); 01073 01074 /* If the alpha destination blend factor is the same as the alpha source 01075 * blend factor, re-use the previously calculated value. 01076 */ 01077 dst_factor[3] = (dF[3] == sF[3]) 01078 ? src_factor[3] 01079 : emit_alpha_factor_calculation(f, dF[3], const_color[3], 01080 frag[3], pixel[3]); 01081 } 01082 01083 01084 if (sF[0] == sF[3]) { 01085 src_factor[0] = src_factor[3]; 01086 src_factor[1] = src_factor[3]; 01087 src_factor[2] = src_factor[3]; 01088 } else if (sF[0] == dF[3]) { 01089 src_factor[0] = dst_factor[3]; 01090 src_factor[1] = dst_factor[3]; 01091 src_factor[2] = dst_factor[3]; 01092 } else if (need_color_factor) { 01093 emit_color_factor_calculation(f, 01094 b->rgb_src_factor, 01095 b->colormask, 01096 frag, pixel, const_color, src_factor); 01097 } 01098 01099 01100 if (dF[0] == sF[3]) { 01101 dst_factor[0] = src_factor[3]; 01102 dst_factor[1] = src_factor[3]; 01103 dst_factor[2] = src_factor[3]; 01104 } else if (dF[0] == dF[3]) { 01105 dst_factor[0] = dst_factor[3]; 01106 dst_factor[1] = dst_factor[3]; 01107 dst_factor[2] = dst_factor[3]; 01108 } else if (dF[0] == sF[0]) { 01109 dst_factor[0] = src_factor[0]; 01110 dst_factor[1] = src_factor[1]; 01111 dst_factor[2] = src_factor[2]; 01112 } else if (need_color_factor) { 01113 emit_color_factor_calculation(f, 01114 b->rgb_dst_factor, 01115 b->colormask, 01116 frag, pixel, const_color, dst_factor); 01117 } 01118 01119 01120 01121 for (i = 0; i < 4; ++i) { 01122 if ((b->colormask & (1U << i)) != 0) { 01123 emit_blend_calculation(f, 01124 func[i], sF[i], dF[i], 01125 frag[i], src_factor[i], 01126 pixel[i], dst_factor[i]); 01127 } 01128 } 01129 01130 spe_bi(f, 0, 0, 0); 01131 01132 #if 0 01133 { 01134 const uint32_t *p = f->store; 01135 01136 printf("# %u instructions\n", f->csr - f->store); 01137 printf("# blend (%sabled)\n", 01138 (cb->base.blend_enable) ? "en" : "dis"); 01139 printf("# RGB func / sf / df: %u %u %u\n", 01140 cb->base.rgb_func, 01141 cb->base.rgb_src_factor, 01142 cb->base.rgb_dst_factor); 01143 printf("# ALP func / sf / df: %u %u %u\n", 01144 cb->base.alpha_func, 01145 cb->base.alpha_src_factor, 01146 cb->base.alpha_dst_factor); 01147 01148 printf("\t.text\n"); 01149 for (/* empty */; p < f->csr; p++) { 01150 printf("\t.long\t0x%04x\n", *p); 01151 } 01152 fflush(stdout); 01153 } 01154 #endif 01155 }
void cell_generate_depth_stencil_test | ( | struct cell_depth_stencil_alpha_state * | cdsa | ) |
Definition at line 466 of file cell_state_per_fragment.c.
References pipe_depth_stencil_alpha_state::alpha, cell_depth_stencil_alpha_state::base, cell_depth_stencil_alpha_state::code, pipe_depth_stencil_alpha_state::depth, emit_alpha_test(), emit_depth_test(), emit_stencil_test(), pipe_alpha_state::enabled, pipe_depth_state::enabled, pipe_stencil_state::enabled, pipe_stencil_state::fail_op, pipe_stencil_state::func, pipe_depth_state::func, pipe_alpha_state::func, pipe_alpha_state::ref, pipe_stencil_state::ref_value, spe_allocate_available_register(), spe_allocate_register(), spe_and(), spe_andc(), spe_bi(), spe_init_func(), SPE_INST_SIZE, spe_or(), spe_release_register(), spe_selb(), pipe_depth_stencil_alpha_state::stencil, spe_function::store, pipe_stencil_state::value_mask, pipe_stencil_state::write_mask, pipe_depth_state::writemask, pipe_stencil_state::zfail_op, and pipe_stencil_state::zpass_op.
00467 { 00468 struct pipe_depth_stencil_alpha_state *const dsa = &cdsa->base; 00469 struct spe_function *const f = &cdsa->code; 00470 00471 /* This code generates a maximum of 6 (alpha test) + 3 (depth test) 00472 * + 25 (front stencil) + 25 (back stencil) + 4 = 63 instructions. Round 00473 * up to 64 to make it a happy power-of-two. 00474 */ 00475 spe_init_func(f, SPE_INST_SIZE * 64); 00476 00477 00478 /* Allocate registers for the function's input parameters. Cleverly (and 00479 * clever code is usually dangerous, but I couldn't resist) the generated 00480 * function returns a structure. Returned structures start with register 00481 * 3, and the structure fields are ordered to match up exactly with the 00482 * input parameters. 00483 */ 00484 int mask = spe_allocate_register(f, 3); 00485 int depth = spe_allocate_register(f, 4); 00486 int stencil = spe_allocate_register(f, 5); 00487 int zvals = spe_allocate_register(f, 6); 00488 int frag_a = spe_allocate_register(f, 7); 00489 int facing = spe_allocate_register(f, 8); 00490 00491 int depth_mask = spe_allocate_available_register(f); 00492 00493 boolean depth_complement; 00494 00495 00496 emit_alpha_test(dsa, f, mask, frag_a); 00497 00498 depth_complement = emit_depth_test(dsa, f, depth_mask, depth, zvals); 00499 00500 if (dsa->stencil[0].enabled) { 00501 const int front_depth_pass = spe_allocate_available_register(f); 00502 int front_stencil = emit_stencil_test(dsa, 0, f, mask, 00503 depth_mask, depth_complement, 00504 stencil, front_depth_pass); 00505 00506 if (dsa->stencil[1].enabled) { 00507 const int back_depth_pass = spe_allocate_available_register(f); 00508 int back_stencil = emit_stencil_test(dsa, 1, f, mask, 00509 depth_mask, depth_complement, 00510 stencil, back_depth_pass); 00511 00512 /* If the front facing stencil value and the back facing stencil 00513 * value are stored in the same register, there is no need to select 00514 * a value based on the facing. This can happen if the stencil value 00515 * was not modified due to the write masks being zero, the stencil 00516 * operations being KEEP, etc. 00517 */ 00518 if (front_stencil != back_stencil) { 00519 spe_selb(f, stencil, back_stencil, front_stencil, facing); 00520 } 00521 00522 if (back_stencil != stencil) { 00523 spe_release_register(f, back_stencil); 00524 } 00525 00526 if (front_stencil != stencil) { 00527 spe_release_register(f, front_stencil); 00528 } 00529 00530 spe_selb(f, mask, back_depth_pass, front_depth_pass, facing); 00531 00532 spe_release_register(f, back_depth_pass); 00533 } else { 00534 if (front_stencil != stencil) { 00535 spe_or(f, stencil, front_stencil, front_stencil); 00536 spe_release_register(f, front_stencil); 00537 } 00538 spe_or(f, mask, front_depth_pass, front_depth_pass); 00539 } 00540 00541 spe_release_register(f, front_depth_pass); 00542 } else if (dsa->depth.enabled) { 00543 if (depth_complement) { 00544 spe_andc(f, mask, mask, depth_mask); 00545 } else { 00546 spe_and(f, mask, mask, depth_mask); 00547 } 00548 } 00549 00550 if (dsa->depth.writemask) { 00551 spe_selb(f, depth, depth, zvals, mask); 00552 } 00553 00554 spe_bi(f, 0, 0, 0); /* return from function call */ 00555 00556 00557 #if 0 00558 { 00559 const uint32_t *p = f->store; 00560 unsigned i; 00561 00562 printf("# alpha (%sabled)\n", 00563 (dsa->alpha.enabled) ? "en" : "dis"); 00564 printf("# func: %u\n", dsa->alpha.func); 00565 printf("# ref: %.2f\n", dsa->alpha.ref); 00566 00567 printf("# depth (%sabled)\n", 00568 (dsa->depth.enabled) ? "en" : "dis"); 00569 printf("# func: %u\n", dsa->depth.func); 00570 00571 for (i = 0; i < 2; i++) { 00572 printf("# %s stencil (%sabled)\n", 00573 (i == 0) ? "front" : "back", 00574 (dsa->stencil[i].enabled) ? "en" : "dis"); 00575 00576 printf("# func: %u\n", dsa->stencil[i].func); 00577 printf("# op (sf, zf, zp): %u %u %u\n", 00578 dsa->stencil[i].fail_op, 00579 dsa->stencil[i].zfail_op, 00580 dsa->stencil[i].zpass_op); 00581 printf("# ref value / value mask / write mask: %02x %02x %02x\n", 00582 dsa->stencil[i].ref_value, 00583 dsa->stencil[i].value_mask, 00584 dsa->stencil[i].write_mask); 00585 } 00586 00587 printf("\t.text\n"); 00588 for (/* empty */; p < f->csr; p++) { 00589 printf("\t.long\t0x%04x\n", *p); 00590 } 00591 fflush(stdout); 00592 } 00593 #endif 00594 }
void cell_generate_logic_op | ( | struct spe_function * | f, | |
const struct pipe_blend_state * | blend, | |||
struct pipe_surface * | surf | |||
) |
Generate code to perform color conversion and logic op.
Definition at line 1182 of file cell_state_per_fragment.c.
References assert, ASSERT, pipe_blend_state::colormask, pipe_surface::format, pipe_blend_state::logicop_enable, pipe_blend_state::logicop_func, PC_OFFSET(), PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_LOGICOP_AND, PIPE_LOGICOP_AND_INVERTED, PIPE_LOGICOP_AND_REVERSE, PIPE_LOGICOP_CLEAR, PIPE_LOGICOP_COPY, PIPE_LOGICOP_COPY_INVERTED, PIPE_LOGICOP_EQUIV, PIPE_LOGICOP_INVERT, PIPE_LOGICOP_NAND, PIPE_LOGICOP_NOOP, PIPE_LOGICOP_NOR, PIPE_LOGICOP_OR, PIPE_LOGICOP_OR_INVERTED, PIPE_LOGICOP_OR_REVERSE, PIPE_LOGICOP_SET, PIPE_LOGICOP_XOR, spe_a(), spe_allocate_available_register(), spe_allocate_register(), spe_and(), spe_andc(), spe_bi(), spe_cfltu(), spe_eqv(), spe_il(), spe_ilh(), spe_init_func(), SPE_INST_SIZE, spe_lqr(), spe_nand(), spe_nor(), spe_or(), spe_orc(), spe_selb(), spe_shufb(), spe_xor(), and spe_function::store.
01185 { 01186 const unsigned logic_op = (blend->logicop_enable) 01187 ? blend->logicop_func : PIPE_LOGICOP_COPY; 01188 01189 /* This code generates a maximum of 37 instructions. An additional 32 01190 * bytes (equiv. to 8 instructions) are needed for data storage. Round up 01191 * to 64 to make it a happy power-of-two. 01192 */ 01193 spe_init_func(f, SPE_INST_SIZE * 64); 01194 01195 01196 /* Pixel colors in framebuffer format in AoS layout. 01197 */ 01198 const int pixel[4] = { 01199 spe_allocate_register(f, 3), 01200 spe_allocate_register(f, 4), 01201 spe_allocate_register(f, 5), 01202 spe_allocate_register(f, 6), 01203 }; 01204 01205 /* Fragment colors stored as floats in SoA layout. 01206 */ 01207 const int frag[4] = { 01208 spe_allocate_register(f, 7), 01209 spe_allocate_register(f, 8), 01210 spe_allocate_register(f, 9), 01211 spe_allocate_register(f, 10), 01212 }; 01213 01214 const int mask = spe_allocate_register(f, 11); 01215 01216 01217 /* Short-circuit the noop and invert cases. 01218 */ 01219 if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->colormask == 0)) { 01220 spe_bi(f, 0, 0, 0); 01221 return; 01222 } else if (logic_op == PIPE_LOGICOP_INVERT) { 01223 spe_nor(f, pixel[0], pixel[0], pixel[0]); 01224 spe_nor(f, pixel[1], pixel[1], pixel[1]); 01225 spe_nor(f, pixel[2], pixel[2], pixel[2]); 01226 spe_nor(f, pixel[3], pixel[3], pixel[3]); 01227 spe_bi(f, 0, 0, 0); 01228 return; 01229 } 01230 01231 01232 const int tmp[4] = { 01233 spe_allocate_available_register(f), 01234 spe_allocate_available_register(f), 01235 spe_allocate_available_register(f), 01236 spe_allocate_available_register(f), 01237 }; 01238 01239 const int shuf_xpose_hi = spe_allocate_available_register(f); 01240 const int shuf_xpose_lo = spe_allocate_available_register(f); 01241 const int shuf_color = spe_allocate_available_register(f); 01242 01243 01244 /* Pointer to the begining of the function's private data area. 01245 */ 01246 uint32_t *const data = ((uint32_t *) f->store) + (64 - 8); 01247 01248 01249 /* Convert fragment colors to framebuffer format in AoS layout. 01250 */ 01251 switch (surf->format) { 01252 case PIPE_FORMAT_A8R8G8B8_UNORM: 01253 data[0] = 0x00010203; 01254 data[1] = 0x10111213; 01255 data[2] = 0x04050607; 01256 data[3] = 0x14151617; 01257 data[4] = 0x0c000408; 01258 data[5] = 0x80808080; 01259 data[6] = 0x80808080; 01260 data[7] = 0x80808080; 01261 break; 01262 case PIPE_FORMAT_B8G8R8A8_UNORM: 01263 data[0] = 0x03020100; 01264 data[1] = 0x13121110; 01265 data[2] = 0x07060504; 01266 data[3] = 0x17161514; 01267 data[4] = 0x0804000c; 01268 data[5] = 0x80808080; 01269 data[6] = 0x80808080; 01270 data[7] = 0x80808080; 01271 break; 01272 default: 01273 fprintf(stderr, "CELL: Bad pixel format in cell_generate_logic_op()"); 01274 ASSERT(0); 01275 } 01276 01277 spe_ilh(f, tmp[0], 0x0808); 01278 spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0)); 01279 spe_lqr(f, shuf_color, PC_OFFSET(f, data+4)); 01280 spe_a(f, shuf_xpose_lo, shuf_xpose_hi, tmp[0]); 01281 01282 spe_shufb(f, tmp[0], frag[0], frag[2], shuf_xpose_hi); 01283 spe_shufb(f, tmp[1], frag[0], frag[2], shuf_xpose_lo); 01284 spe_shufb(f, tmp[2], frag[1], frag[3], shuf_xpose_hi); 01285 spe_shufb(f, tmp[3], frag[1], frag[3], shuf_xpose_lo); 01286 01287 spe_shufb(f, frag[0], tmp[0], tmp[2], shuf_xpose_hi); 01288 spe_shufb(f, frag[1], tmp[0], tmp[2], shuf_xpose_lo); 01289 spe_shufb(f, frag[2], tmp[1], tmp[3], shuf_xpose_hi); 01290 spe_shufb(f, frag[3], tmp[1], tmp[3], shuf_xpose_lo); 01291 01292 spe_cfltu(f, frag[0], frag[0], 32); 01293 spe_cfltu(f, frag[1], frag[1], 32); 01294 spe_cfltu(f, frag[2], frag[2], 32); 01295 spe_cfltu(f, frag[3], frag[3], 32); 01296 01297 spe_shufb(f, frag[0], frag[0], pixel[0], shuf_color); 01298 spe_shufb(f, frag[1], frag[1], pixel[1], shuf_color); 01299 spe_shufb(f, frag[2], frag[2], pixel[2], shuf_color); 01300 spe_shufb(f, frag[3], frag[3], pixel[3], shuf_color); 01301 01302 01303 /* If logic op is enabled, perform the requested logical operation on the 01304 * converted fragment colors and the pixel colors. 01305 */ 01306 switch (logic_op) { 01307 case PIPE_LOGICOP_CLEAR: 01308 spe_il(f, frag[0], 0); 01309 spe_il(f, frag[1], 0); 01310 spe_il(f, frag[2], 0); 01311 spe_il(f, frag[3], 0); 01312 break; 01313 case PIPE_LOGICOP_NOR: 01314 spe_nor(f, frag[0], frag[0], pixel[0]); 01315 spe_nor(f, frag[1], frag[1], pixel[1]); 01316 spe_nor(f, frag[2], frag[2], pixel[2]); 01317 spe_nor(f, frag[3], frag[3], pixel[3]); 01318 break; 01319 case PIPE_LOGICOP_AND_INVERTED: 01320 spe_andc(f, frag[0], pixel[0], frag[0]); 01321 spe_andc(f, frag[1], pixel[1], frag[1]); 01322 spe_andc(f, frag[2], pixel[2], frag[2]); 01323 spe_andc(f, frag[3], pixel[3], frag[3]); 01324 break; 01325 case PIPE_LOGICOP_COPY_INVERTED: 01326 spe_nor(f, frag[0], frag[0], frag[0]); 01327 spe_nor(f, frag[1], frag[1], frag[1]); 01328 spe_nor(f, frag[2], frag[2], frag[2]); 01329 spe_nor(f, frag[3], frag[3], frag[3]); 01330 break; 01331 case PIPE_LOGICOP_AND_REVERSE: 01332 spe_andc(f, frag[0], frag[0], pixel[0]); 01333 spe_andc(f, frag[1], frag[1], pixel[1]); 01334 spe_andc(f, frag[2], frag[2], pixel[2]); 01335 spe_andc(f, frag[3], frag[3], pixel[3]); 01336 break; 01337 case PIPE_LOGICOP_XOR: 01338 spe_xor(f, frag[0], frag[0], pixel[0]); 01339 spe_xor(f, frag[1], frag[1], pixel[1]); 01340 spe_xor(f, frag[2], frag[2], pixel[2]); 01341 spe_xor(f, frag[3], frag[3], pixel[3]); 01342 break; 01343 case PIPE_LOGICOP_NAND: 01344 spe_nand(f, frag[0], frag[0], pixel[0]); 01345 spe_nand(f, frag[1], frag[1], pixel[1]); 01346 spe_nand(f, frag[2], frag[2], pixel[2]); 01347 spe_nand(f, frag[3], frag[3], pixel[3]); 01348 break; 01349 case PIPE_LOGICOP_AND: 01350 spe_and(f, frag[0], frag[0], pixel[0]); 01351 spe_and(f, frag[1], frag[1], pixel[1]); 01352 spe_and(f, frag[2], frag[2], pixel[2]); 01353 spe_and(f, frag[3], frag[3], pixel[3]); 01354 break; 01355 case PIPE_LOGICOP_EQUIV: 01356 spe_eqv(f, frag[0], frag[0], pixel[0]); 01357 spe_eqv(f, frag[1], frag[1], pixel[1]); 01358 spe_eqv(f, frag[2], frag[2], pixel[2]); 01359 spe_eqv(f, frag[3], frag[3], pixel[3]); 01360 break; 01361 case PIPE_LOGICOP_OR_INVERTED: 01362 spe_orc(f, frag[0], pixel[0], frag[0]); 01363 spe_orc(f, frag[1], pixel[1], frag[1]); 01364 spe_orc(f, frag[2], pixel[2], frag[2]); 01365 spe_orc(f, frag[3], pixel[3], frag[3]); 01366 break; 01367 case PIPE_LOGICOP_COPY: 01368 break; 01369 case PIPE_LOGICOP_OR_REVERSE: 01370 spe_orc(f, frag[0], frag[0], pixel[0]); 01371 spe_orc(f, frag[1], frag[1], pixel[1]); 01372 spe_orc(f, frag[2], frag[2], pixel[2]); 01373 spe_orc(f, frag[3], frag[3], pixel[3]); 01374 break; 01375 case PIPE_LOGICOP_OR: 01376 spe_or(f, frag[0], frag[0], pixel[0]); 01377 spe_or(f, frag[1], frag[1], pixel[1]); 01378 spe_or(f, frag[2], frag[2], pixel[2]); 01379 spe_or(f, frag[3], frag[3], pixel[3]); 01380 break; 01381 case PIPE_LOGICOP_SET: 01382 spe_il(f, frag[0], ~0); 01383 spe_il(f, frag[1], ~0); 01384 spe_il(f, frag[2], ~0); 01385 spe_il(f, frag[3], ~0); 01386 break; 01387 01388 /* These two cases are short-circuited above. 01389 */ 01390 case PIPE_LOGICOP_INVERT: 01391 case PIPE_LOGICOP_NOOP: 01392 default: 01393 assert(0); 01394 } 01395 01396 01397 /* Apply fragment mask. 01398 */ 01399 spe_ilh(f, tmp[0], 0x0000); 01400 spe_ilh(f, tmp[1], 0x0404); 01401 spe_ilh(f, tmp[2], 0x0808); 01402 spe_ilh(f, tmp[3], 0x0c0c); 01403 01404 spe_shufb(f, tmp[0], mask, mask, tmp[0]); 01405 spe_shufb(f, tmp[1], mask, mask, tmp[1]); 01406 spe_shufb(f, tmp[2], mask, mask, tmp[2]); 01407 spe_shufb(f, tmp[3], mask, mask, tmp[3]); 01408 01409 spe_selb(f, pixel[0], pixel[0], frag[0], tmp[0]); 01410 spe_selb(f, pixel[1], pixel[1], frag[1], tmp[1]); 01411 spe_selb(f, pixel[2], pixel[2], frag[2], tmp[2]); 01412 spe_selb(f, pixel[3], pixel[3], frag[3], tmp[3]); 01413 01414 spe_bi(f, 0, 0, 0); 01415 01416 #if 0 01417 { 01418 const uint32_t *p = f->store; 01419 unsigned i; 01420 01421 printf("# %u instructions\n", f->csr - f->store); 01422 01423 printf("\t.text\n"); 01424 for (i = 0; i < 64; i++) { 01425 printf("\t.long\t0x%04x\n", p[i]); 01426 } 01427 fflush(stdout); 01428 } 01429 #endif 01430 }