summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-04-19 13:46:03 +1000
committerBen Skeggs <bskeggs@redhat.com>2012-04-24 11:56:04 +1000
commit8ea09db1a1e8dff7c341dc3da17edefda7e56e6d (patch)
tree1eb8d3fe776e41a4329c64e57c8405493e910ea6
parentb48bcc094beecf521899dd63c8fdbccfd534e5cd (diff)
downloadxorg-driver-xf86-video-nouveau-8ea09db1a1e8dff7c341dc3da17edefda7e56e6d.tar.gz
nv50/exa: support solid pictures
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--src/nv50_accel.c4
-rw-r--r--src/nv50_accel.h5
-rw-r--r--src/nv50_exa.c104
3 files changed, 85 insertions, 28 deletions
diff --git a/src/nv50_accel.c b/src/nv50_accel.c
index 086180f..e140db9 100644
--- a/src/nv50_accel.c
+++ b/src/nv50_accel.c
@@ -292,7 +292,7 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn)
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
PUSH_DATA (push, (pNv->scratch->offset + PVP_DATA) >> 32);
PUSH_DATA (push, (pNv->scratch->offset + PVP_DATA));
- PUSH_DATA (push, (CB_PVP << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000);
+ PUSH_DATA (push, (CB_PVP << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 256);
BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
PUSH_DATA (push, 0x00000001 | (CB_PVP << 12));
BEGIN_NV04(push, NV50_3D(VP_START_ID), 1);
@@ -425,7 +425,7 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn)
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
PUSH_DATA (push, (pNv->scratch->offset + PFP_DATA) >> 32);
PUSH_DATA (push, (pNv->scratch->offset + PFP_DATA));
- PUSH_DATA (push, (CB_PFP << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000);
+ PUSH_DATA (push, (CB_PFP << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 256);
BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
PUSH_DATA (push, 0x00000031 | (CB_PFP << 12));
diff --git a/src/nv50_accel.h b/src/nv50_accel.h
index 6fb3dbd..0f9ed5f 100644
--- a/src/nv50_accel.h
+++ b/src/nv50_accel.h
@@ -26,7 +26,8 @@
#define TIC_OFFSET 0x00002000 /* Texture Image Control */
#define TSC_OFFSET 0x00003000 /* Texture Sampler Control */
#define PVP_DATA 0x00004000 /* VP constbuf */
-#define PFP_DATA 0x00005000 /* FP constbuf */
+#define PFP_DATA 0x00004100 /* FP constbuf */
+#define SOLID(i) (0x00006000 + (i) * 0x100)
/* Fragment programs */
#define PFP_S 0x0000 /* (src) */
@@ -72,7 +73,7 @@ PUSH_DATAu(struct nouveau_pushbuf *push, struct nouveau_bo *bo,
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
PUSH_DATA (push, (bo->offset + off) >> 32);
PUSH_DATA (push, (bo->offset + off));
- PUSH_DATA (push, (CB_PSH << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x4000);
+ PUSH_DATA (push, (CB_PSH << NV50_3D_CB_DEF_SET_BUFFER__SHIFT) | 0x2000);
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
PUSH_DATA (push, CB_PSH | (idx << NV50_3D_CB_ADDR_ID__SHIFT));
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), dwords);
diff --git a/src/nv50_exa.c b/src/nv50_exa.c
index 14759c5..cd99e10 100644
--- a/src/nv50_exa.c
+++ b/src/nv50_exa.c
@@ -444,6 +444,7 @@ NV50EXARenderTarget(PixmapPtr ppix, PicturePtr ppict)
NOUVEAU_FALLBACK("invalid picture format\n");
}
+ PUSH_REFN (push, bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
PUSH_DATA (push, bo->offset >> 32);
PUSH_DATA (push, bo->offset);
@@ -462,14 +463,19 @@ NV50EXARenderTarget(PixmapPtr ppix, PicturePtr ppict)
static Bool
NV50EXACheckTexture(PicturePtr ppict, PicturePtr pdpict, int op)
{
- if (!ppict->pDrawable)
- NOUVEAU_FALLBACK("Solid and gradient pictures unsupported\n");
-
- if (ppict->pDrawable->width > 8192 ||
- ppict->pDrawable->height > 8192)
- NOUVEAU_FALLBACK("texture dimensions exceeded %dx%d\n",
- ppict->pDrawable->width,
- ppict->pDrawable->height);
+ if (ppict->pDrawable) {
+ if (ppict->pDrawable->width > 8192 ||
+ ppict->pDrawable->height > 8192)
+ NOUVEAU_FALLBACK("texture too large\n");
+ } else {
+ switch (ppict->pSourcePict->type) {
+ case SourcePictTypeSolidFill:
+ break;
+ default:
+ NOUVEAU_FALLBACK("pict %d\n", ppict->pSourcePict->type);
+ break;
+ }
+ }
switch (ppict->format) {
case PICT_a8r8g8b8:
@@ -524,15 +530,56 @@ NV50EXACheckTexture(PicturePtr ppict, PicturePtr pdpict, int op)
NV50TIC_0_0_FMT_##FMT)
static Bool
-NV50EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit)
+NV50EXAPictSolid(NVPtr pNv, PicturePtr ppict, unsigned unit)
+{
+ uint64_t offset = pNv->scratch->offset + SOLID(unit);
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+
+ PUSH_DATAu(push, pNv->scratch, SOLID(unit), 1);
+ PUSH_DATA (push, ppict->pSourcePict->solidFill.color);
+ PUSH_DATAu(push, pNv->scratch, TIC_OFFSET + (unit * 32), 8);
+ PUSH_DATA (push, _(B_C0, G_C1, R_C2, A_C3, 8_8_8_8));
+ PUSH_DATA (push, offset);
+ PUSH_DATA (push, (offset >> 32) | 0xd005d000);
+ PUSH_DATA (push, 0x00300000);
+ PUSH_DATA (push, 0x00000001);
+ PUSH_DATA (push, 0x00010001);
+ PUSH_DATA (push, 0x03000000);
+ PUSH_DATA (push, 0x00000000);
+ PUSH_DATAu(push, pNv->scratch, TSC_OFFSET + (unit * 32), 8);
+ PUSH_DATA (push, NV50TSC_1_0_WRAPS_REPEAT |
+ NV50TSC_1_0_WRAPT_REPEAT |
+ NV50TSC_1_0_WRAPR_REPEAT | 0x00024000);
+ PUSH_DATA (push, NV50TSC_1_1_MAGF_NEAREST |
+ NV50TSC_1_1_MINF_NEAREST |
+ NV50TSC_1_1_MIPF_NONE);
+ PUSH_DATA (push, 0x00000000);
+ PUSH_DATA (push, 0x00000000);
+ PUSH_DATA (push, 0x00000000);
+ PUSH_DATA (push, 0x00000000);
+ PUSH_DATA (push, 0x00000000);
+ PUSH_DATA (push, 0x00000000);
+
+ return TRUE;
+}
+
+static Bool
+NV50EXAPictGradient(NVPtr pNv, PicturePtr ppict, unsigned unit)
+{
+ return FALSE;
+}
+
+static Bool
+NV50EXAPictTexture(NVPtr pNv, PixmapPtr ppix, PicturePtr ppict, unsigned unit)
{
- NV50EXA_LOCALS(ppix);
struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
+ struct nouveau_pushbuf *push = pNv->pushbuf;
/*XXX: Scanout buffer not tiled, someone needs to figure it out */
if (!nv50_style_tiled_pixmap(ppix))
NOUVEAU_FALLBACK("pixmap is scanout buffer\n");
+ PUSH_REFN (push, bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
PUSH_DATAu(push, pNv->scratch, TIC_OFFSET + (unit * 32), 8);
switch (ppict->format) {
case PICT_a8r8g8b8:
@@ -678,11 +725,28 @@ NV50EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit)
}
PUSH_DATAf(push, 1.0 / ppix->drawable.width);
PUSH_DATAf(push, 1.0 / ppix->drawable.height);
-
return TRUE;
}
static Bool
+NV50EXAPicture(NVPtr pNv, PixmapPtr ppix, PicturePtr ppict, int unit)
+{
+ if (ppict->pDrawable)
+ return NV50EXAPictTexture(pNv, ppix, ppict, unit);
+
+ switch (ppict->pSourcePict->type) {
+ case SourcePictTypeSolidFill:
+ return NV50EXAPictSolid(pNv, ppict, unit);
+ case SourcePictTypeLinear:
+ return NV50EXAPictGradient(pNv, ppict, unit);
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static Bool
NV50EXACheckBlend(int op)
{
if (op > PictOpAdd)
@@ -765,13 +829,12 @@ NV50EXAPrepareComposite(int op,
PicturePtr pspict, PicturePtr pmpict, PicturePtr pdpict,
PixmapPtr pspix, PixmapPtr pmpix, PixmapPtr pdpix)
{
- NV50EXA_LOCALS(pspix);
- struct nouveau_bo *src = nouveau_pixmap_bo(pspix);
- struct nouveau_bo *dst = nouveau_pixmap_bo(pdpix);
- struct nouveau_bo *mask = pmpix ? nouveau_pixmap_bo(pmpix) : NULL;
+ NV50EXA_LOCALS(pdpix);
if (!PUSH_SPACE(push, 256))
NOUVEAU_FALLBACK("space\n");
+ PUSH_RESET(push);
+ PUSH_REFN (push, pNv->scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
BEGIN_NV04(push, SUBC_2D(0x0110), 1);
PUSH_DATA (push, 0);
@@ -782,11 +845,11 @@ NV50EXAPrepareComposite(int op,
NV50EXABlend(pdpix, pdpict, op, pmpict && pmpict->componentAlpha &&
PICT_FORMAT_RGB(pmpict->format));
- if (!NV50EXATexture(pspix, pspict, 0))
+ if (!NV50EXAPicture(pNv, pspix, pspict, 0))
NOUVEAU_FALLBACK("src picture invalid\n");
if (pmpict) {
- if (!NV50EXATexture(pmpix, pmpict, 1))
+ if (!NV50EXAPicture(pNv, pmpix, pmpict, 1))
NOUVEAU_FALLBACK("mask picture invalid\n");
BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
@@ -819,13 +882,6 @@ NV50EXAPrepareComposite(int op,
BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1);
PUSH_DATA (push, 0x203);
- PUSH_RESET(push);
- PUSH_REFN (push, pNv->scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- PUSH_REFN (push, src, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- PUSH_REFN (push, dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- if (pmpict)
- PUSH_REFN (push, mask, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-
nouveau_pushbuf_bufctx(push, pNv->bufctx);
if (nouveau_pushbuf_validate(push)) {
nouveau_pushbuf_bufctx(push, NULL);