All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] exa: add nouveau_exa_pixmap_is_tiled
@ 2009-02-12 22:56 Maarten Maathuis
       [not found] ` <1234479392-1984-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2009-02-12 22:56 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

---
 src/nouveau_exa.c |   19 +++++++++++++++----
 src/nv50_exa.c    |    6 +++---
 src/nv50_xv.c     |    5 +----
 src/nv_proto.h    |    1 +
 4 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index a947a31..3babfd7 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -52,8 +52,7 @@ NVAccelDownloadM2MF(PixmapPtr pspix, int x, int y, int w, int h,
 	unsigned line_len = w * cpp;
 	unsigned src_pitch = 0, src_offset = 0, linear = 0;
 
-	if (pNv->Architecture < NV_ARCH_50 ||
-	    exaGetPixmapOffset(pspix) < pNv->EXADriverPtr->offScreenBase) {
+	if (!nouveau_exa_pixmap_is_tiled(pspix)) {
 		linear     = 1;
 		src_pitch  = exaGetPixmapPitch(pspix);
 		src_offset = (y * src_pitch) + (x * cpp);
@@ -162,8 +161,7 @@ NVAccelUploadM2MF(PixmapPtr pdpix, int x, int y, int w, int h,
 	unsigned line_len = w * cpp;
 	unsigned dst_pitch = 0, dst_offset = 0, linear = 0;
 
-	if (pNv->Architecture < NV_ARCH_50 ||
-	    exaGetPixmapOffset(pdpix) < pNv->EXADriverPtr->offScreenBase) {
+	if (!nouveau_exa_pixmap_is_tiled(pdpix)) {
 		linear     = 1;
 		dst_pitch  = exaGetPixmapPitch(pdpix);
 		dst_offset = (y * dst_pitch) + (x * cpp);
@@ -275,6 +273,19 @@ nouveau_exa_wait_marker(ScreenPtr pScreen, int marker)
 	NVSync(xf86Screens[pScreen->myNum]);
 }
 
+bool
+nouveau_exa_pixmap_is_tiled(PixmapPtr ppix)
+{
+	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+	NVPtr pNv = NVPTR(pScrn);
+
+	if (pNv->Architecture < NV_ARCH_50 ||
+		exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+		return false;
+
+	return true;
+}
+
 static void *
 nouveau_exa_pixmap_map(PixmapPtr ppix)
 {
diff --git a/src/nv50_exa.c b/src/nv50_exa.c
index 9030d22..96c0aa3 100644
--- a/src/nv50_exa.c
+++ b/src/nv50_exa.c
@@ -117,7 +117,7 @@ NV50EXAAcquireSurface2D(PixmapPtr ppix, int is_src)
 	bo_flags  = NOUVEAU_BO_VRAM;
 	bo_flags |= is_src ? NOUVEAU_BO_RD : NOUVEAU_BO_WR;
 
-	if (exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase) {
+	if (!nouveau_exa_pixmap_is_tiled(ppix)) {
 		BEGIN_RING(chan, eng2d, mthd, 2);
 		OUT_RING  (chan, fmt);
 		OUT_RING  (chan, 1);
@@ -438,7 +438,7 @@ NV50EXARenderTarget(PixmapPtr ppix, PicturePtr ppict)
 	unsigned format;
 
 	/*XXX: Scanout buffer not tiled, someone needs to figure it out */
-	if (exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+	if (!nouveau_exa_pixmap_is_tiled(ppix))
 		NOUVEAU_FALLBACK("pixmap is scanout buffer\n");
 
 	switch (ppict->format) {
@@ -511,7 +511,7 @@ NV50EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit)
 	const unsigned tcb_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
 
 	/*XXX: Scanout buffer not tiled, someone needs to figure it out */
-	if (exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+	if (!nouveau_exa_pixmap_is_tiled(ppix))
 		NOUVEAU_FALLBACK("pixmap is scanout buffer\n");
 
 	BEGIN_RING(chan, tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
diff --git a/src/nv50_xv.c b/src/nv50_xv.c
index 0e7d2c4..1ddfeee 100644
--- a/src/nv50_xv.c
+++ b/src/nv50_xv.c
@@ -39,9 +39,6 @@
 static Bool
 nv50_xv_check_image_put(PixmapPtr ppix)
 {
-	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
-	NVPtr pNv = NVPTR(pScrn);
-
 	switch (ppix->drawable.depth) {
 	case 32:
 	case 24:
@@ -51,7 +48,7 @@ nv50_xv_check_image_put(PixmapPtr ppix)
 		return FALSE;
 	}
 
-	if (exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+	if (!nouveau_exa_pixmap_is_tiled(ppix))
 		return FALSE;
 
 	return TRUE;
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 3cb54ef..cc0d2cc 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -64,6 +64,7 @@ void  NVTakedownDma(ScrnInfoPtr pScrn);
 /* in nouveau_exa.c */
 Bool nouveau_exa_init(ScreenPtr pScreen);
 Bool nouveau_exa_pixmap_is_onscreen(PixmapPtr pPixmap);
+bool nouveau_exa_pixmap_is_tiled(PixmapPtr ppix);
 
 /* in nv_hw.c */
 void NVCalcStateExt(ScrnInfoPtr,struct _riva_hw_state *,int,int,int,int,int,int);
-- 
1.6.1.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] nv50: initial bits for "shadowfb"
       [not found] ` <1234479392-1984-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2009-02-12 22:56   ` Maarten Maathuis
       [not found]     ` <1234479392-1984-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2009-02-12 22:56 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

