0x7942:0x1028:0x0204: ATI Radeon Xpress 1250 for Dell/Parker
I would most like to see XV and rotation support. At the moment the drm kernel module (from git) will not compile on my running kernel. So I assume I'll have to wait a bit longer before trying to get XV working. Is there anything I can do to try out or help with rotation? Rafi -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On Tue, Jul 29, 2008 at 10:13 PM, Rafi Rubin
I would most like to see XV and rotation support.
At the moment the drm kernel module (from git) will not compile on my running kernel. So I assume I'll have to wait a bit longer before trying to get XV working.
Is there anything I can do to try out or help with rotation?
radeon has rotation support that could be ported over pretty easily. You'd also need to fill in the randr crtc cursor functions in radeonhd. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
I tried a bit of translation. Its definitely not quite there. If I use noaccel I get some rotation but its a little Escheresque. With windows being drawn in both the -o 0 and whatever the current orientation happens to be. With EXA and I think XAA I just get a black screen after rotating. Which I'm going to assume has something to do with my allocating the wrong frame buffers for those methods. I didn't touch the cursor functions yet, but I figure the screen should draw correctly before I worry about that. I'm including the output from git diff, if anyone else feels like playing with this. Rafi Alex Deucher wrote:
On Tue, Jul 29, 2008 at 10:13 PM, Rafi Rubin
wrote: I would most like to see XV and rotation support.
At the moment the drm kernel module (from git) will not compile on my running kernel. So I assume I'll have to wait a bit longer before trying to get XV working.
Is there anything I can do to try out or help with rotation?
radeon has rotation support that could be ported over pretty easily. You'd also need to fill in the randr crtc cursor functions in radeonhd.
Alex
diff --git a/src/rhd.h b/src/rhd.h index 8ca1c2a..8f1f283 100644 --- a/src/rhd.h +++ b/src/rhd.h @@ -47,6 +47,15 @@ #define RHD_DRIVER_NAME "radeonhd" +#ifdef USE_EXA +#include "exa.h" +#endif +#ifdef USE_XAA +#include "xaa.h" +#endif + + + enum RHD_CHIPSETS { RHD_UNKNOWN = 0, /* R500 */ diff --git a/src/rhd_id.c b/src/rhd_id.c index 517b183..b262bd5 100644 --- a/src/rhd_id.c +++ b/src/rhd_id.c @@ -692,6 +692,7 @@ rhdCards[] = /* 0x793F : RS600 : Radeon Xpress 1200 */ /* 0x7941 : RS600 : Radeon Xpress 1200 */ /* 0x7942 : RS600 : Radeon Xpress 1200 (M) */ + { 0x7942 , 0x1028,0x0204, "ATI Radeon Xpress 1250 for Dell/Parker", RHD_CARD_FLAG_NONE, ID_CONNECTORINFO_EMPTY }, /* 0x796C : RS740 : RS740 */ /* 0x796D : RS740 : RS740M */ /* 0x796E : RS740 : RS740 */ diff --git a/src/rhd_randr.c b/src/rhd_randr.c index ef1376a..0cdee62 100644 --- a/src/rhd_randr.c +++ b/src/rhd_randr.c @@ -57,6 +57,8 @@ /* Driver specific headers */ #include "rhd.h" #include "rhd_randr.h" +# include "dri.h" +# include "rhd_dri.h" #ifdef RANDR_12_SUPPORT # include "rhd_crtc.h" @@ -95,6 +97,14 @@ typedef struct _rhdRandrOutput { struct rhdConnector *Connector; struct rhdOutput *Output; DisplayModePtr ScaledToMode; + +#ifdef USE_XAA + FBLinearPtr rotate_mem_xaa; +#endif +#ifdef USE_EXA + ExaOffscreenArea *rotate_mem_exa; +#endif + } rhdRandrOutputRec, *rhdRandrOutputPtr; #define ATOM_SIGNAL_FORMAT "RANDR_SIGNAL_FORMAT" @@ -459,6 +469,184 @@ Destroys any associated shadow objects. If pPixmap is NULL, then a pixmap was not created, but 'data' may still be non-NULL indicating that the shadow had been allocated. #endif +#ifdef USE_XAA +/** + * copied from radeon + * Allocates memory from the XF86 linear allocator, but also purges + * memory if possible to cause the allocation to succeed. + */ +static FBLinearPtr +rhd_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, + int granularity, + MoveLinearCallbackProcPtr moveCB, + RemoveLinearCallbackProcPtr removeCB, + pointer privData) +{ + FBLinearPtr linear; + int max_size; + + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); + if (linear != NULL) + return linear; + + /* The above allocation didn't succeed, so purge unlocked stuff and try + * again. + */ + xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, + PRIORITY_EXTREME); + + if (max_size < length) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); + + return linear; +} +#endif + +/** + * Allocates memory for a locked-in-framebuffer shadow of the given + * width and height for this CRTC's rotated shadow framebuffer. + */ + +static void * +rhdRRCrtcShadowAllocate (xf86CrtcPtr crtc, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + /* + * RADEONInfoPtr info = RADEONPTR(pScrn); + * RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + */ + RHDPtr rhdPtr = RHDPTR(pScrn); + rhdRandrOutputPtr rout = crtc->driver_private; + unsigned long rotate_pitch; + unsigned long rotate_offset; + int align = 4096, size; + int cpp = pScrn->bitsPerPixel / 8; + + rotate_pitch = pScrn->displayWidth * cpp; + size = rotate_pitch * height; + +#ifdef USE_EXA + /* We could get close to what we want here by just creating a pixmap like + * normal, but we have to lock it down in framebuffer, and there is no + * setter for offscreen area locking in EXA currently. So, we just + * allocate offscreen memory and fake up a pixmap header for it. + */ + // radeon version + //if (info->useEXA) { + if (rhdPtr->AccelMethod == RHD_ACCEL_EXA) { + assert(rout->rotate_mem_exa == NULL); + + rout->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align, + TRUE, NULL, NULL); + if (rout->rotate_mem_exa == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } + rotate_offset = rout->rotate_mem_exa->offset; + } +#endif /* USE_EXA */ +#ifdef USE_XAA + // radeon version + //if (!info->useEXA) { + if (rhdPtr->AccelMethod == RHD_ACCEL_XAA) { + //if (rhdPtr->AccelMethod != RHD_ACCEL_EXA) { + /* The XFree86 linear allocator operates in units of screen pixels, + * sadly. + */ + size = (size + cpp - 1) / cpp; + align = (align + cpp - 1) / cpp; + + assert(radeon_crtc->rotate_mem_xaa == NULL); + + rout->rotate_mem_xaa = + rhd_xf86AllocateOffscreenLinear(pScreen, size, align, + NULL, NULL, NULL); + if (rout->rotate_mem_xaa == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } +#ifdef XF86DRI + rotate_offset = rhdPtr->dri->frontOffset + + rout->rotate_mem_xaa->offset * cpp; +#endif + } +#endif /* USE_XAA */ + + return rhdPtr->FbBase + rotate_offset; +} + +/** + * Creates a pixmap for this CRTC's rotated shadow framebuffer. + */ +static PixmapPtr +rhdRRCrtcShadowCreate(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + unsigned long rotate_pitch; + PixmapPtr rotate_pixmap; + int cpp = pScrn->bitsPerPixel / 8; + + if (!data) + data = rhdRRCrtcShadowAllocate(crtc, width, height); + + rotate_pitch = pScrn->displayWidth * cpp; + + rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, + width, height, + pScrn->depth, + pScrn->bitsPerPixel, + rotate_pitch, + data); + + if (rotate_pixmap == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + } + + return rotate_pixmap; +} +static void +rhdRRCrtcShadowDestroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + ScrnInfoPtr pScrn = crtc->scrn; + /* + * RADEONInfoPtr info = RADEONPTR(pScrn); + * RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + */ + RHDPtr rhdPtr = RHDPTR(pScrn); + rhdRandrOutputPtr rout = crtc->driver_private; + if (rotate_pixmap) + FreeScratchPixmapHeader(rotate_pixmap); + + if (data) { +#ifdef USE_EXA + //if (info->useEXA && radeon_crtc->rotate_mem_exa != NULL) { + if (rhdPtr->AccelMethod == RHD_ACCEL_EXA && rout->rotate_mem_exa != NULL) { + exaOffscreenFree(pScrn->pScreen, rout->rotate_mem_exa); + rout->rotate_mem_exa = NULL; + } +#endif /* USE_EXA */ +#ifdef USE_XAA + //if (!info->useEXA) { + //if (rhdPtr->AccelMethod != RHD_ACCEL_EXA) { + if (rhdPtr->AccelMethod == RHD_ACCEL_XAA) { + xf86FreeOffscreenLinear(rout->rotate_mem_xaa); + rout->rotate_mem_xaa = NULL; + } +#endif /* USE_XAA */ + } +} + /* @@ -1226,7 +1414,8 @@ static const xf86CrtcFuncsRec rhdRRCrtcFuncs = { rhdRRCrtcPrepare, rhdRRCrtcModeSet, rhdRRCrtcCommit, rhdRRCrtcGammaSet, /* rhdRRCrtcShadowAllocate,rhdRRCrtcShadowCreate,rhdRRCrtcShadowDestroy */ - NULL, NULL, NULL, + rhdRRCrtcShadowAllocate,rhdRRCrtcShadowCreate,rhdRRCrtcShadowDestroy, + /*NULL, NULL, NULL,*/ /* SetCursorColors,SetCursorPosition,ShowCursor,HideCursor, * LoadCursorImage,LoadCursorArgb,CrtcDestroy */ NULL, NULL, NULL, NULL, NULL, NULL, NULL
On Thu, Jul 31, 2008 at 11:33 PM, Rafi Rubin
I tried a bit of translation. Its definitely not quite there.
If I use noaccel I get some rotation but its a little Escheresque. With windows being drawn in both the -o 0 and whatever the current orientation happens to be. With EXA and I think XAA I just get a black screen after rotating. Which I'm going to assume has something to do with my allocating the wrong frame buffers for those methods.
I didn't touch the cursor functions yet, but I figure the screen should draw correctly before I worry about that.
I'm including the output from git diff, if anyone else feels like playing with this.
You will need to take the rotate offset into account when you set the crtc base address. Take a look at atombios_crtc_mode_set() in the radeon driver. Alex
Rafi
Alex Deucher wrote:
On Tue, Jul 29, 2008 at 10:13 PM, Rafi Rubin
wrote: I would most like to see XV and rotation support.
At the moment the drm kernel module (from git) will not compile on my running kernel. So I assume I'll have to wait a bit longer before trying to get XV working.
Is there anything I can do to try out or help with rotation?
radeon has rotation support that could be ported over pretty easily. You'd also need to fill in the randr crtc cursor functions in radeonhd.
Alex
diff --git a/src/rhd.h b/src/rhd.h index 8ca1c2a..8f1f283 100644 --- a/src/rhd.h +++ b/src/rhd.h @@ -47,6 +47,15 @@ #define RHD_DRIVER_NAME "radeonhd"
+#ifdef USE_EXA +#include "exa.h" +#endif +#ifdef USE_XAA +#include "xaa.h" +#endif + + + enum RHD_CHIPSETS { RHD_UNKNOWN = 0, /* R500 */ diff --git a/src/rhd_id.c b/src/rhd_id.c index 517b183..b262bd5 100644 --- a/src/rhd_id.c +++ b/src/rhd_id.c @@ -692,6 +692,7 @@ rhdCards[] = /* 0x793F : RS600 : Radeon Xpress 1200 */ /* 0x7941 : RS600 : Radeon Xpress 1200 */ /* 0x7942 : RS600 : Radeon Xpress 1200 (M) */ + { 0x7942 , 0x1028,0x0204, "ATI Radeon Xpress 1250 for Dell/Parker", RHD_CARD_FLAG_NONE, ID_CONNECTORINFO_EMPTY }, /* 0x796C : RS740 : RS740 */ /* 0x796D : RS740 : RS740M */ /* 0x796E : RS740 : RS740 */ diff --git a/src/rhd_randr.c b/src/rhd_randr.c index ef1376a..0cdee62 100644 --- a/src/rhd_randr.c +++ b/src/rhd_randr.c @@ -57,6 +57,8 @@ /* Driver specific headers */ #include "rhd.h" #include "rhd_randr.h" +# include "dri.h" +# include "rhd_dri.h"
#ifdef RANDR_12_SUPPORT # include "rhd_crtc.h" @@ -95,6 +97,14 @@ typedef struct _rhdRandrOutput { struct rhdConnector *Connector; struct rhdOutput *Output; DisplayModePtr ScaledToMode; + +#ifdef USE_XAA + FBLinearPtr rotate_mem_xaa; +#endif +#ifdef USE_EXA + ExaOffscreenArea *rotate_mem_exa; +#endif + } rhdRandrOutputRec, *rhdRandrOutputPtr;
#define ATOM_SIGNAL_FORMAT "RANDR_SIGNAL_FORMAT" @@ -459,6 +469,184 @@ Destroys any associated shadow objects. If pPixmap is NULL, then a pixmap was not created, but 'data' may still be non-NULL indicating that the shadow had been allocated. #endif +#ifdef USE_XAA +/** + * copied from radeon + * Allocates memory from the XF86 linear allocator, but also purges + * memory if possible to cause the allocation to succeed. + */ +static FBLinearPtr +rhd_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, + int granularity, + MoveLinearCallbackProcPtr moveCB, + RemoveLinearCallbackProcPtr removeCB, + pointer privData) +{ + FBLinearPtr linear; + int max_size; + + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); + if (linear != NULL) + return linear; + + /* The above allocation didn't succeed, so purge unlocked stuff and try + * again. + */ + xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, + PRIORITY_EXTREME); + + if (max_size < length) + return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); + + return linear; +} +#endif + +/** + * Allocates memory for a locked-in-framebuffer shadow of the given + * width and height for this CRTC's rotated shadow framebuffer. + */ + +static void * +rhdRRCrtcShadowAllocate (xf86CrtcPtr crtc, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + /* + * RADEONInfoPtr info = RADEONPTR(pScrn); + * RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + */ + RHDPtr rhdPtr = RHDPTR(pScrn); + rhdRandrOutputPtr rout = crtc->driver_private; + unsigned long rotate_pitch; + unsigned long rotate_offset; + int align = 4096, size; + int cpp = pScrn->bitsPerPixel / 8; + + rotate_pitch = pScrn->displayWidth * cpp; + size = rotate_pitch * height; + +#ifdef USE_EXA + /* We could get close to what we want here by just creating a pixmap like + * normal, but we have to lock it down in framebuffer, and there is no + * setter for offscreen area locking in EXA currently. So, we just + * allocate offscreen memory and fake up a pixmap header for it. + */ + // radeon version + //if (info->useEXA) { + if (rhdPtr->AccelMethod == RHD_ACCEL_EXA) { + assert(rout->rotate_mem_exa == NULL); + + rout->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align, + TRUE, NULL, NULL); + if (rout->rotate_mem_exa == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } + rotate_offset = rout->rotate_mem_exa->offset; + } +#endif /* USE_EXA */ +#ifdef USE_XAA + // radeon version + //if (!info->useEXA) { + if (rhdPtr->AccelMethod == RHD_ACCEL_XAA) { + //if (rhdPtr->AccelMethod != RHD_ACCEL_EXA) { + /* The XFree86 linear allocator operates in units of screen pixels, + * sadly. + */ + size = (size + cpp - 1) / cpp; + align = (align + cpp - 1) / cpp; + + assert(radeon_crtc->rotate_mem_xaa == NULL); + + rout->rotate_mem_xaa = + rhd_xf86AllocateOffscreenLinear(pScreen, size, align, + NULL, NULL, NULL); + if (rout->rotate_mem_xaa == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow memory for rotated CRTC\n"); + return NULL; + } +#ifdef XF86DRI + rotate_offset = rhdPtr->dri->frontOffset + + rout->rotate_mem_xaa->offset * cpp; +#endif + } +#endif /* USE_XAA */ + + return rhdPtr->FbBase + rotate_offset; +} + +/** + * Creates a pixmap for this CRTC's rotated shadow framebuffer. + */ +static PixmapPtr +rhdRRCrtcShadowCreate(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + unsigned long rotate_pitch; + PixmapPtr rotate_pixmap; + int cpp = pScrn->bitsPerPixel / 8; + + if (!data) + data = rhdRRCrtcShadowAllocate(crtc, width, height); + + rotate_pitch = pScrn->displayWidth * cpp; + + rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, + width, height, + pScrn->depth, + pScrn->bitsPerPixel, + rotate_pitch, + data); + + if (rotate_pixmap == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate shadow pixmap for rotated CRTC\n"); + } + + return rotate_pixmap; +} +static void +rhdRRCrtcShadowDestroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + ScrnInfoPtr pScrn = crtc->scrn; + /* + * RADEONInfoPtr info = RADEONPTR(pScrn); + * RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + */ + RHDPtr rhdPtr = RHDPTR(pScrn); + rhdRandrOutputPtr rout = crtc->driver_private; + if (rotate_pixmap) + FreeScratchPixmapHeader(rotate_pixmap); + + if (data) { +#ifdef USE_EXA + //if (info->useEXA && radeon_crtc->rotate_mem_exa != NULL) { + if (rhdPtr->AccelMethod == RHD_ACCEL_EXA && rout->rotate_mem_exa != NULL) { + exaOffscreenFree(pScrn->pScreen, rout->rotate_mem_exa); + rout->rotate_mem_exa = NULL; + } +#endif /* USE_EXA */ +#ifdef USE_XAA + //if (!info->useEXA) { + //if (rhdPtr->AccelMethod != RHD_ACCEL_EXA) { + if (rhdPtr->AccelMethod == RHD_ACCEL_XAA) { + xf86FreeOffscreenLinear(rout->rotate_mem_xaa); + rout->rotate_mem_xaa = NULL; + } +#endif /* USE_XAA */ + } +} +
/* @@ -1226,7 +1414,8 @@ static const xf86CrtcFuncsRec rhdRRCrtcFuncs = { rhdRRCrtcPrepare, rhdRRCrtcModeSet, rhdRRCrtcCommit, rhdRRCrtcGammaSet, /* rhdRRCrtcShadowAllocate,rhdRRCrtcShadowCreate,rhdRRCrtcShadowDestroy */ - NULL, NULL, NULL, + rhdRRCrtcShadowAllocate,rhdRRCrtcShadowCreate,rhdRRCrtcShadowDestroy, + /*NULL, NULL, NULL,*/ /* SetCursorColors,SetCursorPosition,ShowCursor,HideCursor, * LoadCursorImage,LoadCursorArgb,CrtcDestroy */ NULL, NULL, NULL, NULL, NULL, NULL, NULL
-- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
participants (3)
-
Alex Deucher
-
Rafi Rubin
-
Rafi Rubin