summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2007-12-17 15:00:36 +1000
committerDave Airlie <airlied@redhat.com>2007-12-17 15:00:36 +1000
commit2a134af01bc85de758ad83a85b23d1bba4a1a0f5 (patch)
treefa23219b93459b60e2f17b3fbb8cecf12860ad67
parent614414611a9f246cbc74f579a79987fff97cf571 (diff)
r600: add shadow support to r600 driver to at least make 2d useable
-rw-r--r--src/radeon.h3
-rw-r--r--src/radeon_driver.c84
2 files changed, 76 insertions, 11 deletions
diff --git a/src/radeon.h b/src/radeon.h
index 6c38826d..6cc2b6f9 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -710,6 +710,9 @@ typedef struct {
Bool IsSecondary;
Bool IsPrimary;
+
+ Bool r600_shadow_fb;
+ void *fb_shadow;
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ac307ab7..62e7cd0b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -97,6 +97,7 @@
#include "xf86cmap.h"
#include "vbe.h"
+#include "shadow.h"
/* vgaHW definitions */
#ifdef WITH_VGAHW
#include "vgaHW.h"
@@ -347,6 +348,15 @@ static const char *i2cSymbols[] = {
NULL
};
+static const char *shadowSymbols[] = {
+ "shadowAdd",
+ "shadowInit",
+ "shadowSetup",
+ "shadowUpdatePacked",
+ "shadowUpdatePackedWeak",
+ NULL
+};
+
void RADEONLoaderRefSymLists(void)
{
/*
@@ -405,23 +415,41 @@ struct RADEONInt10Save {
static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
-#if 0
+static void *
+radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
+ CARD32 *size, void *closure)
+{
+ ScrnInfoPtr pScrn = xf86Screens[screen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int stride;
+
+ stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
+ *size = stride;
+
+ return ((CARD8 *)info->FB + pScrn->fbOffset +
+ row * stride + offset);
+}
static Bool
RADEONCreateScreenResources (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
+ PixmapPtr pixmap;
pScreen->CreateScreenResources = info->CreateScreenResources;
if (!(*pScreen->CreateScreenResources)(pScreen))
return FALSE;
+ pScreen->CreateScreenResources = RADEONCreateScreenResources;
- if (!xf86RandR12CreateScreenResources(pScreen))
- return FALSE;
+ if (info->r600_shadow_fb) {
+ pixmap = pScreen->GetScreenPixmap(pScreen);
- return TRUE;
+ if (!shadowAdd(pScreen, pixmap, shadowUpdatePackedWeak(),
+ radeonShadowWindow, 0, NULL))
+ return FALSE;
+ }
+ return TRUE;
}
-#endif
RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
{
@@ -1930,6 +1958,14 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
info->Chipset != PCI_CHIP_RN50_5969);
#endif
+ if (info->ChipFamily >= CHIP_FAMILY_R600) {
+ info->r600_shadow_fb = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "using shadow framebuffer\n");
+ if (!xf86LoadSubModule(pScrn, "shadow"))
+ return FALSE;
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
return TRUE;
}
@@ -3697,13 +3733,32 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
#endif
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"Initializing fb layer\n");
+
+ if (info->r600_shadow_fb) {
+ info->fb_shadow = xcalloc(1,
+ pScrn->displayWidth * pScrn->virtualY *
+ ((pScrn->bitsPerPixel + 7) >> 3));
+ if (info->fb_shadow == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate shadow framebuffer\n");
+ info->r600_shadow_fb = FALSE;
+ } else {
+ if (!fbScreenInit(pScreen, info->fb_shadow,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+ pScrn->bitsPerPixel))
+ return FALSE;
+ }
+ }
- /* Init fb layer */
- if (!fbScreenInit(pScreen, info->FB,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
- pScrn->bitsPerPixel))
- return FALSE;
+ if (info->r600_shadow_fb == FALSE) {
+ /* Init fb layer */
+ if (!fbScreenInit(pScreen, info->FB,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+ pScrn->bitsPerPixel))
+ return FALSE;
+ }
xf86SetBlackWhitePixels(pScreen);
@@ -3815,6 +3870,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
RADEONChangeSurfaces(pScrn);
+
/* Enable aceleration */
if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -3883,6 +3939,10 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
RADEONInitVideo(pScreen);
}
+ if (!shadowSetup(pScreen)) {
+ return FALSE;
+ }
+
/* Provide SaveScreen & wrap BlockHandler and CloseScreen */
/* Wrap CloseScreen */
info->CloseScreen = pScreen->CloseScreen;
@@ -3890,6 +3950,8 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
pScreen->SaveScreen = RADEONSaveScreen;
info->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = RADEONBlockHandler;
+ info->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = RADEONCreateScreenResources;
if (!xf86CrtcScreenInit (pScreen))
return FALSE;