xf86-video-nouveau:

- remove package xf86-video-nouveau - we now have nvidia binary driver for this
This commit is contained in:
Stephan Raue 2009-12-01 11:07:03 +01:00
parent 70dd4d28e9
commit 36768c089f
10 changed files with 0 additions and 1542 deletions

View File

@ -1,18 +0,0 @@
#!/bin/sh
. config/options
$SCRIPTS/build toolchain
$SCRIPTS/build $MESA
$SCRIPTS/build $LIBDRM
cd $BUILD/$1*
./configure --host=$TARGET_NAME \
--build=$HOST_NAME \
--prefix=/usr \
--sysconfdir=/etc \
--disable-static \
--enable-shared \
--with-xorg-module-dir=$XORG_PATH_MODULES
make

View File

@ -1,6 +0,0 @@
#!/bin/sh
. config/options
mkdir -p $INSTALL/$XORG_PATH_MODULES/drivers
cp $BUILD/$1*/src/.libs/*_drv.so $INSTALL/$XORG_PATH_MODULES/drivers

View File

@ -1,181 +0,0 @@
From 98cd8bd95073e6248a0f63a2b5299736e6d097ef Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:12:25 +1000
Subject: [PATCH 1/6] kms/f11: hack in transition support without driver pixmaps
---
src/drmmode_display.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 142 insertions(+), 2 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index aa8befe..4909e51 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -185,6 +185,139 @@ drmmode_fb_pixmap(ScrnInfoPtr pScrn, int id, int *w, int *h)
}
static void
+drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
+ int src_id, int x, int y)
+{
+ drmModeFBPtr fb;
+ NVPtr pNv = NVPTR(pScrn);
+ char *dst = NULL, *src = NULL;
+ struct drm_nouveau_gem_mmap req;
+ int ret, h;
+
+ /* This is not what this should look like. Until we can do driver
+ * pixmaps, this will be a nasty hack!
+ */
+
+ fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, src_id);
+ if (!fb) {
+ ErrorF("src fb\n");
+ return;
+ }
+
+ req.handle = fb->handle;
+ ret = drmCommandWriteRead(nouveau_device(pNv->dev)->fd,
+ DRM_NOUVEAU_GEM_MMAP, &req, sizeof(req));
+ if (ret) {
+ ErrorF("src bo map: %d\n", ret);
+ drmFree(fb);
+ return;
+ }
+ src = (void *)req.vaddr;
+
+ nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
+ dst = pNv->FB->map;
+ dst += (y * fb->pitch) + (x * (fb->bpp >> 3));
+
+ h = fb->height;
+ while (h--) {
+ memcpy(dst, src, fb->width * (fb->bpp >> 3));
+ src += fb->pitch;
+ dst += pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
+ }
+
+ nouveau_bo_unmap(pNv->FB);
+ drmFree(fb);
+}
+
+static void
+drmmode_fb_copy_nv50(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
+ int src_id, int x, int y)
+{
+ drmModeFBPtr fb;
+ NVPtr pNv = NVPTR(pScrn);
+ struct nouveau_channel *chan = pNv->chan;
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ struct nouveau_bo *src = NULL, *dst = NULL;
+ struct drm_gem_flink req;
+ int ret;
+
+ /* This is not what this should look like. Until we can do driver
+ * pixmaps, this will be a nasty hack!
+ */
+
+ fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, src_id);
+ if (!fb) {
+ ErrorF("src fb\n");
+ return;
+ }
+
+ req.handle = fb->handle;
+ ret = ioctl(nouveau_device(pNv->dev)->fd, DRM_IOCTL_GEM_FLINK, &req);
+ if (ret) {
+ ErrorF("name bo: %d\n", ret);
+ drmFree(fb);
+ return;
+ }
+
+ ret = nouveau_bo_handle_ref(pNv->dev, req.name, &src);
+ if (ret) {
+ ErrorF("src bo: %d\n", ret);
+ drmFree(fb);
+ return;
+ }
+
+ nouveau_bo_ref(pNv->scanout, &dst);
+
+ BEGIN_RING(chan, eng2d, 0x02ac, 1);
+ OUT_RING (chan, 3);
+ BEGIN_RING(chan, eng2d, 0x0200, 2);
+ OUT_RING (chan, pScrn->bitsPerPixel == 16 ? 0xe8 : 0xcf);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, 0x0214, 5);
+ OUT_RING (chan, pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+ OUT_RING (chan, pScrn->virtualX);
+ OUT_RING (chan, pScrn->virtualY);
+ OUT_RELOCh(chan, dst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, dst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BEGIN_RING(chan, eng2d, 0x0280, 4);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, pScrn->virtualX);
+ OUT_RING (chan, pScrn->virtualY);
+ BEGIN_RING(chan, eng2d, 0x0230, 2);
+ OUT_RING (chan, fb->bpp == 16 ? 0xe8 : 0xcf);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, 0x0244, 5);
+ OUT_RING (chan, fb->pitch);
+ OUT_RING (chan, fb->width);
+ OUT_RING (chan, fb->height);
+ OUT_RELOCh(chan, src, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, src, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BEGIN_RING(chan, eng2d, 0x0110, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, eng2d, 0x08b0, 12);
+ OUT_RING (chan, x);
+ OUT_RING (chan, y);
+ OUT_RING (chan, fb->width);
+ OUT_RING (chan, fb->height);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ FIRE_RING (chan);
+
+ nouveau_bo_map(dst, NOUVEAU_BO_RD);
+ nouveau_bo_unmap(dst);
+ nouveau_bo_ref(NULL, &dst);
+ nouveau_bo_ref(NULL, &src);
+ drmFree(fb);
+}
+
+static void
drmmode_fb_copy(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, int src_id,
int x, int y)
{
@@ -194,6 +327,14 @@ drmmode_fb_copy(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, int src_id,
PixmapPtr pspix, pdpix;
int w, h;
+ if (!pNv->exa_driver_pixmaps) {
+ if (pNv->NoAccel)
+ drmmode_fb_copy_sw(pScrn, drmmode, dst_id, src_id, x, y);
+ else
+ drmmode_fb_copy_nv50(pScrn, drmmode, dst_id, src_id, x, y);
+ return;
+ }
+
pspix = drmmode_fb_pixmap(pScrn, src_id, NULL, NULL);
if (!pspix)
return;
@@ -292,8 +433,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (drmmode_crtc->rotate_fb_id)
fb_id = drmmode_crtc->rotate_fb_id;
else
- if (fb_id != drmmode_crtc->mode_crtc->buffer_id &&
- pNv->exa_driver_pixmaps) {
+ if (fb_id != drmmode_crtc->mode_crtc->buffer_id) {
drmmode_fb_copy(pScrn, drmmode, fb_id,
drmmode_crtc->mode_crtc->buffer_id, x, y);
}
--
1.6.2.2

View File

@ -1,51 +0,0 @@
From 514eb5a03b8ca223a4d832e1675cda3a6a56b02d Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:13:26 +1000
Subject: [PATCH 2/6] bios/f11: store a copy of used vbios image in /var/run
---
src/nv_bios.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/nv_bios.c b/src/nv_bios.c
index ebf4027..ad4ff1f 100644
--- a/src/nv_bios.c
+++ b/src/nv_bios.c
@@ -22,6 +22,9 @@
* SOFTWARE.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "nv_include.h"
#if defined(__FreeBSD__) || defined(__NetBSD__)
@@ -4492,7 +4495,10 @@ uint8_t * nouveau_bios_embedded_edid(ScrnInfoPtr pScrn)
bool NVInitVBIOS(ScrnInfoPtr pScrn)
{
+ NVPtr pNv = NVPTR(pScrn);
struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
+ char img[128];
+ int fd;
memset(bios, 0, sizeof(struct nvbios));
@@ -4503,6 +4509,13 @@ bool NVInitVBIOS(ScrnInfoPtr pScrn)
if (bios->length > NV_PROM_SIZE)
bios->length = NV_PROM_SIZE;
+ sprintf(img, "/var/run/nv%02x_%04x.rom", pNv->NVArch, pNv->Chipset);
+ fd = open(img, O_CREAT|O_RDWR|O_EXCL, 0700);
+ if (fd >= 0) {
+ write(fd, bios->data, bios->length);
+ close(fd);
+ }
+
return true;
}
--
1.6.2.2

View File

@ -1,202 +0,0 @@
From e278ea7300169355b17b17a785aef938c3fbc1e3 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:25:25 +1000
Subject: [PATCH 3/6] f11: hack to support multiple xserver instances
---
src/nv_driver.c | 126 ++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 98 insertions(+), 28 deletions(-)
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 92232dd..9f4c96f 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -21,6 +21,7 @@
*/
#include <stdio.h>
+#include <sys/ioctl.h>
#include "nv_include.h"
@@ -654,14 +655,27 @@ NV50ReleaseDisplay(ScrnInfoPtr pScrn)
*/
/* Mandatory */
+static void NVMapMemGART(ScrnInfoPtr);
static Bool
NVEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
NVPtr pNv = NVPTR(pScrn);
+ int ret;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
+ if (pNv->dev) {
+ ret = ioctl(nouveau_device(pNv->dev)->fd,
+ DRM_IOCTL_SET_MASTER, NULL);
+ if (ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to set master\n");
+ }
+
+ NVMapMemGART(pScrn);
+ }
+
if (!pNv->NoAccel)
NVAccelCommonInit(pScrn);
@@ -718,6 +732,12 @@ NVLeaveVT(int scrnIndex, int flags)
NVSync(pScrn);
+ if (pNv->dev) {
+ nouveau_bo_ref(NULL, &pNv->GART);
+
+ ioctl(nouveau_device(pNv->dev)->fd, DRM_IOCTL_DROP_MASTER, NULL);
+ }
+
if (!pNv->kms_enable) {
if (pNv->Architecture < NV_ARCH_50)
NVRestore(pScrn);
@@ -1629,11 +1649,81 @@ NVMapMemSW(ScrnInfoPtr pScrn)
}
static Bool
+NVMapMemSharedFB(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ uint64_t handle, size;
+ void *map;
+ int ret;
+
+ ret = nouveau_device_get_param(pNv->dev, 0xdeadcafe00000001, &handle);
+ if (ret)
+ return FALSE;
+
+ ret = nouveau_device_get_param(pNv->dev, 0xdeadcafe00000002, &size);
+ if (ret)
+ return FALSE;
+
+ if (nouveau_device(pNv->dev)->mm_enabled) {
+ ret = nouveau_bo_handle_ref(pNv->dev, handle, &pNv->FB);
+ if (ret) {
+ ErrorF("%d\n", ret);
+ return FALSE;
+ }
+
+ pNv->FB->size = size;
+ pNv->FB->tiled = (pNv->Architecture == NV_ARCH_50);
+ return TRUE;
+ }
+
+ ret = drmMap(nouveau_device(pNv->dev)->fd, handle >> 32, size, &map);
+ if (ret)
+ return FALSE;
+
+ ret = nouveau_bo_fake(pNv->dev, handle & 0xffffffff, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_PIN, size, map, &pNv->FB);
+ if (ret)
+ return FALSE;
+
+ pNv->FB->tiled = (pNv->Architecture == NV_ARCH_50);
+ return TRUE;
+}
+
+static void
+NVMapMemGART(ScrnInfoPtr pScrn) {
+ NVPtr pNv = NVPTR(pScrn);
+ int size;
+
+ if (pNv->AGPSize) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "AGPGART: %dMiB available\n",
+ (unsigned int)(pNv->AGPSize >> 20));
+ if (pNv->AGPSize > (16*1024*1024))
+ size = 16*1024*1024;
+ else
+ /* always leave 512kb for other things like the fifos */
+ size = pNv->AGPSize - 512*1024;
+ } else {
+ size = (4 << 20) - (1 << 18) ;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "GART: PCI DMA - using %dKiB\n",
+ size >> 10);
+ }
+
+ if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0,
+ size, &pNv->GART)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to allocate GART memory\n");
+ }
+}
+
+static Bool
NVMapMem(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
uint64_t res;
int size;
+ uint32_t flags;
if (!pNv->dev)
return NVMapMemSW(pScrn);
@@ -1650,46 +1740,26 @@ NVMapMem(ScrnInfoPtr pScrn)
size = size * (pScrn->bitsPerPixel >> 3);
size = size * pScrn->virtualY;
} else {
+ if (NVMapMemSharedFB(pScrn))
+ goto skip_fb;
size = pNv->VRAMPhysicalSize / 2;
}
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
- 0, size, &pNv->FB)) {
+ 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, size, &pNv->FB)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to allocate framebuffer memory\n");
return FALSE;
}
+skip_fb:
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);
- if (pNv->AGPSize) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "AGPGART: %dMiB available\n",
- (unsigned int)(pNv->AGPSize >> 20));
- if (pNv->AGPSize > (16*1024*1024))
- size = 16*1024*1024;
- else
- /* always leave 512kb for other things like the fifos */
- size = pNv->AGPSize - 512*1024;
- } else {
- size = (4 << 20) - (1 << 18) ;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "GART: PCI DMA - using %dKiB\n",
- size >> 10);
- }
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0,
- size, &pNv->GART)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unable to allocate GART memory\n");
- }
- if (pNv->GART) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "GART: Allocated %dMiB as a scratch buffer\n",
- (unsigned int)(pNv->GART->size >> 20));
- }
/* We don't need to allocate cursors / lut here if we're using
* kernel modesetting
--
1.6.2.2

View File

@ -1,644 +0,0 @@
From e31aa5217c97dfd1e2c678ce7391fcd255abb0bf Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:30:38 +1000
Subject: [PATCH 4/6] nv50/f11: accelerate front-buffer rendering, linear shadow for scanout
---
src/Makefile.am | 1 +
src/drmmode_display.c | 8 +-
src/nouveau_exa.c | 37 ++++--
src/nv50_randr.c | 2 +-
src/nv50_shadow_damage.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++
src/nv_dri.c | 2 +-
src/nv_driver.c | 38 +++++-
src/nv_proto.h | 4 +
src/nv_shadow.c | 8 +-
src/nv_type.h | 4 +
10 files changed, 387 insertions(+), 23 deletions(-)
create mode 100644 src/nv50_shadow_damage.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 29253a6..0c9e4e9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,6 +81,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/drmmode_display.c b/src/drmmode_display.c
index 4909e51..ca1a60b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -214,8 +214,8 @@ drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
}
src = (void *)req.vaddr;
- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
- dst = pNv->FB->map;
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
+ dst = pNv->scanout->map;
dst += (y * fb->pitch) + (x * (fb->bpp >> 3));
h = fb->height;
@@ -225,7 +225,7 @@ drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
dst += pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
}
- nouveau_bo_unmap(pNv->FB);
+ nouveau_bo_unmap(pNv->scanout);
drmFree(fb);
}
@@ -380,7 +380,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
ret = drmModeAddFB(drmmode->fd,
pScrn->virtualX, pScrn->virtualY,
pScrn->depth, pScrn->bitsPerPixel,
- pitch, pNv->FB->handle, &drmmode->fb_id);
+ pitch, pNv->scanout->handle, &drmmode->fb_id);
if (ret < 0) {
ErrorF("failed to add fb\n");
return FALSE;
diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index b7bcc87..aee2794 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -265,7 +265,8 @@ nouveau_exa_wait_marker(ScreenPtr pScreen, int marker)
static Bool
nouveau_exa_prepare_access(PixmapPtr ppix, int index)
{
- ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ ScreenPtr pScreen = ppix->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
if (pNv->exa_driver_pixmaps) {
@@ -275,20 +276,33 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index)
return FALSE;
ppix->devPrivate.ptr = map;
- return TRUE;
+ } else
+ if (ppix == pScreen->GetScreenPixmap(pScreen)) {
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR);
+ ppix->devPrivate.ptr = pNv->scanout->map;
+ } else {
+ /* force migration */
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
static void
nouveau_exa_finish_access(PixmapPtr ppix, int index)
{
- ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ ScreenPtr pScreen = ppix->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- if (pNv->exa_driver_pixmaps)
+ if (pNv->exa_driver_pixmaps) {
nouveau_exa_pixmap_unmap(ppix);
+ } else
+ if (ppix == pScreen->GetScreenPixmap(pScreen)) {
+ ppix->devPrivate.ptr = NULL;
+ nouveau_bo_unmap(pNv->scanout);
+ nv50_shadow_damage_frontbuffer_fallback(pScrn);
+ }
}
static Bool
@@ -393,8 +407,7 @@ nouveau_exa_pixmap_is_tiled(PixmapPtr ppix)
if (!nouveau_pixmap_bo(ppix)->tiled)
return false;
} else
- if (pNv->Architecture < NV_ARCH_50 ||
- exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+ if (pNv->Architecture < NV_ARCH_50)
return false;
return true;
@@ -406,7 +419,7 @@ nouveau_exa_pixmap_map(PixmapPtr ppix)
struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
unsigned delta = nouveau_pixmap_offset(ppix);
- if (bo->tiled) {
+ if (NVPTR(xf86Screens[ppix->drawable.pScreen->myNum])->GART && bo->tiled) {
struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix);
nvpix->map_refcount++;
@@ -432,7 +445,7 @@ nouveau_exa_pixmap_unmap(PixmapPtr ppix)
{
struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
- if (bo->tiled) {
+ if (NVPTR(xf86Screens[ppix->drawable.pScreen->myNum])->GART && bo->tiled) {
struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix);
if (--nvpix->map_refcount)
@@ -616,6 +629,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_randr.c b/src/nv50_randr.c
index 8a9281b..538c883 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..790b09c
--- /dev/null
+++ b/src/nv50_shadow_damage.c
@@ -0,0 +1,306 @@
+/*
+ * 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"
+#include "damagestr.h"
+
+/* When driver allocated pixmaps are used we can easily fold this back into exa code. */
+
+static void
+nv50_shadow_damage_blit_state_emit(struct nouveau_channel *chan)
+{
+ ScrnInfoPtr pScrn = chan->user_private;
+ NVPtr pNv = NVPTR(pScrn);
+ PixmapPtr ppix = pNv->pspix;
+ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ unsigned delta = nouveau_pixmap_offset(ppix), fmt;
+
+ WAIT_RING (chan, 27 + 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_RELOCh(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, bo, delta, 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);
+}
+
+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;
+ BoxPtr pbox;
+ int nbox;
+
+ pbox = REGION_RECTS(pRegion);
+ nbox = REGION_NUM_RECTS(pRegion);
+ if (!nbox)
+ return;
+
+ pNv->pspix = ppix;
+ chan->flush_notify = nv50_shadow_damage_blit_state_emit;
+ chan->flush_notify(chan);
+ while (nbox--) {
+ WAIT_RING (chan, 13);
+ 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++;
+ }
+ chan->flush_notify = NULL;
+}
+
+/* For frontbuffer fallbacks. */
+static void
+nv50_shadow_damage_blit_back_state_emit(struct nouveau_channel *chan)
+{
+ ScrnInfoPtr pScrn = chan->user_private;
+ NVPtr pNv = NVPTR(pScrn);
+ PixmapPtr ppix = pNv->pdpix;
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
+ unsigned delta = nouveau_pixmap_offset(ppix), fmt;
+
+ WAIT_RING (chan, 27 + 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_RELOCh(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, bo, delta, 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);
+}
+
+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;
+ BoxPtr pbox;
+ int nbox;
+
+ pbox = REGION_RECTS(pRegion);
+ nbox = REGION_NUM_RECTS(pRegion);
+ if (!nbox)
+ return;
+
+ pNv->pdpix = ppix;
+ chan->flush_notify = nv50_shadow_damage_blit_back_state_emit;
+ chan->flush_notify(chan);
+ while (nbox--) {
+ WAIT_RING (chan, 13);
+ 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++;
+ }
+ chan->flush_notify = NULL;
+}
+
+static void
+nv50_shadow_damage_report(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ PixmapPtr ppix = closure;
+
+ 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;
+ 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_dri.c b/src/nv_dri.c
index bd3e5a9..dca6a40 100644
--- a/src/nv_dri.c
+++ b/src/nv_dri.c
@@ -337,7 +337,7 @@ Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn)
pNOUVEAUDRI->depth = pScrn->depth;
pNOUVEAUDRI->bpp = pScrn->bitsPerPixel;
- ret = nouveau_bo_handle_get(pNv->FB, &pNOUVEAUDRI->front_offset);
+ ret = nouveau_bo_handle_get(pNv->scanout, &pNOUVEAUDRI->front_offset);
if (ret) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] unable to reference front buffer: %d\n", ret);
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 9f4c96f..a280257 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -686,10 +686,11 @@ NVEnterVT(int scrnIndex, int flags)
/* Clear the framebuffer, we don't want to see garbage
* on-screen up until X decides to draw something
*/
- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
- memset(pNv->FB->map, 0, NOUVEAU_ALIGN(pScrn->virtualX, 64) *
- pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
- nouveau_bo_unmap(pNv->FB);
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
+ memset(pNv->scanout->map, 0,
+ NOUVEAU_ALIGN(pScrn->virtualX, 64) * pScrn->virtualY *
+ (pScrn->bitsPerPixel >> 3));
+ nouveau_bo_unmap(pNv->scanout);
if (pNv->Architecture == NV_ARCH_50) {
if (!NV50AcquireDisplay(pScrn))
@@ -1609,6 +1610,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 * 64 * 4, pNv->VRAMMap + Cursor0Offset,
@@ -1760,6 +1763,23 @@ skip_fb:
"at offset 0x%X\n",
(uint32_t)(pNv->FB->size >> 20), (uint32_t) pNv->FB->offset);
+ /* Allocate linear scanout. */
+ if (!pNv->NoAccel && 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);
+ }
/* We don't need to allocate cursors / lut here if we're using
* kernel modesetting
@@ -1832,6 +1852,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);
@@ -2347,6 +2368,15 @@ 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->NoAccel && !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 072c7c4..4e9b65c 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -267,6 +267,10 @@ 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);
+void nv50_shadow_damage_frontbuffer_fallback(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_shadow.c b/src/nv_shadow.c
index ea1ba35..e15051c 100644
--- a/src/nv_shadow.c
+++ b/src/nv_shadow.c
@@ -38,9 +38,9 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
cpp = pScrn->bitsPerPixel >> 3;
FBPitch = pScrn->displayWidth * cpp;
- max_height = pNv->FB->size/FBPitch;
+ max_height = pNv->scanout->size/FBPitch;
- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
while(num--) {
x1 = MAX(pbox->x1, 0);
y1 = MAX(pbox->y1, 0);
@@ -51,7 +51,7 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
if (width > 0 && height > 0) {
src = pNv->ShadowPtr + (y1 * pNv->ShadowPitch) + (x1 * cpp);
- dst = pNv->FB->map + (y1 * FBPitch) + (x1 * cpp);
+ dst = pNv->scanout->map + (y1 * FBPitch) + (x1 * cpp);
while(height--) {
memcpy(dst, src, width);
@@ -62,5 +62,5 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
pbox++;
}
- nouveau_bo_unmap(pNv->FB);
+ nouveau_bo_unmap(pNv->scanout);
}
diff --git a/src/nv_type.h b/src/nv_type.h
index 2ec4fba..5396cc8 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -270,6 +270,7 @@ typedef struct _NVRec {
/* Various pinned memory regions */
struct nouveau_bo * FB;
void * FBMap;
+ 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;
@@ -278,6 +279,9 @@ typedef struct _NVRec {
struct nvbios VBIOS;
struct nouveau_bios_info *vbios;
+
+ DamagePtr screen_damage; /* for NV50+ */
+
Bool NoAccel;
Bool HWCursor;
Bool FpScale;
--
1.6.2.2

View File

@ -1,31 +0,0 @@
From 7460d8ebca84bd5e7c26e88143f14f4909598b68 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 20:20:39 +1000
Subject: [PATCH 5/6] nv50/f11: disable acceleration on NVAx chipsets
---
src/nv_driver.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/src/nv_driver.c b/src/nv_driver.c
index a280257..f097fb9 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1144,6 +1144,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
pNv->ShadowFB = TRUE;
}
+ if ((pNv->NVArch & 0xf0) == 0xa0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_NOTICE,
+ "Acceleration disabled, currently non-functional "
+ "on this chipset\n");
+ pNv->NoAccel = TRUE;
+ pNv->ShadowFB = TRUE;
+ }
+
/* Save current console video mode */
if (pNv->Architecture >= NV_ARCH_50 && pNv->pInt10 && !pNv->kms_enable) {
const xf86Int10InfoPtr pInt10 = pNv->pInt10;
--
1.6.2.2

View File

@ -1,13 +0,0 @@
diff --git a/src/nv_bios.c b/src/nv_bios.c
index fe6368e..7b56148 100644
--- a/src/nv_bios.c
+++ b/src/nv_bios.c
@@ -4104,6 +4104,8 @@ parse_dcb20_entry(ScrnInfoPtr pScrn, struct bios_parsed_dcb *bdcb,
mask = ~0x5;
if (conf & 0x4)
entry->lvdsconf.use_power_scripts = true;
+ if ((conf & 0xf0) == 0x60)
+ mask &= ~0xf0;
}
if (conf & mask) {
/* I'm bored of getting this reported; left as a reminder for someone to fix it */

View File

@ -1,395 +0,0 @@
From 7e4b7775589cff4433de1f3dfa1416c66cdfe060 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@caspar.localdomain>
Date: Tue, 14 Apr 2009 09:23:07 +1000
Subject: [PATCH 6/6] f11: support framebuffer resize without driver pixmaps
---
src/drmmode_display.c | 75 +++++++++++++++++++++++++++++++--
src/nouveau_exa.c | 17 ++++----
src/nv50_randr.c | 6 +++
src/nv_crtc.c | 16 ++++++-
src/nv_driver.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++---
src/nv_type.h | 9 ++++-
6 files changed, 209 insertions(+), 22 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index ca1a60b..c666c9f 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1069,6 +1069,59 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
}
static Bool
+nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+ const int cpp = pScrn->bitsPerPixel >> 3;
+ int pitch = NOUVEAU_ALIGN(width * cpp, 256);
+ int ret = 0;
+ PixmapPtr ppix;
+
+ if (pScrn->virtualX == width && pScrn->virtualY == height &&
+ (pNv->NoAccel || pNv->exa_onscreen))
+ return TRUE;
+
+ if (!pNv->dev)
+ goto out_done;
+
+ nouveau_fb_free(pScrn);
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ if (ret) {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ pitch = (*pScreen->GetScreenPixmap)(pScreen)->devKind;
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ /* famous last words: "this should never happen!" */
+ if (ret)
+ FatalError("couldn't allocate framebuffer!\n");
+
+ ret = -ENOMEM;
+ }
+
+out_done:
+ if (!ret && pNv->ShadowFB) {
+ xfree(pNv->ShadowPtr);
+ pNv->ShadowPtr = xalloc(pitch * height);
+ pNv->ShadowPitch = pitch;
+ }
+
+ ppix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ (*pScreen->ModifyPixmapHeader)(ppix, width, height, -1, -1, pitch,
+ (!pNv->NoAccel || pNv->ShadowFB) ?
+ pNv->ShadowPtr : pNv->FBMap);
+ pScrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
+
+ pScrn->virtualX = width;
+ pScrn->virtualY = height;
+ pScrn->displayWidth = pitch / cpp;
+ return ret == 0;
+}
+
+static Bool
drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1083,10 +1136,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
ErrorF("resize called %d %d\n", width, height);
if (!pNv->exa_driver_pixmaps) {
- if (width > scrn->virtualX || height > scrn->virtualY)
+ if (!nv_xf86crtc_resize(scrn, width, height))
return FALSE;
- scrn->displayWidth = NOUVEAU_ALIGN(width, 64);
+ if (drmmode->fb_id)
+ drmModeRmFB(drmmode->fd, drmmode->fb_id);
+ drmmode->fb_id = 0;
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation,
+ crtc->x, crtc->y);
+ }
+
return TRUE;
}
@@ -1149,7 +1215,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
{
- xf86CrtcConfigPtr xf86_config;
+ xf86CrtcConfigPtr xf86_config;
drmmode_ptr drmmode;
int i;
@@ -1173,8 +1239,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i);
- xf86InitialConfiguration(pScrn, NVPTR(pScrn)->exa_driver_pixmaps);
-
+ xf86InitialConfiguration(pScrn, TRUE);
return TRUE;
}
diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index aee2794..41e3f85 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -279,7 +279,10 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index)
} else
if (ppix == pScreen->GetScreenPixmap(pScreen)) {
nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR);
- ppix->devPrivate.ptr = pNv->scanout->map;
+ if (pNv->scanout != pNv->FB)
+ ppix->devPrivate.ptr = pNv->scanout->map;
+ else
+ ppix->devPrivate.ptr = pNv->FB->map + pNv->exa_onscreen->offset;
} else {
/* force migration */
return FALSE;
@@ -301,7 +304,8 @@ nouveau_exa_finish_access(PixmapPtr ppix, int index)
if (ppix == pScreen->GetScreenPixmap(pScreen)) {
ppix->devPrivate.ptr = NULL;
nouveau_bo_unmap(pNv->scanout);
- nv50_shadow_damage_frontbuffer_fallback(pScrn);
+ if (pNv->Architecture == NV_ARCH_50)
+ nv50_shadow_damage_frontbuffer_fallback(pScrn);
}
}
@@ -543,10 +547,9 @@ Bool
nouveau_exa_pixmap_is_onscreen(PixmapPtr ppix)
{
ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
unsigned long offset = exaGetPixmapOffset(ppix);
- if (offset < pNv->EXADriverPtr->offScreenBase)
+ if (offset == 0)
return TRUE;
return FALSE;
@@ -630,10 +633,8 @@ nouveau_exa_init(ScreenPtr pScreen)
}
/* 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->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_randr.c b/src/nv50_randr.c
index 538c883..c451ba3 100644
--- a/src/nv50_randr.c
+++ b/src/nv50_randr.c
@@ -289,8 +289,14 @@ nv50_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
{
ScrnInfoPtr pScrn = crtc->scrn;
NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
+ NVPtr pNv = NVPTR(pScrn);
nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y);
+ if (nv_crtc->crtc->front_buffer &&
+ nv_crtc->crtc->front_buffer != pNv->scanout) {
+ nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->scanout);
+ nv_crtc->crtc->ModeSet(nv_crtc->crtc, &crtc->mode);
+ }
NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
}
diff --git a/src/nv_crtc.c b/src/nv_crtc.c
index 1d50874..cfa06e1 100644
--- a/src/nv_crtc.c
+++ b/src/nv_crtc.c
@@ -1154,7 +1154,10 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
ScrnInfoPtr pScrn = crtc->scrn;
NVPtr pNv = NVPTR(pScrn);
struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- uint32_t start = (y * pScrn->displayWidth + x) * pScrn->bitsPerPixel / 8;
+ uint32_t cpp = pScrn->bitsPerPixel / 8;
+ uint32_t start = (y * pScrn->displayWidth + x) * cpp;
+ uint32_t pitch = pScrn->displayWidth * cpp;
+ NVCrtcRegPtr regp = &pNv->ModeReg.crtc_reg[nv_crtc->head];
if (crtc->rotatedData != NULL) /* we do not exist on the real framebuffer */
#if NOUVEAU_EXA_PIXMAPS
@@ -1162,8 +1165,17 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
#else
start = pNv->FB->offset + nv_crtc->shadow->offset; /* We do exist relative to the framebuffer */
#endif
- else
+ else {
+ if (pNv->exa_onscreen)
+ start += pNv->exa_onscreen->offset;
start += pNv->FB->offset;
+ }
+
+ regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = pitch >> 3;
+ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
+ XLATE(pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
start &= ~3;
pNv->ModeReg.crtc_reg[nv_crtc->head].fb_start = start;
diff --git a/src/nv_driver.c b/src/nv_driver.c
index f097fb9..0cc81ae 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -900,16 +900,112 @@ Bool NVI2CInit(ScrnInfoPtr pScrn)
return TRUE;
}
+void
+nouveau_fb_free(ScrnInfoPtr pScrn)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+
+ if (!pNv->NoAccel && pNv->exa_onscreen) {
+ exaOffscreenFree(pScreen, pNv->exa_onscreen);
+ pNv->exa_onscreen = NULL;
+ }
+
+ if (pNv->scanout && pNv->FB != pNv->scanout)
+ nouveau_bo_ref(NULL, &pNv->scanout);
+}
+
+int
+nouveau_fb_alloc(ScrnInfoPtr pScrn, int pitch, int height, int cpp)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+ int ret;
+
+ if (!pNv->NoAccel) {
+ pNv->exa_onscreen = exaOffscreenAlloc(pScreen, pitch * height,
+ 256, TRUE, NULL, NULL);
+ if (!pNv->exa_onscreen)
+ return -ENOMEM;
+ }
+
+ if (!pNv->scanout) {
+ ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
+ 256, pitch * height, &pNv->scanout);
+ if (ret) {
+ nouveau_fb_free(pScrn);
+ return ret;
+ }
+ }
+
+
+ return 0;
+}
+
static Bool
nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
-#if 0
- do not change virtual* for now, as it breaks multihead server regeneration
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_xf86crtc_resize is called with %dx%d resolution.\n", width, height);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+ const int cpp = pScrn->bitsPerPixel >> 3;
+ int pitch = NOUVEAU_ALIGN(width * cpp, 256);
+ int ret = 0, i;
+ PixmapPtr ppix;
+
+ if (pScrn->virtualX == width && pScrn->virtualY == height &&
+ (pNv->NoAccel || pNv->exa_onscreen))
+ return TRUE;
+
+ if (!pNv->dev)
+ goto out_done;
+
+ nouveau_fb_free(pScrn);
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ if (ret) {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ pitch = (*pScreen->GetScreenPixmap)(pScreen)->devKind;
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ /* famous last words: "this should never happen!" */
+ if (ret)
+ FatalError("couldn't allocate framebuffer!\n");
+
+ ret = -ENOMEM;
+ }
+
+out_done:
+
+ if (!ret && pNv->ShadowFB) {
+ xfree(pNv->ShadowPtr);
+ pNv->ShadowPtr = xalloc(pitch * height);
+ pNv->ShadowPitch = pitch;
+ }
+
+ ppix = pScreen->GetScreenPixmap(pScreen);
+
+ (*pScreen->ModifyPixmapHeader)(ppix, width, height, -1, -1, pitch,
+ (!pNv->NoAccel || pNv->ShadowFB) ?
+ pNv->ShadowPtr : pNv->FBMap);
+ pScrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
+
pScrn->virtualX = width;
pScrn->virtualY = height;
-#endif
- return TRUE;
+ pScrn->displayWidth = pitch / cpp;
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation,
+ crtc->x, crtc->y);
+ }
+
+ return ret == 0;
}
static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = {
@@ -1423,7 +1519,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
} else
nv50_output_create(pScrn); /* create randr-1.2 "outputs". */
- if (!xf86InitialConfiguration(pScrn, FALSE))
+ if (!xf86InitialConfiguration(pScrn, TRUE))
NVPreInitFail("No valid modes.\n");
}
diff --git a/src/nv_type.h b/src/nv_type.h
index 5396cc8..1a9b9ed 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -304,8 +304,11 @@ typedef struct _NVRec {
volatile CARD8 *PDIO1;
uint8_t cur_head;
+
ExaDriverPtr EXADriverPtr;
Bool exa_driver_pixmaps;
+ ExaOffscreenArea * exa_onscreen;
+
ScreenBlockHandlerProcPtr BlockHandler;
CloseScreenProcPtr CloseScreen;
/* Cursor */
@@ -494,11 +497,15 @@ nouveau_pixmap_offset(PixmapPtr ppix)
{
ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
+ unsigned offset;
if (pNv->exa_driver_pixmaps)
return 0;
- return exaGetPixmapOffset(ppix);
+ offset = exaGetPixmapOffset(ppix);
+ if (offset == 0)
+ offset = pNv->exa_onscreen->offset;
+ return offset;
}
#endif /* __NV_STRUCT_H__ */
--
1.6.2.2

View File

@ -1 +0,0 @@
http://sources.openelec.tv/svn/xf86-video-nouveau-master-20090425.tar.bz2