static void setup_blend_function(NVPtr pNv) { struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *celsius = pNv->Nv3D; struct pict_op *op = &nv10_pict_op[pNv->alu]; int src_factor = op->src; int dst_factor = op->dst; if (src_factor == SF(ONE_MINUS_DST_ALPHA) && !PICT_FORMAT_A(pNv->pdpict->format)) /* ONE_MINUS_DST_ALPHA doesn't always do the right thing for * framebuffers without alpha channel. But it's the same as * ZERO in that case. */ src_factor = SF(ZERO); if (effective_component_alpha(pNv->pmpict)) { if (dst_factor == DF(SRC_ALPHA)) dst_factor = DF(SRC_COLOR); else if (dst_factor == DF(ONE_MINUS_SRC_ALPHA)) dst_factor = DF(ONE_MINUS_SRC_COLOR); } BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 2); OUT_RING (chan, src_factor); OUT_RING (chan, dst_factor); BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); OUT_RING (chan, 1); }
static void setup_blend_function(NVPtr pNv, PicturePtr pdpict, int alu) { struct nouveau_pushbuf *push = pNv->pushbuf; struct pict_op *op = &nv10_pict_op[alu]; int src_factor = op->src; int dst_factor = op->dst; if (src_factor == SF(ONE_MINUS_DST_ALPHA) && !PICT_FORMAT_A(pdpict->format)) /* ONE_MINUS_DST_ALPHA doesn't always do the right thing for * framebuffers without alpha channel. But it's the same as * ZERO in that case. */ src_factor = SF(ZERO); if (effective_component_alpha(pNv->pmpict)) { if (dst_factor == DF(SRC_ALPHA)) dst_factor = DF(SRC_COLOR); else if (dst_factor == DF(ONE_MINUS_SRC_ALPHA)) dst_factor = DF(ONE_MINUS_SRC_COLOR); } BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 2); PUSH_DATA (push, src_factor); PUSH_DATA (push, dst_factor); BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1); PUSH_DATA (push, 1); }
static void setup_combiners(NVPtr pNv, PicturePtr src, PicturePtr mask) { struct nouveau_channel *chan = pNv->chan; struct nouveau_grobj *celsius = pNv->Nv3D; uint32_t rc_in_alpha = 0, rc_in_rgb = 0; if (PICT_FORMAT_A(src->format)) rc_in_alpha |= RC_IN_TEX(A, ALPHA, 0); else rc_in_alpha |= RC_IN_ONE(A); if (mask && PICT_FORMAT_A(mask->format)) rc_in_alpha |= RC_IN_TEX(B, ALPHA, 1); else rc_in_alpha |= RC_IN_ONE(B); if (effective_component_alpha(mask)) { if (!needs_src_alpha(pNv->alu)) { /* The alpha channels won't be used for blending. Drop * them, as our pixels only have 4 components... * output_i = src_i * mask_i */ if (PICT_FORMAT_RGB(src->format)) rc_in_rgb |= RC_IN_TEX(A, RGB, 0); } else { /* The RGB channels won't be used for blending. Drop * them. * output_i = src_alpha * mask_i */ if (PICT_FORMAT_A(src->format)) rc_in_rgb |= RC_IN_TEX(A, ALPHA, 0); else rc_in_rgb |= RC_IN_ONE(A); } rc_in_rgb |= RC_IN_TEX(B, RGB, 1); } else { if (PICT_FORMAT_RGB(src->format)) rc_in_rgb |= RC_IN_TEX(A, RGB, 0); if (mask && PICT_FORMAT_A(mask->format)) rc_in_rgb |= RC_IN_TEX(B, ALPHA, 1); else rc_in_rgb |= RC_IN_ONE(B); } BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(0), 1); OUT_RING (chan, rc_in_alpha); BEGIN_RING(chan, celsius, NV10TCL_RC_IN_RGB(0), 1); OUT_RING (chan, rc_in_rgb); }
Bool NV10EXAPrepareComposite(int op, PicturePtr pict_src, PicturePtr pict_mask, PicturePtr pict_dst, PixmapPtr src, PixmapPtr mask, PixmapPtr dst) { ScrnInfoPtr pScrn = xf86ScreenToScrn(dst->drawable.pScreen); NVPtr pNv = NVPTR(pScrn); struct nouveau_pushbuf *push = pNv->pushbuf; uint32_t sc, sa, mc, ma; if (!PUSH_SPACE(push, 128)) return FALSE; PUSH_RESET(push); /* setup render target and blending */ if (!setup_render_target(pNv, pict_dst, dst)) return FALSE; setup_blend_function(pNv, pict_dst, op); /* select picture sources */ if (!setup_picture(pNv, pict_src, src, 0, &sc, &sa)) return FALSE; if (!setup_picture(pNv, pict_mask, mask, 1, &mc, &ma)) return FALSE; /* configure register combiners */ BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(0)), 1); PUSH_DATA (push, sa | ma); BEGIN_NV04(push, NV10_3D(RC_IN_RGB(0)), 1); if (effective_component_alpha(pict_mask)) { if (needs_src_alpha(op)) PUSH_DATA(push, sa | mc); else PUSH_DATA(push, sc | mc); } else { PUSH_DATA(push, sc | ma); } nouveau_pushbuf_bufctx(push, pNv->bufctx); if (nouveau_pushbuf_validate(push)) { nouveau_pushbuf_bufctx(push, NULL); return FALSE; } pNv->pspict = pict_src; pNv->pmpict = pict_mask; return TRUE; }
Bool NV10EXACheckComposite(int op, PicturePtr src, PicturePtr mask, PicturePtr dst) { ScrnInfoPtr pScrn = xf86ScreenToScrn(dst->pDrawable->pScreen); NVPtr pNv = NVPTR(pScrn); if (!check_pict_op(op)) { print_fallback_info("pictop", op, src, mask, dst); return FALSE; } if (!check_render_target(dst)) { print_fallback_info("dst", op, src, mask, dst); return FALSE; } if (!check_texture(pNv, src)) { print_fallback_info("src", op, src, mask, dst); return FALSE; } if (mask) { if (!check_texture(pNv, mask)) { print_fallback_info("mask", op, src, mask, dst); return FALSE; } if (effective_component_alpha(mask) && needs_src(op) && needs_src_alpha(op)) { print_fallback_info("ca-mask", op, src, mask, dst); return FALSE; } } print_fallback_info("Accelerating", op, src, mask, dst); return TRUE; }
Bool NV10EXACheckComposite(int op, PicturePtr src, PicturePtr mask, PicturePtr dst) { if (!check_pict_op(op)) { print_fallback_info("pictop", op, src, mask, dst); return FALSE; } if (!check_render_target(dst)) { print_fallback_info("dst", op, src, mask, dst); return FALSE; } if (!check_texture(src)) { print_fallback_info("src", op, src, mask, dst); return FALSE; } if (mask) { if (!check_texture(mask)) { print_fallback_info("mask", op, src, mask, dst); return FALSE; } if (effective_component_alpha(mask) && needs_src(op) && needs_src_alpha(op)) { print_fallback_info("ca-mask", op, src, mask, dst); return FALSE; } } print_fallback_info("Accelerating", op, src, mask, dst); return TRUE; }