- Fallbacks on the frontbuffer still need to be handled.
---
 src/Makefile.am          |    1 +
 src/nouveau_exa.c        |    7 +--
 src/nv50_randr.c         |    2 +-
 src/nv50_shadow_damage.c |  164 ++++++++++++++++++++++++++++++++++++++++++++++
 src/nv_driver.c          |   46 ++++++++++++--
 src/nv_proto.h           |    3 +
 src/nv_type.h            |    3 +
 7 files changed, 214 insertions(+), 12 deletions(-)
 create mode 100644 src/nv50_shadow_damage.c

diff --git a/src/Makefile.am b/src/Makefile.am
index f2ba849..4294796 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,6 +79,7 @@ nouveau_drv_la_SOURCES = \
 			 nv50_xv.c \
 			 nv50_texture.h \
 			 nv50reg.h \
+			 nv50_shadow_damage.c \
 			 nouveau_crtc.h \
 			 nouveau_output.h \
 			 nouveau_connector.h \
diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index 3babfd7..c4cafb0 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -279,8 +279,7 @@ nouveau_exa_pixmap_is_tiled(PixmapPtr ppix)
 	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
 	NVPtr pNv = NVPTR(pScrn);
 
-	if (pNv->Architecture < NV_ARCH_50 ||
-		exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+	if (pNv->Architecture < NV_ARCH_50)
 		return false;
 
 	return true;
@@ -437,10 +436,6 @@ nouveau_exa_init(ScreenPtr pScreen)
 	exa->memorySize = pNv->FB->size; 
 
 	if (pNv->Architecture >= NV_ARCH_50) {
-		nouveau_bo_tile(pNv->FB, NOUVEAU_BO_VRAM | NOUVEAU_BO_TILED,
-				exa->offScreenBase,
-				exa->memorySize - exa->offScreenBase);
-
 		exa->maxX = 8192;
 		exa->maxY = 8192;
 	} else
diff --git a/src/nv50_randr.c b/src/nv50_randr.c
index f1cca0c..fcf5d7f 100644
--- a/src/nv50_randr.c
+++ b/src/nv50_randr.c
@@ -99,7 +99,7 @@ nv50_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjuste
 		nv_crtc->crtc->SetFB(nv_crtc->crtc, nv_crtc->shadow);
 		nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, 0, 0);
 	} else {
-		nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->FB);
+		nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->scanout);
 		nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y);
 	}
 	nv_crtc->crtc->ModeSet(nv_crtc->crtc, mode);
