summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-01-30 17:53:03 -0500
committerKristian Høgsberg <krh@redhat.com>2009-02-01 22:28:14 -0500
commit0cb87ccfe97b0e016e47dcf236fd5ce78dddfc4b (patch)
tree375b1c4de9351d744f357dd0632ee21958b79c10 /src
parent66bc44e8f9a0505c0b11b8042243ca74079da85f (diff)
Implement front buffer resize for KMS.
This adds back the resize hook so we can resize the front buffer under kernel mode setting as well. The patch also pulls the drmmode_* structs from drmmode_display.h into drmmode_display.c and eliminates the header file.
Diffstat (limited to 'src')
-rw-r--r--src/drmmode_display.c224
-rw-r--r--src/drmmode_display.h73
-rw-r--r--src/i830.h11
-rw-r--r--src/i830_driver.c36
-rw-r--r--src/i830_memory.c15
5 files changed, 154 insertions, 205 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 49942519..52402ab0 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -33,25 +33,31 @@
#ifdef XF86DRM_MODE
#include "i830.h"
-#include "sarea.h"
-
-static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode,
- int width, int height);
-
-static Bool
-drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- drmmode_crtc_private_ptr drmmode_crtc =
- xf86_config->crtc[0]->driver_private;
- drmmode_ptr drmmode = drmmode_crtc->drmmode;
- Bool ret;
-
- ret = drmmode_resize_fb(scrn, drmmode, width, height);
- scrn->virtualX = width;
- scrn->virtualY = height;
- return ret;
-}
+#include "intel_bufmgr.h"
+#include "xf86drmMode.h"
+
+typedef struct {
+ int fd;
+ uint32_t fb_id;
+ drmModeResPtr mode_res;
+ int cpp;
+} drmmode_rec, *drmmode_ptr;
+
+typedef struct {
+ drmmode_ptr drmmode;
+ drmModeCrtcPtr mode_crtc;
+ dri_bo *cursor;
+ dri_bo *rotate_bo;
+ int rotate_fb_id;
+} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
+
+typedef struct {
+ drmmode_ptr drmmode;
+ int output_id;
+ drmModeConnectorPtr mode_output;
+ drmModeEncoderPtr mode_encoder;
+ drmModePropertyBlobPtr edid_blob;
+} drmmode_output_private_rec, *drmmode_output_private_ptr;
static void
drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
@@ -112,10 +118,6 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn,
}
-static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
- drmmode_xf86crtc_resize
-};
-
static void
drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
{
@@ -126,6 +128,8 @@ static Bool
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
Rotation rotation, int x, int y)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
@@ -138,6 +142,19 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
int i;
int fb_id;
struct drm_mode_modeinfo kmode;
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+
+ if (drmmode->fb_id == 0) {
+ ret = drmModeAddFB(drmmode->fd,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->depth, pScrn->bitsPerPixel,
+ pitch, pI830->front_buffer->bo->handle,
+ &drmmode->fb_id);
+ if (ret < 0) {
+ ErrorF("failed to add fb\n");
+ return FALSE;
+ }
+ }
saved_mode = crtc->mode;
saved_x = crtc->x;
@@ -185,7 +202,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
fb_id = drmmode->fb_id;
if (drmmode_crtc->rotate_fb_id)
fb_id = drmmode_crtc->rotate_fb_id;
- ErrorF("fb id is %d\n", fb_id);
ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
fb_id, x, y, output_ids, output_count, &kmode);
if (ret)
@@ -574,24 +590,89 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
return;
}
-Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId,
- char *driver_name, int cpp)
+static Bool
+drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
{
- xf86CrtcConfigPtr xf86_config;
- int i;
- Bool ret;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ drmmode_crtc_private_ptr
+ drmmode_crtc = xf86_config->crtc[0]->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ I830Ptr pI830 = I830PTR(scrn);
+ i830_memory *new_front, *old_front = NULL;
+ BoxRec mem_box;
+ Bool tiled, ret;
+ ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
+ uint32_t old_fb_id;
+ int i, pitch;
+
+ if (scrn->virtualX == width && scrn->virtualY == height)
+ return TRUE;
- /* Create a bus Id */
- /* Low level DRM open */
- ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, busId, driver_name);
- if (!ret) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[dri] DRIGetVersion failed to open the DRM\n"
- "[dri] Disabling DRI.\n");
+ if (!pI830->can_resize)
+ return FALSE;
+
+ tiled = i830_tiled_width(pI830, &scrn->displayWidth, pI830->cpp);
+ pitch = scrn->displayWidth * pI830->cpp;
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "Allocate new frame buffer %dx%d stride %d\n",
+ width, height, scrn->displayWidth);
+
+ old_front = pI830->front_buffer;
+ new_front = i830_allocate_framebuffer(scrn, pI830, &mem_box, FALSE);
+ if (!new_front)
return FALSE;
+
+ old_fb_id = drmmode->fb_id;
+ ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+ scrn->bitsPerPixel, pitch, new_front->bo->handle,
+ &drmmode->fb_id);
+ if (ret)
+ ErrorF("Failed to add fb: %s\n", strerror(-ret));
+
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+ scrn->displayWidth = i830_pad_drawable_width(width, pI830->cpp);
+ pI830->front_buffer = new_front;
+ i830_set_pixmap_bo(screen->GetScreenPixmap(screen), new_front->bo);
+ scrn->fbOffset = pI830->front_buffer->offset;
+
+ screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+ width, height, -1, -1, pitch, NULL);
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n",
+ pI830->front_buffer->offset);
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ drmmode_set_mode_major(crtc, &crtc->mode,
+ crtc->rotation, crtc->x, crtc->y);
}
- drmmode->fd = DRIMasterFD(pScrn);
+ if (old_fb_id)
+ drmModeRmFB(drmmode->fd, old_fb_id);
+ if (old_front)
+ i830_free_memory(scrn, old_front);
+
+ return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+ drmmode_xf86crtc_resize
+};
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config;
+ drmmode_ptr drmmode;
+ int i;
+
+ drmmode = xnfalloc(sizeof *drmmode);
+ drmmode->fd = fd;
+ drmmode->fb_id = 0;
xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -609,40 +690,10 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId,
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i);
- xf86InitialConfiguration(pScrn, FALSE);
-
- return TRUE;
-}
+ xf86InitialConfiguration(pScrn, pI830->can_resize);
-#if 0
-Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
- dri_bufmgr *bufmgr)
-{
- drmmode->bufmgr = bufmgr;
return TRUE;
}
-#endif
-
-void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
- int height, int pitch, dri_bo *bo)
-{
- int ret;
-
- ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
- scrn->bitsPerPixel, pitch, bo->handle,
- &drmmode->fb_id);
-
- if (ret) {
- ErrorF("Failed to add fb: %s\n", strerror(-ret));
- }
-
- drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
- if (!drmmode->mode_fb)
- return;
-
-
- ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
-}
Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
{
@@ -668,41 +719,4 @@ Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
#endif
}
-static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width,
- int height)
-{
- uint32_t handle;
- int pitch;
- int ret;
-
- return FALSE;
-
- if (drmmode->mode_fb->width == width &&
- drmmode->mode_fb->height == height)
- return TRUE;
-
- if (!drmmode->create_new_fb)
- return FALSE;
-
- handle = drmmode->create_new_fb(scrn, width, height, &pitch);
- if (handle == 0)
- return FALSE;
-
- ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id,
- width, height,
- scrn->depth, scrn->bitsPerPixel, pitch,
- handle);
-
- if (ret)
- return FALSE;
-
- drmModeFreeFB(drmmode->mode_fb);
- drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
- if (!drmmode->mode_fb)
- return FALSE;
-
- return TRUE;
-}
-
#endif
-
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
deleted file mode 100644
index ee51c955..00000000
--- a/src/drmmode_display.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright © 2007 Red Hat, Inc.
- *
- * 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 (including the next
- * paragraph) 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 OR COPYRIGHT HOLDERS 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.
- *
- * Authors:
- * Dave Airlie <airlied@redhat.com>
- *
- */
-#ifndef DRMMODE_DISPLAY_H
-#define DRMMODE_DISPLAY_H
-
-#ifdef XF86DRM_MODE
-
-#include "intel_bufmgr.h"
-#include "xf86drmMode.h"
-
-typedef struct {
- int fd;
- uint32_t fb_id;
- drmModeResPtr mode_res;
- drmModeFBPtr mode_fb;
- int cpp;
- uint32_t (*create_new_fb)(ScrnInfoPtr pScrn, int width, int height,
- int *pitch);
-} drmmode_rec, *drmmode_ptr;
-
-typedef struct {
-
- drmmode_ptr drmmode;
- drmModeCrtcPtr mode_crtc;
- dri_bo *cursor;
- dri_bo *rotate_bo;
- int rotate_fb_id;
-} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
-
-typedef struct {
- drmmode_ptr drmmode;
- int output_id;
- drmModeConnectorPtr mode_output;
- drmModeEncoderPtr mode_encoder;
- drmModePropertyBlobPtr edid_blob;
-} drmmode_output_private_rec, *drmmode_output_private_ptr;
-
-
-extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
- char *busId, char *driver_name, int cpp);
-extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width,
- int height, int pitch, dri_bo *bo);
-extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData,
- dri_bo **bo);
-extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id,
- void *ptr, uint32_t handle);
-#endif /* XF86DRM_MODE */
-
-#endif /* DRMMODE_DISPLAY_H */
diff --git a/src/i830.h b/src/i830.h
index d9adfbfd..bfd78dc7 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -72,7 +72,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri.h"
#include "GL/glxint.h"
#include "i830_dri.h"
-#include "drmmode_display.h"
#endif
#include "intel_bufmgr.h"
#include "i915_drm.h"
@@ -725,10 +724,6 @@ typedef struct _I830Rec {
Bool use_drm_mode;
Bool kernel_exec_fencing;
-#ifdef XF86DRM_MODE
- drmmode_rec drmmode;
- int drm_mm_init;
-#endif
/** Enables logging of debug output related to mode switching. */
Bool debug_modes;
@@ -836,6 +831,12 @@ Bool I830DRI2ScreenInit(ScreenPtr pScreen);
void I830DRI2CloseScreen(ScreenPtr pScreen);
#endif
+#ifdef XF86DRM_MODE
+extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
+extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData,
+ dri_bo **bo);
+#endif
+
extern Bool I830AccelInit(ScreenPtr pScreen);
extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
int ydir, int rop,
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 2c4ea077..b8d8d37f 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -212,6 +212,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i915_drm.h"
#endif
+#ifdef XF86DRM_MODE
+#include <xf86drmMode.h>
+#endif
+
#ifdef I830_USE_EXA
const char *I830exaSymbols[] = {
"exaGetVersion",
@@ -1718,6 +1722,7 @@ I830DrmModeInit(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
char *bus_id;
char *s;
+ int ret;
/* Default to UXA but allow override */
pI830->accel = ACCEL_UXA;
@@ -1731,21 +1736,36 @@ I830DrmModeInit(ScrnInfoPtr pScrn)
pI830->accel = ACCEL_UXA;
}
+ pI830->can_resize = FALSE;
+ if (pI830->accel == ACCEL_UXA && pI830->directRenderingType != DRI_XF86DRI)
+ pI830->can_resize = TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Resizable framebuffer: %s (%d %d)\n",
+ pI830->can_resize ? "available" : "not available",
+ pI830->directRenderingType, pI830->accel);
+
bus_id = DRICreatePCIBusID(pI830->PciInfo);
- if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915",
- pI830->cpp) == FALSE) {
- xfree(bus_id);
+
+ /* Create a bus Id */
+ /* Low level DRM open */
+ ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, bus_id, "i915");
+ xfree(bus_id);
+ if (!ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] DRIGetVersion failed to open the DRM\n"
+ "[dri] Disabling DRI.\n");
+ return FALSE;
+ }
+
+ pI830->drmSubFD = DRIMasterFD(pScrn);
+ if (drmmode_pre_init(pScrn, pI830->drmSubFD, pI830->cpp) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Kernel modesetting setup failed\n");
PreInitCleanup(pScrn);
return FALSE;
}
- pI830->drmmode.create_new_fb = i830_create_new_fb;
-
- pI830->drmSubFD = pI830->drmmode.fd;
- xfree(bus_id);
-
pI830->directRenderingType = DRI_NONE;
pI830->allocate_classic_textures = FALSE;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index f3c55a34..e5d70fa2 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1292,14 +1292,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
return NULL;
}
- if (pI830->use_drm_mode) {
-#ifdef XF86DRM_MODE
- ErrorF("setting kernel fb to new front buffer\n");
- ErrorF("front_buffer->bo->size: %ld\n", front_buffer->bo->size);
- drmmode_set_fb(pScrn, &pI830->drmmode, pScrn->virtualX, fb_height,
- pScrn->displayWidth * pI830->cpp, front_buffer->bo);
-#endif
- } else if (pI830->FbBase)
+ if (!pI830->use_drm_mode)
memset (pI830->FbBase + front_buffer->offset, 0, size);
return front_buffer;
@@ -2130,9 +2123,3 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
return TRUE;
}
#endif
-
-uint32_t
-i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
-{
- return 0;
-}