summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-07-29 11:52:20 -0400
committerAdam Jackson <ajax@redhat.com>2015-07-29 11:53:43 -0400
commitecf6e1dfe507ad6cde7a81ef6adfc3b11458be65 (patch)
tree8daeef51200e8f26f47d5006b00437baf0532b58
parent2123f7682d522619f101b05fb75efa75dabbe371 (diff)
modesetting: Implement 32->24 bpp conversion in shadow updatems2432-1.17
24bpp front buffers tend to be the least well tested path for client rendering. On the qemu cirrus emulation, and on some Matrox G200 server chips, the hardware can't do 32bpp at all. It's better to just allocate a 32bpp shadow and downconvert in the upload hook than expose a funky pixmap format to clients. [ajax: Ported from RHEL and separate modesetting driver, lifted kbpp into the drmmode struct, cleaned up commit message, fixed 16bpp] [ajax: Backported from upstream submission to 1.17 branch] Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlied <airlied@redhat.com>
-rw-r--r--hw/xfree86/drivers/modesetting/Makefile.am2
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c41
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.c19
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.h2
4 files changed, 42 insertions, 22 deletions
diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am
index 82c4f2f32..ca7e05aac 100644
--- a/hw/xfree86/drivers/modesetting/Makefile.am
+++ b/hw/xfree86/drivers/modesetting/Makefile.am
@@ -51,6 +51,8 @@ modesetting_drv_la_SOURCES = \
dumb_bo.c \
dumb_bo.h \
present.c \
+ sh3224.c \
+ sh3224.h \
vblank.c \
$(NULL)
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index d52517d1a..b14a512b0 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -60,6 +60,7 @@
#endif
#include "driver.h"
+#include "sh3224.h"
static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
static Bool CloseScreen(ScreenPtr pScreen);
@@ -730,10 +731,16 @@ PreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp);
- if (defaultdepth == 24 && defaultbpp == 24)
- bppflags = SupportConvert32to24 | Support24bppFb;
- else
- bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb;
+ if (defaultdepth == 24 && defaultbpp == 24) {
+ ms->drmmode.force_24_32 = TRUE;
+ ms->drmmode.kbpp = 24;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using 24bpp hw front buffer with 32bpp shadow\n");
+ defaultbpp = 32;
+ } else {
+ ms->drmmode.kbpp = defaultbpp;
+ }
+ bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb;
if (!xf86SetDepthBpp
(pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags))
@@ -786,18 +793,24 @@ PreInit(ScrnInfoPtr pScrn, int flags)
} else {
Bool prefer_shadow = TRUE;
- ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value);
- if (!ret) {
- prefer_shadow = !!value;
- }
+ if (ms->drmmode.force_24_32) {
+ prefer_shadow = TRUE;
+ ms->drmmode.shadow_enable = TRUE;
+ } else {
+ ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value);
+ if (!ret) {
+ prefer_shadow = !!value;
+ }
- ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options,
- OPTION_SHADOW_FB,
- prefer_shadow);
+ ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options,
+ OPTION_SHADOW_FB,
+ prefer_shadow);
+ }
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"ShadowFB: preferred %s, enabled %s\n",
prefer_shadow ? "YES" : "NO",
+ ms->drmmode.force_24_32 ? "FORCE" :
ms->drmmode.shadow_enable ? "YES" : "NO");
}
@@ -851,7 +864,7 @@ msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
modesettingPtr ms = modesettingPTR(pScrn);
int stride;
- stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
+ stride = (pScrn->displayWidth * ms->drmmode.kbpp) / 8;
*size = stride;
return ((uint8_t *) ms->drmmode.front_bo.dumb->ptr + row * stride + offset);
@@ -872,6 +885,7 @@ CreateScreenResources(ScreenPtr pScreen)
Bool ret;
void *pixels = NULL;
int err;
+ Bool use_ms_shadow = ms->drmmode.force_24_32 && pScrn->bitsPerPixel == 32;
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
@@ -903,7 +917,8 @@ CreateScreenResources(ScreenPtr pScreen)
FatalError("Couldn't adjust screen pixmap\n");
if (ms->drmmode.shadow_enable) {
- if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked,
+ if (!shadowAdd(pScreen, rootPixmap,
+ use_ms_shadow ? ms_shadowUpdate32to24 : msUpdatePacked,
msShadowWindow, 0, 0))
return FALSE;
}
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index a8de5f9e7..ec7eb72ee 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -288,7 +288,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (drmmode->fb_id == 0) {
ret = drmModeAddFB(drmmode->fd,
pScrn->virtualX, height,
- pScrn->depth, pScrn->bitsPerPixel,
+ pScrn->depth, drmmode->kbpp,
drmmode_bo_get_pitch(&drmmode->front_bo),
drmmode_bo_get_handle(&drmmode->front_bo),
&drmmode->fb_id);
@@ -1329,6 +1329,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
uint32_t old_fb_id;
int i, pitch, old_width, old_height, old_pitch;
int cpp = (scrn->bitsPerPixel + 7) / 8;
+ int kcpp = (drmmode->kbpp + 7) / 8;
PixmapPtr ppix = screen->GetScreenPixmap(screen);
void *new_pixels = NULL;
@@ -1350,17 +1351,17 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
old_front = drmmode->front_bo;
if (!drmmode_create_bo(drmmode, &drmmode->front_bo,
- width, height, scrn->bitsPerPixel))
+ width, height, drmmode->kbpp))
goto fail;
pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
scrn->virtualX = width;
scrn->virtualY = height;
- scrn->displayWidth = pitch / cpp;
+ scrn->displayWidth = pitch / kcpp;
ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
- scrn->bitsPerPixel, pitch,
+ drmmode->kbpp, pitch,
drmmode_bo_get_handle(&drmmode->front_bo),
&drmmode->fb_id);
if (ret)
@@ -1373,8 +1374,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
}
if (drmmode->shadow_enable) {
- uint32_t size = scrn->displayWidth * scrn->virtualY *
- ((scrn->bitsPerPixel + 7) >> 3);
+ uint32_t size = scrn->displayWidth * scrn->virtualY * cpp;
new_pixels = calloc(1, size);
if (new_pixels == NULL)
goto fail;
@@ -1382,7 +1382,8 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
drmmode->shadow_fb = new_pixels;
}
- screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, new_pixels);
+ screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
+ scrn->displayWidth * cpp, new_pixels);
if (!drmmode_glamor_handle_new_screen_pixmap(drmmode))
goto fail;
@@ -1409,7 +1410,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
drmmode->front_bo = old_front;
scrn->virtualX = old_width;
scrn->virtualY = old_height;
- scrn->displayWidth = old_pitch / cpp;
+ scrn->displayWidth = old_pitch / kcpp;
drmmode->fb_id = old_fb_id;
return FALSE;
@@ -1684,7 +1685,7 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int width;
int height;
- int bpp = pScrn->bitsPerPixel;
+ int bpp = ms->drmmode.kbpp;
int i;
int cpp = (bpp + 7) / 8;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 3a8959ac3..5c66d6b9c 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -50,6 +50,7 @@ typedef struct {
drmModeResPtr mode_res;
drmModeFBPtr mode_fb;
int cpp;
+ int kbpp;
ScrnInfoPtr scrn;
struct gbm_device *gbm;
@@ -64,6 +65,7 @@ typedef struct {
Bool glamor;
Bool shadow_enable;
+ Bool force_24_32;
void *shadow_fb;
/**