diff --git a/src/nv50_shadow_damage.c b/src/nv50_shadow_damage.c
new file mode 100644
index 0000000..9d1a8cb
--- /dev/null
+++ b/src/nv50_shadow_damage.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2009 Maarten Maathuis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * This file serves to process all damage to the frontbuffer pixmap.
+ * This is needed until we can/have:
+ * - Tiled frontbufffer support.
+ * - Working wfb support.
+ * - Widespread wfb exa support.
+ */
+
+#include "nv_include.h"
+
+/* When driver allocated pixmaps are used we can easily fold this back into exa code. */
+static void nv50_shadow_damage_blit(PixmapPtr ppix, RegionPtr pRegion)
+{
+	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+	NVPtr pNv = NVPTR(pScrn);
+	struct nouveau_channel *chan = pNv->chan;
+	struct nouveau_grobj *eng2d = pNv->Nv2D;
+	uint32_t fmt;
+	BoxPtr pbox;
+	int nbox;
+
+	pbox = REGION_RECTS(pRegion);
+	nbox = REGION_NUM_RECTS(pRegion);
+	if (!nbox)
+		return;
+
+	/* flush_notify is not needed, we check for all the ring space in advance. */
+	WAIT_RING (chan, 26 + nbox * 13);
+
+	switch (ppix->drawable.depth) {
+		case 8 : fmt = NV50_2D_SRC_FORMAT_8BPP; break;
+		case 15: fmt = NV50_2D_SRC_FORMAT_15BPP; break;
+		case 16: fmt = NV50_2D_SRC_FORMAT_16BPP; break;
+		case 24: fmt = NV50_2D_SRC_FORMAT_24BPP; break;
+		case 32: fmt = NV50_2D_SRC_FORMAT_32BPP; break;
+		default:
+			 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				    "Unknown surface format for bpp=%d\n",
+				    ppix->drawable.depth);
+			 return;
+	}
+
+	/* tiled source */
+	BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 5);
+	OUT_RING  (chan, fmt);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 1);
+	OUT_RING  (chan, 0);
+
+	BEGIN_RING(chan, eng2d, NV50_2D_SRC_WIDTH, 4);
+	OUT_RING  (chan, ppix->drawable.width);
+	OUT_RING  (chan, ppix->drawable.height);
+	OUT_PIXMAPh(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	OUT_PIXMAPl(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+	/* untiled destination */
+	BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
+	OUT_RING  (chan, fmt);
+	OUT_RING  (chan, 1);
+	BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5);
+	OUT_RING  (chan, NOUVEAU_ALIGN(pScrn->virtualX, 64) *
+			 (pScrn->bitsPerPixel >> 3));
+	OUT_RING  (chan, ppix->drawable.width);
+	OUT_RING  (chan, ppix->drawable.height);
+	OUT_RELOCh(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	OUT_RELOCl(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+	BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, ppix->drawable.width);
+	OUT_RING  (chan, ppix->drawable.height);
+	BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1);
+	OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
+
+	while (nbox--) {
+		BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+		OUT_RING  (chan, pbox->x1);
+		OUT_RING  (chan, pbox->y1);
+		OUT_RING  (chan, pbox->x2 - pbox->x1);
+		OUT_RING  (chan, pbox->y2 - pbox->y1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, 1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, 1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, pbox->x1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, pbox->y1);
+
+		pbox++;
+	}
+}
+
+static void nv50_shadow_damage_report(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+	PixmapPtr ppix = closure;
+
+	nv50_shadow_damage_blit(ppix, pRegion);
+}
+
+static void nv50_shadow_damage_destroy(DamagePtr pDamage, void *closure)
+{
+	PixmapPtr ppix = closure;
+	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+	NVPtr pNv = NVPTR(pScrn);
+
+	pNv->screen_damage = NULL;
+}
+
+bool nv50_shadow_damage_create(ScrnInfoPtr pScrn)
+{
+	NVPtr pNv = NVPTR(pScrn);
+	ScreenPtr pScreen = pScrn->pScreen;
+	PixmapPtr ppix = NULL;
+
+	if (pNv->Architecture < NV_ARCH_50)
+		return false;
+
+	ppix = pScreen->GetScreenPixmap(pScreen);
+	if (!ppix) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			"No screen pixmap.\n");
+		return false;
+	}
+
+	pNv->screen_damage = DamageCreate(nv50_shadow_damage_report, nv50_shadow_damage_destroy, 
+		DamageReportRawRegion, true, pScreen, ppix);
+	if (!pNv->screen_damage) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			"No screen damage\n");
+		return false;
+	}
+
+	/* We want the notification after submission. */
+	DamageSetReportAfterOp(pNv->screen_damage, true);
+
+	DamageRegister(&ppix->drawable, pNv->screen_damage);
+
+	return true;
+}
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 3d6e9ea..c302412 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1580,6 +1580,8 @@ NVMapMemSW(ScrnInfoPtr pScrn)
 		return FALSE;
 	pNv->GART = NULL;
 
