Ben Skeggs
2010-May-31 01:44 UTC
[Nouveau] [PATCH] nv50/exa: use dual-source blending for component-alpha composite
From: Ben Skeggs <bskeggs at redhat.com> --- src/nv50_accel.c | 38 ++++++++------------------------------ src/nv50_accel.h | 1 - src/nv50_exa.c | 45 ++++++++++++++++++++------------------------- 3 files changed, 28 insertions(+), 56 deletions(-) diff --git a/src/nv50_accel.c b/src/nv50_accel.c index 1218e18..db8c744 100644 --- a/src/nv50_accel.c +++ b/src/nv50_accel.c @@ -213,7 +213,7 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn) OUT_RING (chan, (0 << NV50TCL_CB_DEF_SET_BUFFER_SHIFT) | 0x4000); BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, 0); - BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), 16); + BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), 22); OUT_RING (chan, 0x80000000); OUT_RING (chan, 0x90000004); OUT_RING (chan, 0x82030210); @@ -228,36 +228,14 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn) OUT_RING (chan, 0xc0050204); OUT_RING (chan, 0xc0060409); OUT_RING (chan, 0x00000780); - OUT_RING (chan, 0xc007060d); - OUT_RING (chan, 0x00000781); - BEGIN_RING(chan, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_CCASA, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_CCASA, - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { - MARK_UNDO(chan); - return FALSE; - } - OUT_RING (chan, (0 << NV50TCL_CB_DEF_SET_BUFFER_SHIFT) | 0x4000); - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); - OUT_RING (chan, 0); - BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), 16); - OUT_RING (chan, 0x80000000); - OUT_RING (chan, 0x90000004); - OUT_RING (chan, 0x82030200); - OUT_RING (chan, 0x82040204); - OUT_RING (chan, 0x82010210); - OUT_RING (chan, 0x82020214); - OUT_RING (chan, 0xf6400201); - OUT_RING (chan, 0x0000c784); - OUT_RING (chan, 0xf0400011); - OUT_RING (chan, 0x00008784); - OUT_RING (chan, 0xc0040000); - OUT_RING (chan, 0xc0040204); - OUT_RING (chan, 0xc0040409); + OUT_RING (chan, 0xc0040610); + OUT_RING (chan, 0xc0050614); + OUT_RING (chan, 0xc0060619); OUT_RING (chan, 0x00000780); - OUT_RING (chan, 0xc004060d); - OUT_RING (chan, 0x00000781); + OUT_RING (chan, 0xc007061d); + OUT_RING (chan, 0x00000780); + OUT_RING (chan, 0x10000e0d); + OUT_RING (chan, 0x0403c781); BEGIN_RING(chan, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_S_A8, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || diff --git a/src/nv50_accel.h b/src/nv50_accel.h index f5ccd92..4a885b5 100644 --- a/src/nv50_accel.h +++ b/src/nv50_accel.h @@ -11,7 +11,6 @@ #define PFP_S 0x0000 /* (src) */ #define PFP_C 0x0100 /* (src IN mask) */ #define PFP_CCA 0x0200 /* (src IN mask) component-alpha */ -#define PFP_CCASA 0x0300 /* (src IN mask) component-alpha src-alpha */ #define PFP_S_A8 0x0400 /* (src) a8 rt */ #define PFP_C_A8 0x0500 /* (src IN mask) a8 rt - same for CA and CA_SA */ #define PFP_NV12 0x0600 /* NV12 YUV->RGB */ diff --git a/src/nv50_exa.c b/src/nv50_exa.c index e86f903..8bacdf0 100644 --- a/src/nv50_exa.c +++ b/src/nv50_exa.c @@ -751,7 +751,7 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) NV50EXA_LOCALS(ppix); struct nv50_blend_op *b = &NV50EXABlendOp[op]; unsigned sblend = b->src_blend; - unsigned dblend = b->dst_blend; + unsigned dblend = b->dst_blend, dblend_a = b->dst_blend; if (b->dst_alpha) { if (!PICT_FORMAT_A(ppict->format)) { @@ -764,11 +764,18 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) } if (b->src_alpha && component_alpha) { - if (dblend == BF(SRC_ALPHA)) - dblend = BF(SRC_COLOR); - else - if (dblend == BF(ONE_MINUS_SRC_ALPHA)) - dblend = BF(ONE_MINUS_SRC_COLOR); + switch (dblend) { + case BF(SRC_ALPHA): + dblend = BF(SRC1_COLOR); + dblend_a = BF(SRC1_ALPHA); + break; + case BF(ONE_MINUS_SRC_ALPHA): + dblend = BF(ONE_MINUS_SRC1_COLOR); + dblend_a = BF(ONE_MINUS_SRC1_ALPHA); + break; + default: + break; + } } if (sblend == BF(ONE) && dblend == BF(ZERO)) { @@ -784,7 +791,7 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) OUT_RING (chan, NV50TCL_BLEND_EQUATION_ALPHA_FUNC_ADD); OUT_RING (chan, sblend); BEGIN_RING(chan, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); - OUT_RING (chan, dblend); + OUT_RING (chan, dblend_a); } } @@ -802,12 +809,6 @@ NV50EXACheckComposite(int op, NOUVEAU_FALLBACK("src picture invalid\n"); if (pmpict) { - if (pmpict->componentAlpha && - PICT_FORMAT_RGB(pmpict->format) && - NV50EXABlendOp[op].src_alpha && - NV50EXABlendOp[op].src_blend != BF(ZERO)) - NOUVEAU_FALLBACK("component-alpha not supported\n"); - if (!NV50EXACheckTexture(pmpict, pdpict, op)) NOUVEAU_FALLBACK("mask picture invalid\n"); } @@ -874,19 +875,13 @@ NV50EXAPrepareComposite(int op, state->have_mask = TRUE; BEGIN_RING(chan, tesla, NV50TCL_FP_START_ID, 1); - if (pdpict->format == PICT_a8) { + if (pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)) + OUT_RING (chan, PFP_CCA); + else + if (pdpict->format != PICT_a8) + OUT_RING (chan, PFP_C); + else OUT_RING (chan, PFP_C_A8); - } else { - if (pmpict->componentAlpha && - PICT_FORMAT_RGB(pmpict->format)) { - if (NV50EXABlendOp[op].src_alpha) - OUT_RING (chan, PFP_CCASA); - else - OUT_RING (chan, PFP_CCA); - } else { - OUT_RING (chan, PFP_C); - } - } } else { state->have_mask = FALSE; -- 1.7.0.1
Ben Skeggs
2010-May-31 01:49 UTC
[Nouveau] [PATCH] nv50/exa: use dual-source blending for component-alpha composite
On Mon, 2010-05-31 at 11:44 +1000, Ben Skeggs wrote:> From: Ben Skeggs <bskeggs at redhat.com>This is the result of some playing around, thought it'd be useful so sending to the list for some sanity checking first, particularly in the shader setup. I would assume we'd need to in the very least bump up FP_REG_ALLOC_TEMP from its default? I had to in a test, but this passes rendercheck etc fine even without. This removes the need for the two-pass CA Over rendering pass by EXA, and allows us to accelerate a few other CA composite operations that we couldn't previously. Ben.> > --- > src/nv50_accel.c | 38 ++++++++------------------------------ > src/nv50_accel.h | 1 - > src/nv50_exa.c | 45 ++++++++++++++++++++------------------------- > 3 files changed, 28 insertions(+), 56 deletions(-) > > diff --git a/src/nv50_accel.c b/src/nv50_accel.c > index 1218e18..db8c744 100644 > --- a/src/nv50_accel.c > +++ b/src/nv50_accel.c > @@ -213,7 +213,7 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn) > OUT_RING (chan, (0 << NV50TCL_CB_DEF_SET_BUFFER_SHIFT) | 0x4000); > BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); > OUT_RING (chan, 0); > - BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), 16); > + BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), 22); > OUT_RING (chan, 0x80000000); > OUT_RING (chan, 0x90000004); > OUT_RING (chan, 0x82030210); > @@ -228,36 +228,14 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn) > OUT_RING (chan, 0xc0050204); > OUT_RING (chan, 0xc0060409); > OUT_RING (chan, 0x00000780); > - OUT_RING (chan, 0xc007060d); > - OUT_RING (chan, 0x00000781); > - BEGIN_RING(chan, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); > - if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_CCASA, > - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || > - OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_CCASA, > - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) { > - MARK_UNDO(chan); > - return FALSE; > - } > - OUT_RING (chan, (0 << NV50TCL_CB_DEF_SET_BUFFER_SHIFT) | 0x4000); > - BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); > - OUT_RING (chan, 0); > - BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), 16); > - OUT_RING (chan, 0x80000000); > - OUT_RING (chan, 0x90000004); > - OUT_RING (chan, 0x82030200); > - OUT_RING (chan, 0x82040204); > - OUT_RING (chan, 0x82010210); > - OUT_RING (chan, 0x82020214); > - OUT_RING (chan, 0xf6400201); > - OUT_RING (chan, 0x0000c784); > - OUT_RING (chan, 0xf0400011); > - OUT_RING (chan, 0x00008784); > - OUT_RING (chan, 0xc0040000); > - OUT_RING (chan, 0xc0040204); > - OUT_RING (chan, 0xc0040409); > + OUT_RING (chan, 0xc0040610); > + OUT_RING (chan, 0xc0050614); > + OUT_RING (chan, 0xc0060619); > OUT_RING (chan, 0x00000780); > - OUT_RING (chan, 0xc004060d); > - OUT_RING (chan, 0x00000781); > + OUT_RING (chan, 0xc007061d); > + OUT_RING (chan, 0x00000780); > + OUT_RING (chan, 0x10000e0d); > + OUT_RING (chan, 0x0403c781); > BEGIN_RING(chan, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); > if (OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET + PFP_S_A8, > NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) || > diff --git a/src/nv50_accel.h b/src/nv50_accel.h > index f5ccd92..4a885b5 100644 > --- a/src/nv50_accel.h > +++ b/src/nv50_accel.h > @@ -11,7 +11,6 @@ > #define PFP_S 0x0000 /* (src) */ > #define PFP_C 0x0100 /* (src IN mask) */ > #define PFP_CCA 0x0200 /* (src IN mask) component-alpha */ > -#define PFP_CCASA 0x0300 /* (src IN mask) component-alpha src-alpha */ > #define PFP_S_A8 0x0400 /* (src) a8 rt */ > #define PFP_C_A8 0x0500 /* (src IN mask) a8 rt - same for CA and CA_SA */ > #define PFP_NV12 0x0600 /* NV12 YUV->RGB */ > diff --git a/src/nv50_exa.c b/src/nv50_exa.c > index e86f903..8bacdf0 100644 > --- a/src/nv50_exa.c > +++ b/src/nv50_exa.c > @@ -751,7 +751,7 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) > NV50EXA_LOCALS(ppix); > struct nv50_blend_op *b = &NV50EXABlendOp[op]; > unsigned sblend = b->src_blend; > - unsigned dblend = b->dst_blend; > + unsigned dblend = b->dst_blend, dblend_a = b->dst_blend; > > if (b->dst_alpha) { > if (!PICT_FORMAT_A(ppict->format)) { > @@ -764,11 +764,18 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) > } > > if (b->src_alpha && component_alpha) { > - if (dblend == BF(SRC_ALPHA)) > - dblend = BF(SRC_COLOR); > - else > - if (dblend == BF(ONE_MINUS_SRC_ALPHA)) > - dblend = BF(ONE_MINUS_SRC_COLOR); > + switch (dblend) { > + case BF(SRC_ALPHA): > + dblend = BF(SRC1_COLOR); > + dblend_a = BF(SRC1_ALPHA); > + break; > + case BF(ONE_MINUS_SRC_ALPHA): > + dblend = BF(ONE_MINUS_SRC1_COLOR); > + dblend_a = BF(ONE_MINUS_SRC1_ALPHA); > + break; > + default: > + break; > + } > } > > if (sblend == BF(ONE) && dblend == BF(ZERO)) { > @@ -784,7 +791,7 @@ NV50EXABlend(PixmapPtr ppix, PicturePtr ppict, int op, int component_alpha) > OUT_RING (chan, NV50TCL_BLEND_EQUATION_ALPHA_FUNC_ADD); > OUT_RING (chan, sblend); > BEGIN_RING(chan, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); > - OUT_RING (chan, dblend); > + OUT_RING (chan, dblend_a); > } > } > > @@ -802,12 +809,6 @@ NV50EXACheckComposite(int op, > NOUVEAU_FALLBACK("src picture invalid\n"); > > if (pmpict) { > - if (pmpict->componentAlpha && > - PICT_FORMAT_RGB(pmpict->format) && > - NV50EXABlendOp[op].src_alpha && > - NV50EXABlendOp[op].src_blend != BF(ZERO)) > - NOUVEAU_FALLBACK("component-alpha not supported\n"); > - > if (!NV50EXACheckTexture(pmpict, pdpict, op)) > NOUVEAU_FALLBACK("mask picture invalid\n"); > } > @@ -874,19 +875,13 @@ NV50EXAPrepareComposite(int op, > state->have_mask = TRUE; > > BEGIN_RING(chan, tesla, NV50TCL_FP_START_ID, 1); > - if (pdpict->format == PICT_a8) { > + if (pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)) > + OUT_RING (chan, PFP_CCA); > + else > + if (pdpict->format != PICT_a8) > + OUT_RING (chan, PFP_C); > + else > OUT_RING (chan, PFP_C_A8); > - } else { > - if (pmpict->componentAlpha && > - PICT_FORMAT_RGB(pmpict->format)) { > - if (NV50EXABlendOp[op].src_alpha) > - OUT_RING (chan, PFP_CCASA); > - else > - OUT_RING (chan, PFP_CCA); > - } else { > - OUT_RING (chan, PFP_C); > - } > - } > } else { > state->have_mask = FALSE; >