From 60edf2a87b928f413385443335493cb27da30a48 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 24 Apr 2012 10:54:51 +1000 Subject: nv40/exa: support for solid pictures Signed-off-by: Ben Skeggs --- src/nv04_accel.h | 1 + src/nv40_exa.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/nv04_accel.h b/src/nv04_accel.h index 7100e85..e7b76c5 100644 --- a/src/nv04_accel.h +++ b/src/nv04_accel.h @@ -17,6 +17,7 @@ #define PFP_NV12_BILINEAR 0x00000700 #define PFP_NV12_BICUBIC 0x00000800 #define XV_TABLE 0x00001000 +#define SOLID(i) (0x00002000 + (i) * 0x100) /* subchannel assignments */ #define SUBC_M2MF(mthd) 0, (mthd) diff --git a/src/nv40_exa.c b/src/nv40_exa.c index fb9ec80..10f15f1 100644 --- a/src/nv40_exa.c +++ b/src/nv40_exa.c @@ -181,9 +181,64 @@ NV40_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend, } static Bool -NV40EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) +NV40EXAPictSolid(NVPtr pNv, PicturePtr pPict, int unit) +{ + struct nouveau_pushbuf *push = pNv->pushbuf; + + PUSH_DATAu(push, pNv->scratch, SOLID(unit), 2); + PUSH_DATA (push, pPict->pSourcePict->solidFill.color); + PUSH_DATA (push, 0); + BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8); + PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), pNv->scratch, SOLID(unit), + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + PUSH_DATA (push, NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8 | 0x8000 | + NV40_3D_TEX_FORMAT_LINEAR | + NV30_3D_TEX_FORMAT_DIMS_2D | + NV30_3D_TEX_FORMAT_NO_BORDER | + (1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT) | + NV30_3D_TEX_FORMAT_DMA0); + PUSH_DATA (push, NV30_3D_TEX_WRAP_S_REPEAT | + NV30_3D_TEX_WRAP_T_REPEAT | + NV30_3D_TEX_WRAP_R_REPEAT); + PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE); + PUSH_DATA (push, 0x0000aae4); + PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST | + NV30_3D_TEX_FILTER_MAG_NEAREST | 0x3fd6); + PUSH_DATA (push, 0x00010001); + PUSH_DATA (push, 0x00000000); + BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1); + PUSH_DATA (push, 0x00100040); + + BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 17); + PUSH_DATA (push, unit * 4); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 1.0); + PUSH_DATAf(push, 0.0); + PUSH_DATAf(push, 0.0); + return TRUE; +} + +static Bool +NV40EXAPictGradient(NVPtr pNv, PicturePtr pPict, int unit) +{ + return TRUE; +} + +static Bool +NV40EXAPictTexture(NVPtr pNv, PixmapPtr pPix, PicturePtr pPict, int unit) { - NVPtr pNv = NVPTR(pScrn); unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR; struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(pPix); @@ -278,6 +333,24 @@ NV40EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) return TRUE; } +static Bool +NV40EXAPicture(NVPtr pNv, PixmapPtr ppix, PicturePtr ppict, int unit) +{ + if (ppict->pDrawable) + return NV40EXAPictTexture(pNv, ppix, ppict, unit); + + switch (ppict->pSourcePict->type) { + case SourcePictTypeSolidFill: + return NV40EXAPictSolid(pNv, ppict, unit); + case SourcePictTypeLinear: + return NV40EXAPictGradient(pNv, ppict, unit); + default: + break; + } + + return FALSE; +} + static Bool NV40_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PictFormatShort format) { @@ -305,13 +378,19 @@ static Bool NV40EXACheckCompositeTexture(PicturePtr pPict, PicturePtr pdPict, int op) { nv_pict_texture_format_t *fmt; - int w, h; - - if (!pPict->pDrawable) - NOUVEAU_FALLBACK("Solid and gradient pictures unsupported\n"); + int w = 1, h = 1; - w = pPict->pDrawable->width; - h = pPict->pDrawable->height; + if (pPict->pDrawable) { + w = pPict->pDrawable->width; + h = pPict->pDrawable->height; + } else { + switch (pPict->pSourcePict->type) { + case SourcePictTypeSolidFill: + break; + default: + NOUVEAU_FALLBACK("gradient\n"); + } + } if ((w > 4096) || (h > 4096)) NOUVEAU_FALLBACK("picture too large, %dx%d\n", w, h); @@ -377,7 +456,7 @@ NV40EXAPrepareComposite(int op, PicturePtr psPict, PixmapPtr pmPix, PixmapPtr pdPix) { - ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum]; + ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); nv_pict_op_t *blend = NV40_GetPictOpRec(op); struct nouveau_pushbuf *push = pNv->pushbuf; @@ -392,11 +471,11 @@ NV40EXAPrepareComposite(int op, PicturePtr psPict, PICT_FORMAT_RGB(pmPict->format))); if (!NV40_SetupSurface(pScrn, pdPix, pdPict->format) || - !NV40EXATexture(pScrn, psPix, psPict, 0)) + !NV40EXAPicture(pNv, psPix, psPict, 0)) return FALSE; if (pmPict) { - if (!NV40EXATexture(pScrn, pmPix, pmPict, 1)) + if (!NV40EXAPicture(pNv, pmPix, pmPict, 1)) return FALSE; if (pdPict->format == PICT_a8) { -- cgit v1.2.1