+	nouveau_bo_ref(pNv->FB, &pNv->scanout);
+
 	ret = nouveau_bo_fake(&dev, Cursor0Offset,
 			      NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
 			      64*1024, pNv->VRAMMap + Cursor0Offset,
@@ -1625,6 +1627,7 @@ NVMapMem(ScrnInfoPtr pScrn)
 	NVPtr pNv = NVPTR(pScrn);
 	int gart_scratch_size;
 	uint64_t res;
+	uint32_t flags;
 
 	if (pNv->NoAccel)
 		return NVMapMemSW(pScrn);
@@ -1636,15 +1639,39 @@ NVMapMem(ScrnInfoPtr pScrn)
 	nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_AGP_SIZE, &res);
 	pNv->AGPSize=res;
 
-	if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
-		0, pNv->VRAMPhysicalSize / 2, &pNv->FB)) {
-			xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for framebuffer!\n");
-			return FALSE;
-	}
+	flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN;
+	if (pNv->Architecture >= NV_ARCH_50)
+		flags |= NOUVEAU_BO_TILED;
+
+	if (nouveau_bo_new(pNv->dev, flags, 0, pNv->VRAMPhysicalSize / 2,
+			   &pNv->FB)) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Failed to allocate memory for framebuffer!\n");
+		return FALSE;
+ 	}
+
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		"Allocated %dMiB VRAM for framebuffer + offscreen pixmaps, at offset 0x%X\n",
 		(uint32_t)(pNv->FB->size >> 20), (uint32_t) pNv->FB->offset);
 
+	/* Allocate linear scanout. */
+	if (pNv->Architecture >= NV_ARCH_50) {
+		unsigned scanout_size;
+
+		scanout_size = NOUVEAU_ALIGN(pScrn->virtualX, 64);
+		scanout_size *= (pScrn->bitsPerPixel >> 3);
+		scanout_size *= pScrn->virtualY;
+
+		if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
+				   0, scanout_size, &pNv->scanout)) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				   "Failed to allocate scanout buffer\n");
+			return FALSE;
+		}
+	} else {
+		nouveau_bo_ref(pNv->FB, &pNv->scanout);
+	}
+
 	if (pNv->AGPSize) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "AGPGART: %dMiB available\n",
@@ -1743,6 +1770,7 @@ NVUnmapMem(ScrnInfoPtr pScrn)
 	}
 
 	nouveau_bo_ref(NULL, &pNv->FB);
+	nouveau_bo_ref(NULL, &pNv->scanout);
 	nouveau_bo_ref(NULL, &pNv->GART);
 	nouveau_bo_ref(NULL, &pNv->Cursor);
 	nouveau_bo_ref(NULL, &pNv->Cursor2);
@@ -2268,6 +2296,14 @@ NVSaveScreen(ScreenPtr pScreen, int mode)
 	bool on = xf86IsUnblank(mode);
 	int i;
 
+	/* This might seem strange, but we need an entry point after CreateScreenResources.
+	 * This happens to one of the few, if not the only place.
+	 * When we move to driver allocated pixmaps, we can move this.
+	 */
+	if (mode == SCREEN_SAVER_FORCER && pNv->Architecture == NV_ARCH_50 && 
+		!pNv->screen_damage && !nv50_shadow_damage_create(pScrn))
+		return FALSE;
+
 	if (!pNv->randr12_enable)
 		return vgaHWSaveScreen(pScreen, mode);
 
diff --git a/src/nv_proto.h b/src/nv_proto.h
index cc0d2cc..f39c294 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -276,6 +276,9 @@ void nv50_xv_video_stop(ScrnInfoPtr, pointer, Bool);
 int nv50_xv_port_attribute_set(ScrnInfoPtr, Atom, INT32, pointer);
 int nv50_xv_port_attribute_get(ScrnInfoPtr, Atom, INT32 *, pointer);
 
+/* nv50_shadow_damage.c */
+bool nv50_shadow_damage_create(ScrnInfoPtr pScrn);
+
 /* To support EXA 2.0, 2.1 has this in the header */
 #ifndef exaMoveInPixmap
 extern void exaMoveInPixmap(PixmapPtr pPixmap);
diff --git a/src/nv_type.h b/src/nv_type.h
index 6da8561..cd9a45c 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -248,12 +248,15 @@ typedef struct _NVRec {
 
     /* Various pinned memory regions */
     struct nouveau_bo * FB;
+    struct nouveau_bo * scanout;
     //struct nouveau_bo * FB_old; /* for KMS */
     struct nouveau_bo * shadow[2]; /* for easy acces by exa */
     struct nouveau_bo * Cursor;
     struct nouveau_bo * Cursor2;
     struct nouveau_bo * GART;
 
+    DamagePtr screen_damage; /* for NV50+ */
+
     struct nouveau_bios	VBIOS;
     Bool                NoAccel;
     Bool                HWCursor;
-- 
1.6.1.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] nv50: support frontbuffer fallbacks
       [not found]     ` <1234479392-1984-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2009-02-12 22:56       ` Maarten Maathuis
       [not found]         ` <1234479392-1984-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2009-02-12 23:11       ` [PATCH 2/3] nv50: initial bits for "shadowfb" Stephane Marchesin
  1 sibling, 1 reply; 7+ messages in thread
From: Maarten Maathuis @ 2009-02-12 22:56 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

---
 src/nouveau_exa.c        |   36 +++++++++++++++
 src/nv50_shadow_damage.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++
 src/nv_proto.h           |    1 +
 3 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index c4cafb0..b6ae8ca 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -308,6 +308,36 @@ nouveau_exa_pixmap_unmap(PixmapPtr ppix)
 }
 
 static Bool
+nouveau_exa_prepare_access(PixmapPtr ppix, int index)
+{
+	ScreenPtr pScreen = ppix->drawable.pScreen;
+	NVPtr pNv = NVPTR(xf86Screens[pScreen->myNum]);
+
+	if (ppix == pScreen->GetScreenPixmap(pScreen)) {
+		nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR);
+		ppix->devPrivate.ptr = pNv->scanout->map;
+	} else if (nouveau_exa_pixmap_is_tiled(ppix)) {
+		return false; /* force migration */
+	}
+
+	return true;
+}
+
+static void
+nouveau_exa_finish_access(PixmapPtr ppix, int index)
+{
+	ScreenPtr pScreen = ppix->drawable.pScreen;
+	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+	NVPtr pNv = NVPTR(pScrn);
+
+	if (ppix == pScreen->GetScreenPixmap(pScreen)) {
+		ppix->devPrivate.ptr = NULL;
+		nouveau_bo_unmap(pNv->scanout);
+		nv50_shadow_damage_frontbuffer_fallback(pScrn);
+	}
+}
+
+static Bool
 nouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h,
 				 char *dst, int dst_pitch)
 {
@@ -447,6 +477,12 @@ nouveau_exa_init(ScreenPtr pScreen)
 		exa->maxY = 2048;
 	}
 
+	/* Needed for frontbuffer fallbacks (to ensure it accesses the linear fb). */
+	if (pNv->Architecture >= NV_ARCH_50) {
+		exa->PrepareAccess = nouveau_exa_prepare_access;
+		exa->FinishAccess = nouveau_exa_finish_access;
+	}
+
 	exa->MarkSync = nouveau_exa_mark_sync;
 	exa->WaitMarker = nouveau_exa_wait_marker;
 
diff --git a/src/nv50_shadow_damage.c b/src/nv50_shadow_damage.c
index 9d1a8cb..a48cfb2 100644
--- a/src/nv50_shadow_damage.c
+++ b/src/nv50_shadow_damage.c
@@ -29,6 +29,7 @@
  */
 
 #include "nv_include.h"
+#include "damagestr.h"
 
 /* When driver allocated pixmaps are used we can easily fold this back into exa code. */
 static void nv50_shadow_damage_blit(PixmapPtr ppix, RegionPtr pRegion)
@@ -115,6 +116,91 @@ static void nv50_shadow_damage_blit(PixmapPtr ppix, RegionPtr pRegion)
 	}
 }
 
+/* For frontbuffer fallbacks. */
+static void nv50_shadow_damage_blit_back(PixmapPtr ppix, RegionPtr pRegion)
+{
+	ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+	NVPtr pNv = NVPTR(pScrn);
+	struct nouveau_channel *chan = pNv->chan;
+	struct nouveau_grobj *eng2d = pNv->Nv2D;
+	uint32_t fmt;
+	BoxPtr pbox;
+	int nbox;
+
+	pbox = REGION_RECTS(pRegion);
+	nbox = REGION_NUM_RECTS(pRegion);
+	if (!nbox)
+		return;
+
+	/* flush_notify is not needed, we check for all the ring space in advance. */
+	WAIT_RING (chan, 26 + nbox * 13);
+
+	switch (ppix->drawable.depth) {
+		case 8 : fmt = NV50_2D_SRC_FORMAT_8BPP; break;
+		case 15: fmt = NV50_2D_SRC_FORMAT_15BPP; break;
+		case 16: fmt = NV50_2D_SRC_FORMAT_16BPP; break;
+		case 24: fmt = NV50_2D_SRC_FORMAT_24BPP; break;
+		case 32: fmt = NV50_2D_SRC_FORMAT_32BPP; break;
+		default:
+			 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				    "Unknown surface format for bpp=%d\n",
+				    ppix->drawable.depth);
+			 return;
+	}
+
+	/* untiled source */
+	BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2);
+	OUT_RING  (chan, fmt);
+	OUT_RING  (chan, 1);
+	BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5);
+	OUT_RING  (chan, NOUVEAU_ALIGN(pScrn->virtualX, 64) *
+			 (pScrn->bitsPerPixel >> 3));
+	OUT_RING  (chan, ppix->drawable.width);
+	OUT_RING  (chan, ppix->drawable.height);
+	OUT_RELOCh(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	OUT_RELOCl(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+	/* tiled destination */
+	BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5);
+	OUT_RING  (chan, fmt);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 1);
+	OUT_RING  (chan, 0);
+
+	BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 4);
+	OUT_RING  (chan, ppix->drawable.width);
+	OUT_RING  (chan, ppix->drawable.height);
+	OUT_PIXMAPh(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	OUT_PIXMAPl(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+	BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, ppix->drawable.width);
+	OUT_RING  (chan, ppix->drawable.height);
+	BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1);
+	OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
+
+	while (nbox--) {
+		BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+		OUT_RING  (chan, pbox->x1);
+		OUT_RING  (chan, pbox->y1);
+		OUT_RING  (chan, pbox->x2 - pbox->x1);
+		OUT_RING  (chan, pbox->y2 - pbox->y1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, 1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, 1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, pbox->x1);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, pbox->y1);
+
+		pbox++;
+	}
+}
+
 static void nv50_shadow_damage_report(DamagePtr pDamage, RegionPtr pRegion, void *closure)
 {
 	PixmapPtr ppix = closure;
@@ -122,6 +208,28 @@ static void nv50_shadow_damage_report(DamagePtr pDamage, RegionPtr pRegion, void
 	nv50_shadow_damage_blit(ppix, pRegion);
 }
 
+void nv50_shadow_damage_frontbuffer_fallback(ScrnInfoPtr pScrn)
+{
+	NVPtr pNv = NVPTR(pScrn);
+	ScreenPtr pScreen = pScrn->pScreen;
+	PixmapPtr ppix = NULL;
+	DamagePtr pDamage = pNv->screen_damage;
+
+	if (pNv->Architecture < NV_ARCH_50)
+		return;
+
+	ppix = pScreen->GetScreenPixmap(pScreen);
+	if (!ppix) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			"No screen pixmap.\n");
+		return;
+	}
+
+	/* Pending damage reflects the rendering currently being done. */
+	/* When exa calls finish access, damage hasn't flushed it yet. */
+	nv50_shadow_damage_blit_back(ppix, &pDamage->pendingDamage);
+}
+
 static void nv50_shadow_damage_destroy(DamagePtr pDamage, void *closure)
 {
 	PixmapPtr ppix = closure;
diff --git a/src/nv_proto.h b/src/nv_proto.h
index f39c294..f73770d 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -278,6 +278,7 @@ int nv50_xv_port_attribute_get(ScrnInfoPtr, Atom, INT32 *, pointer);
 
 /* nv50_shadow_damage.c */
 bool nv50_shadow_damage_create(ScrnInfoPtr pScrn);
+void nv50_shadow_damage_frontbuffer_fallback(ScrnInfoPtr pScrn);
 
 /* To support EXA 2.0, 2.1 has this in the header */
 #ifndef exaMoveInPixmap
-- 
1.6.1.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] nv50: initial bits for "shadowfb"
       [not found]     ` <1234479392-1984-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2009-02-12 22:56       ` [PATCH 3/3] nv50: support frontbuffer fallbacks Maarten Maathuis
@ 2009-02-12 23:11       ` Stephane Marchesin
       [not found]         ` <6a89f9d50902121511w2b20af44m48b9c48d2fc97175-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 7+ messages in thread
From: Stephane Marchesin @ 2009-02-12 23:11 UTC (permalink / raw)
  To: Maarten Maathuis; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Thu, Feb 12, 2009 at 23:56, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> - Fallbacks on the frontbuffer still need to be handled.
> ---

Why are you posting this again ? It's not really better than the last
time, still a lousy workaround.

Stephane

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] nv50: initial bits for "shadowfb"
       [not found]         ` <6a89f9d50902121511w2b20af44m48b9c48d2fc97175-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2009-02-12 23:22           ` Maarten Maathuis
  0 siblings, 0 replies; 7+ messages in thread
From: Maarten Maathuis @ 2009-02-12 23:22 UTC (permalink / raw)
  To: Stephane Marchesin; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, Feb 13, 2009 at 12:11 AM, Stephane Marchesin
<marchesin-YynmYXH4S6491FlJP1ih0VAUjnlXr6A1@public.gmane.org> wrote:
> On Thu, Feb 12, 2009 at 23:56, Maarten Maathuis <madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> - Fallbacks on the frontbuffer still need to be handled.
>> ---
>
> Why are you posting this again ? It's not really better than the last
> time, still a lousy workaround.
>
> Stephane
>

It's at least correct rendering wise (the last one obviously wasn't).
I was curious about how difficult the implementation would be. I
wanted to put the issue on the table. The hw "fix" is out my reach,
but if anyone wants to give it a shot then be my guest. These patches
are also serve the bridge the gap between now and the moment exa wfb
support becomes reasonable widespread, regardless of hw issues.

Maarten.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] nv50: support frontbuffer fallbacks
       [not found]         ` <1234479392-1984-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2009-02-13  9:19           ` Hervé Cauwelier
       [not found]             ` <49953B0B.6020909-GANU6spQydw@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Hervé Cauwelier @ 2009-02-13  9:19 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Maarten Maathuis a écrit :
> [snip]

I can't tell you about the technical quality of this patch but it made
my day.

When I saw "frontbuffer" I thought about my bug #20066 and applied your
three patches in another branch. Gnome-terminal is now fast as expected,
with the nouveau module loaded.

It will be fine enough for me now. I'll report if it crashes.

Notice that the second patch contains white space.

Hervé
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] nv50: support frontbuffer fallbacks
       [not found]             ` <49953B0B.6020909-GANU6spQydw@public.gmane.org>
@ 2009-02-13 12:31               ` Maarten Maathuis
  0 siblings, 0 replies; 7+ messages in thread
From: Maarten Maathuis @ 2009-02-13 12:31 UTC (permalink / raw)
  To: Hervé Cauwelier; +Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

These patches are workarounds, and therefore will not be applied to git.

I made them out of curiosity.

Maarten.

On Fri, Feb 13, 2009 at 10:19 AM, Hervé Cauwelier
<herve.cauwelier-GANU6spQydw@public.gmane.org> wrote:
> Maarten Maathuis a écrit :
>> [snip]
>
> I can't tell you about the technical quality of this patch but it made
> my day.
>
> When I saw "frontbuffer" I thought about my bug #20066 and applied your
> three patches in another branch. Gnome-terminal is now fast as expected,
> with the nouveau module loaded.
>
> It will be fine enough for me now. I'll report if it crashes.
>
> Notice that the second patch contains white space.
>
> Hervé
> _______________________________________________
> Nouveau mailing list
> Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/nouveau
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-02-13 12:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-12 22:56 [PATCH 1/3] exa: add nouveau_exa_pixmap_is_tiled Maarten Maathuis
     [not found] ` <1234479392-1984-1-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-02-12 22:56   ` [PATCH 2/3] nv50: initial bits for "shadowfb" Maarten Maathuis
     [not found]     ` <1234479392-1984-2-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-02-12 22:56       ` [PATCH 3/3] nv50: support frontbuffer fallbacks Maarten Maathuis
     [not found]         ` <1234479392-1984-3-git-send-email-madman2003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-02-13  9:19           ` Hervé Cauwelier
     [not found]             ` <49953B0B.6020909-GANU6spQydw@public.gmane.org>
2009-02-13 12:31               ` Maarten Maathuis
2009-02-12 23:11       ` [PATCH 2/3] nv50: initial bits for "shadowfb" Stephane Marchesin
     [not found]         ` <6a89f9d50902121511w2b20af44m48b9c48d2fc97175-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-02-12 23:22           ` Maarten Maathuis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.