diff --git a/configure.ac b/configure.ac
index b8c18a6..a7e954d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,6 +115,15 @@ if test "$DRI" = yes; then
if test "$have_damage_h" = yes; then
AC_DEFINE(DAMAGE,1,[Use Damage extension])
fi
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$XORG_CFLAGS $DRI_CFLAGS"
+ AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include <stdint.h>
+#include <stdlib.h>])
+ if test "x$DRM_MODE" = xyes; then
+ AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
+ fi
+ CFLAGS="$save_CFLAGS"
fi
save_CFLAGS="$CFLAGS"
diff --git a/src/Makefile.am b/src/Makefile.am
index 97c686b..d32e74a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -90,12 +90,13 @@ radeon_drv_ladir = @moduledir@/drivers
radeon_drv_la_SOURCES = \
radeon_accel.c radeon_cursor.c radeon_dga.c \
radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
- radeon_vip.c radeon_misc.c radeon_probe.c \
+ radeon_vip.c radeon_misc.c radeon_probe.c radeon_memory.c \
legacy_crtc.c legacy_output.c \
radeon_textured_video.c \
radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
$(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \
- $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c
+ $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c \
+ drmmode_display.c radeon_bufmgr_exa.c radeon_bufmgr_gem.c
if XMODES
radeon_drv_la_SOURCES += \
@@ -160,4 +161,5 @@ EXTRA_DIST = \
radeon_pci_device_match_gen.h \
pcidb/ati_pciids.csv \
pcidb/parse_pci_ids.pl \
- radeon_atombios.h
+ radeon_atombios.h \
+ drmmode_display.h
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
new file mode 100644
index 0000000..97762ce
--- /dev/null
+++ b/src/drmmode_display.c
@@ -0,0 +1,681 @@
+/*
+ * 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>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef XF86DRM_MODE
+#include "radeon.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;
+
+ ErrorF("resize called %d %d\n", width, height);
+ ret = drmmode_resize_fb(scrn, drmmode, width, height);
+ scrn->virtualX = width;
+ scrn->virtualY = height;
+ return ret;
+}
+
+static void
+drmmode_ConvertFromKMode(ScrnInfoPtr scrn,
+ struct drm_mode_modeinfo *kmode,
+ DisplayModePtr mode)
+{
+ memset(mode, 0, sizeof(DisplayModeRec));
+ mode->status = MODE_OK;
+
+ mode->Clock = kmode->clock;
+
+ mode->HDisplay = kmode->hdisplay;
+ mode->HSyncStart = kmode->hsync_start;
+ mode->HSyncEnd = kmode->hsync_end;
+ mode->HTotal = kmode->htotal;
+ mode->HSkew = kmode->hskew;
+
+ mode->VDisplay = kmode->vdisplay;
+ mode->VSyncStart = kmode->vsync_start;
+ mode->VSyncEnd = kmode->vsync_end;
+ mode->VTotal = kmode->vtotal;
+ mode->VScan = kmode->vscan;
+
+ mode->Flags = kmode->flags; //& FLAG_BITS;
+ mode->name = strdup(kmode->name);
+
+ if (kmode->type & DRM_MODE_TYPE_DRIVER)
+ mode->type = M_T_DRIVER;
+ if (kmode->type & DRM_MODE_TYPE_PREFERRED)
+ mode->type |= M_T_PREFERRED;
+ xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static void
+drmmode_ConvertToKMode(ScrnInfoPtr scrn,
+ struct drm_mode_modeinfo *kmode,
+ DisplayModePtr mode)
+{
+ memset(kmode, 0, sizeof(*kmode));
+
+ kmode->clock = mode->Clock;
+ kmode->hdisplay = mode->HDisplay;
+ kmode->hsync_start = mode->HSyncStart;
+ kmode->hsync_end = mode->HSyncEnd;
+ kmode->htotal = mode->HTotal;
+ kmode->hskew = mode->HSkew;
+
+ kmode->vdisplay = mode->VDisplay;
+ kmode->vsync_start = mode->VSyncStart;
+ kmode->vsync_end = mode->VSyncEnd;
+ kmode->vtotal = mode->VTotal;
+ kmode->vscan = mode->VScan;
+
+ kmode->flags = mode->Flags; //& FLAG_BITS;
+ if (mode->name)
+ strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
+ kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+ drmmode_xf86crtc_resize
+};
+
+static void
+drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+
+}
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int saved_x, saved_y;
+ Rotation saved_rotation;
+ DisplayModeRec saved_mode;
+ uint32_t *output_ids;
+ int output_count = 0;
+ int ret = TRUE;
+ int i;
+ int fb_id;
+ struct drm_mode_modeinfo kmode;
+
+ saved_mode = crtc->mode;
+ saved_x = crtc->x;
+ saved_y = crtc->y;
+ saved_rotation = crtc->rotation;
+
+ crtc->mode = *mode;
+ crtc->x = x;
+ crtc->y = y;
+ crtc->rotation = rotation;
+
+ output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
+ if (!output_ids) {
+ ret = FALSE;
+ goto done;
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ drmmode_output_private_ptr drmmode_output;
+
+ if (output->crtc != crtc)
+ continue;
+
+ drmmode_output = output->driver_private;
+ output_ids[output_count] = drmmode_output->mode_output->connector_id;
+ output_count++;
+ }
+
+ if (!xf86CrtcRotate(crtc, mode, rotation)) {
+ goto done;
+ }
+
+ drmmode_ConvertToKMode(crtc->scrn, &kmode, 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);
+ drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+ fb_id, x, y, output_ids, output_count, &kmode);
+
+
+done:
+ if (!ret) {
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ crtc->rotation = saved_rotation;
+ crtc->mode = saved_mode;
+ }
+ return ret;
+}
+
+static void
+drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+
+}
+
+static void
+drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
+}
+
+static void
+drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ void *ptr;
+
+ /* cursor should be mapped already */
+ ptr = drmmode_crtc->cursor_map;
+
+ memcpy (ptr, image, 64 * 64 * 4);
+
+ return;
+}
+
+
+static void
+drmmode_hide_cursor (xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
+
+}
+
+static void
+drmmode_show_cursor (xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->cursor_handle, 64, 64);
+}
+
+static void *
+drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int size;
+ unsigned long rotate_pitch;
+ dri_bo *rotate_bo;
+ int ret;
+ rotate_pitch = crtc->scrn->displayWidth * drmmode->cpp;
+ size = rotate_pitch * height;
+
+ rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate", size, 0);
+ if (rotate_bo == NULL)
+ return NULL;
+
+ radeon_bufmgr_pin(rotate_bo);
+ dri_bo_map(rotate_bo, 1);
+
+ ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+ crtc->scrn->bitsPerPixel, rotate_pitch, radeon_bufmgr_get_handle(rotate_bo),
+ &drmmode_crtc->rotate_fb_id);
+ if (ret) {
+ ErrorF("failed to add rotate fb\n");
+ }
+
+ drmmode_crtc->rotate_bo = rotate_bo;
+ return drmmode_crtc->rotate_bo->virtual;
+}
+
+static PixmapPtr
+drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ unsigned long rotate_pitch;
+ PixmapPtr rotate_pixmap;
+
+ if (!data)
+ data = drmmode_crtc_shadow_allocate (crtc, width, height);
+
+ rotate_pitch = pScrn->displayWidth * drmmode->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
+drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ if (rotate_pixmap)
+ FreeScratchPixmapHeader(rotate_pixmap);
+
+ if (data) {
+ drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
+ drmmode_crtc->rotate_fb_id = 0;
+ dri_bo_unreference(drmmode_crtc->rotate_bo);
+ drmmode_crtc->rotate_bo = NULL;
+ }
+
+}
+
+static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
+ .dpms = drmmode_crtc_dpms,
+ .set_mode_major = drmmode_set_mode_major,
+ .set_cursor_colors = drmmode_set_cursor_colors,
+ .set_cursor_position = drmmode_set_cursor_position,
+ .show_cursor = drmmode_show_cursor,
+ .hide_cursor = drmmode_hide_cursor,
+ .load_cursor_argb = drmmode_load_cursor_argb,
+
+ .shadow_create = drmmode_crtc_shadow_create,
+ .shadow_allocate = drmmode_crtc_shadow_allocate,
+ .shadow_destroy = drmmode_crtc_shadow_destroy,
+#if 0
+ .gamma_set = i830_crtc_gamma_set,
+#endif
+ .destroy = NULL, /* XXX */
+};
+
+
+static void
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+ xf86CrtcPtr crtc;
+ drmmode_crtc_private_ptr drmmode_crtc;
+
+ crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
+ if (crtc == NULL)
+ return;
+
+ drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
+ drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+ drmmode_crtc->drmmode = drmmode;
+ crtc->driver_private = drmmode_crtc;
+
+ return;
+}
+
+static xf86OutputStatus
+drmmode_output_detect(xf86OutputPtr output)
+{
+ /* go to the hw and retrieve a new output struct */
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmmode_ptr drmmode = drmmode_output->drmmode;
+ xf86OutputStatus status;
+ drmModeFreeConnector(drmmode_output->mode_output);
+
+ drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+
+ switch (drmmode_output->mode_output->connection) {
+ case DRM_MODE_CONNECTED:
+ status = XF86OutputStatusConnected;
+ break;
+ case DRM_MODE_DISCONNECTED:
+ status = XF86OutputStatusDisconnected;
+ break;
+ default:
+ case DRM_MODE_UNKNOWNCONNECTION:
+ status = XF86OutputStatusUnknown;
+ break;
+ }
+ return status;
+}
+
+static Bool
+drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+ return MODE_OK;
+}
+
+static DisplayModePtr
+drmmode_output_get_modes(xf86OutputPtr output)
+{
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmModeConnectorPtr koutput = drmmode_output->mode_output;
+ drmmode_ptr drmmode = drmmode_output->drmmode;
+ int i;
+ DisplayModePtr Modes = NULL, Mode;
+ drmModePropertyPtr props;
+
+ /* look for an EDID property */
+ for (i = 0; i < koutput->count_props; i++) {
+ props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+ if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+ if (!strcmp(props->name, "EDID")) {
+ if (drmmode_output->edid_blob)
+ drmModeFreePropertyBlob(drmmode_output->edid_blob);
+ drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+ }
+ drmModeFreeProperty(props);
+ }
+ }
+
+ if (drmmode_output->edid_blob)
+ xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
+ else
+ xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
+
+ /* modes should already be available */
+ for (i = 0; i < koutput->count_modes; i++) {
+ Mode = xnfalloc(sizeof(DisplayModeRec));
+
+ drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
+ Modes = xf86ModesAdd(Modes, Mode);
+
+ }
+ return Modes;
+}
+
+static void
+drmmode_output_destroy(xf86OutputPtr output)
+{
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+
+ if (drmmode_output->edid_blob)
+ drmModeFreePropertyBlob(drmmode_output->edid_blob);
+ drmModeFreeConnector(drmmode_output->mode_output);
+ xfree(drmmode_output);
+ output->driver_private = NULL;
+}
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode)
+{
+ return;
+}
+
+static const xf86OutputFuncsRec drmmode_output_funcs = {
+ .dpms = drmmode_output_dpms,
+#if 0
+
+ .save = drmmode_crt_save,
+ .restore = drmmode_crt_restore,
+ .mode_fixup = drmmode_crt_mode_fixup,
+ .prepare = drmmode_output_prepare,
+ .mode_set = drmmode_crt_mode_set,
+ .commit = drmmode_output_commit,
+#endif
+ .detect = drmmode_output_detect,
+ .mode_valid = drmmode_output_mode_valid,
+
+ .get_modes = drmmode_output_get_modes,
+ .destroy = drmmode_output_destroy
+};
+
+static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
+ SubPixelHorizontalRGB,
+ SubPixelHorizontalBGR,
+ SubPixelVerticalRGB,
+ SubPixelVerticalBGR,
+ SubPixelNone };
+
+const char *output_names[] = { "None",
+ "VGA",
+ "DVI",
+ "DVI",
+ "DVI",
+ "Composite",
+ "TV",
+ "LVDS",
+ "CTV",
+ "DIN",
+ "DP",
+ "HDMI",
+ "HDMI",
+};
+
+
+static void
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+ xf86OutputPtr output;
+ drmModeConnectorPtr koutput;
+ drmModeEncoderPtr kencoder;
+ drmmode_output_private_ptr drmmode_output;
+ char name[32];
+
+ koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+ if (!koutput)
+ return;
+
+ kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
+ if (!kencoder) {
+ drmModeFreeConnector(koutput);
+ return;
+ }
+
+ snprintf(name, 32, "%s%d", output_names[koutput->connector_type], koutput->connector_type_id);
+
+ output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
+ if (!output) {
+ drmModeFreeEncoder(kencoder);
+ drmModeFreeConnector(koutput);
+ return;
+ }
+
+ drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
+ if (!drmmode_output) {
+ xf86OutputDestroy(output);
+ drmModeFreeConnector(koutput);
+ drmModeFreeEncoder(kencoder);
+ return;
+ }
+
+ drmmode_output->output_id = drmmode->mode_res->connectors[num];
+ drmmode_output->mode_output = koutput;
+ drmmode_output->mode_encoder = kencoder;
+ drmmode_output->drmmode = drmmode;
+ output->mm_width = koutput->mmWidth;
+ output->mm_height = koutput->mmHeight;
+
+ output->subpixel_order = subpixel_conv_table[koutput->subpixel];
+ output->driver_private = drmmode_output;
+
+ output->possible_crtcs = kencoder->possible_crtcs;
+ output->possible_clones = kencoder->possible_clones;
+ return;
+}
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp)
+{
+ xf86CrtcConfigPtr xf86_config;
+ int i;
+ Bool ret;
+
+ /* 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");
+ return FALSE;
+ }
+
+ drmmode->fd = DRIMasterFD(pScrn);
+
+ xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
+ xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+ drmmode->cpp = cpp;
+ drmmode->mode_res = drmModeGetResources(drmmode->fd);
+ if (!drmmode->mode_res)
+ return FALSE;
+
+ xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
+ for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+ drmmode_crtc_init(pScrn, drmmode, i);
+
+ for (i = 0; i < drmmode->mode_res->count_connectors; i++)
+ drmmode_output_init(pScrn, drmmode, i);
+
+ xf86InitialConfiguration(pScrn, FALSE);
+
+ return TRUE;
+}
+
+Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr)
+{
+ drmmode->bufmgr = bufmgr;
+ return TRUE;
+}
+
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle)
+{
+ int ret;
+
+ ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+ scrn->bitsPerPixel, pitch, handle,
+ &drmmode->fb_id);
+
+ if (ret) {
+ ErrorF("Failed to add fb\n");
+ }
+
+ 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);
+}
+
+void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CrtcPtr crtc = xf86_config->crtc[id];
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+
+ drmmode_crtc->cursor_handle = handle;
+ drmmode_crtc->cursor_map = ptr;
+}
+
+Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
+ int i;
+
+ if (pPixData == NULL)
+ return FALSE;
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ if (!drmmode_crtc->rotate_bo)
+ continue;
+
+ if (drmmode_crtc->rotate_bo->virtual == pPixData) {
+ *bo = drmmode_crtc->rotate_bo;
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+}
+
+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;
+}
+
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output = config->output[config->compat_output];
+ xf86CrtcPtr crtc = output->crtc;
+
+ if (crtc && crtc->enabled) {
+ drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+ x, y);
+ }
+}
+
+#endif
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
new file mode 100644
index 0000000..691d62e
--- /dev/null
+++ b/src/drmmode_display.h
@@ -0,0 +1,74 @@
+/*
+ * 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 "xf86drmMode.h"
+
+#include "radeon_probe.h"
+#include "radeon_bufmgr.h"
+
+typedef struct {
+ int fd;
+ int fb_id;
+ drmModeResPtr mode_res;
+ drmModeFBPtr mode_fb;
+ int cpp;
+ dri_bufmgr *bufmgr;
+
+ 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;
+ uint32_t cursor_handle;
+ void *cursor_map;
+ 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 Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr);
+extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle);
+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);
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags);
+#endif
+#endif
diff --git a/src/radeon.h b/src/radeon.h
index 2348e7c..32bfa4e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -46,6 +46,8 @@
#include "compiler.h"
#include "xf86fbman.h"
+#include "drmmode_display.h"
+
/* PCI support */
#include "xf86Pci.h"
@@ -84,6 +86,7 @@
#include "xf86Crtc.h"
#include "X11/Xatom.h"
+#include "radeon_bufmgr.h"
/* Render support */
#ifdef RENDER
#include "picturestr.h"
@@ -403,6 +406,9 @@ typedef enum {
typedef struct _atomBiosHandle *atomBiosHandlePtr;
+#define RADEON_POOL_GART 0
+#define RADEON_POOL_VRAM 1
+
typedef struct {
uint32_t pci_device_id;
RADEONChipFamily chip_family;
@@ -413,6 +419,25 @@ typedef struct {
int singledac;
} RADEONCardInfo;
+#define RADEON_2D_EXA_COPY 1
+#define RADEON_2D_EXA_SOLID 2
+
+struct radeon_2d_state {
+ int op; //
+ uint32_t dst_pitch_offset;
+ uint32_t src_pitch_offset;
+ uint32_t dp_gui_master_cntl;
+ uint32_t dp_cntl;
+ uint32_t dp_write_mask;
+ uint32_t dp_brush_frgd_clr;
+ uint32_t dp_brush_bkgd_clr;
+ uint32_t dp_src_frgd_clr;
+ uint32_t dp_src_bkgd_clr;
+ uint32_t default_sc_bottom_right;
+ dri_bo *dst_bo;
+ dri_bo *src_bo;
+};
+
typedef struct {
EntityInfoPtr pEnt;
pciVideoPtr PciInfo;
@@ -612,13 +637,13 @@ typedef struct {
drm_handle_t ringHandle; /* Handle from drmAddMap */
drmSize ringMapSize; /* Size of map */
int ringSize; /* Size of ring (in MB) */
- drmAddress ring; /* Map */
+ // drmAddress ring; /* Map */
int ringSizeLog2QW;
unsigned long ringReadOffset; /* Offset into GART space */
drm_handle_t ringReadPtrHandle; /* Handle from drmAddMap */
drmSize ringReadMapSize; /* Size of map */
- drmAddress ringReadPtr; /* Map */
+ // drmAddress ringReadPtr; /* Map */
/* CP vertex/indirect buffer data */
unsigned long bufStart; /* Offset into GART space */
@@ -641,6 +666,9 @@ typedef struct {
drmBufPtr indirectBuffer;
int indirectStart;
+ drmBuf ib_gem_fake;
+ void *ib_ptr;
+
/* DRI screen private data */
int fbX;
int fbY;
@@ -798,6 +826,45 @@ typedef struct {
int num_gb_pipes;
Bool has_tcl;
+
+ Bool new_cs; // new command submission routine
+ struct radeon_2d_state state_2d;
+ void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
+ Bool cs_used_depth;
+ Bool drm_mm; // the drm memory manager exists and is initialised
+ struct {
+ uint64_t vram_start;
+ uint64_t vram_size;
+ uint64_t gart_start;
+ uint64_t gart_size;
+
+ struct radeon_memory *bo_list[2];
+ struct radeon_memory *front_buffer;
+ struct radeon_memory *back_buffer;
+ struct radeon_memory *depth_buffer;
+
+#if 0
+ struct radeon_memory *exa_buffer;
+#endif
+ struct radeon_memory *texture_buffer;
+
+ struct radeon_memory *dma_buffer;
+ struct radeon_memory *gart_texture_buffer;
+ struct radeon_memory *rotate_buffer;
+ struct radeon_memory *cursor[2];
+
+ /* indirect buffer for accel */
+ struct radeon_memory *gem_ib_memory;
+
+ } mm;
+
+ drm_handle_t fb_map_handle;
+ Bool drm_mode_setting;
+#ifdef XF86DRM_MODE
+ drmmode_rec drmmode;
+#endif
+
+ dri_bufmgr *bufmgr;
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
@@ -1030,6 +1097,23 @@ extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
extern void RADEONInitVideo(ScreenPtr pScreen);
extern void RADEONResetVideo(ScrnInfoPtr pScrn);
+/* radeon_memory.c */
+extern uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+extern Bool radeon_bind_all_memory(ScrnInfoPtr pScrn);
+extern Bool radeon_unbind_all_memory(ScrnInfoPtr pScrn);
+extern struct radeon_memory *radeon_allocate_memory(ScrnInfoPtr pScrn, int pool, int size, int alignment, Bool no_backing_store, char *name,
+ int need_bind);
+uint32_t radeon_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch);
+int radeon_map_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+void radeon_unmap_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+void radeon_free_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+Bool radeon_bind_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+Bool radeon_free_all_memory(ScrnInfoPtr pScrn);
+Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
+Bool RADEONDRIDoMappings(ScreenPtr pScreen);
+Bool radeon_update_dri_buffers(ScrnInfoPtr pScrn);
+Bool radeon_setup_gart_mem(ScreenPtr pScreen);
+
#ifdef XF86DRI
# ifdef USE_XAA
/* radeon_accelfuncs.c */
@@ -1048,7 +1132,9 @@ do { \
#define RADEONCP_RELEASE(pScrn, info) \
do { \
- if (info->CPInUse) { \
+ if (info->new_cs) { \
+ RADEONCPReleaseIndirect(pScrn); \
+ } else if (info->CPInUse) { \
RADEON_PURGE_CACHE(); \
RADEON_WAIT_UNTIL_IDLE(); \
RADEONCPReleaseIndirect(pScrn); \
@@ -1082,7 +1168,7 @@ do { \
#define RADEONCP_REFRESH(pScrn, info) \
do { \
- if (!info->CPInUse) { \
+ if (!info->CPInUse && !info->new_cs) { \
if (info->needCacheFlush) { \
RADEON_PURGE_CACHE(); \
RADEON_PURGE_ZCACHE(); \
@@ -1109,6 +1195,13 @@ do { \
#define RING_LOCALS uint32_t *__head = NULL; int __expected; int __count = 0
#define BEGIN_RING(n) do { \
+ if (!info->indirectBuffer) { \
+ info->indirectBuffer = RADEONCPGetBuffer(pScrn); \
+ info->indirectStart = 0; \
+ } else if (info->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \
+ info->indirectBuffer->total) { \
+ RADEONCPFlushIndirect(pScrn, 1); \
+ } \
if (RADEON_VERBOSE) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, \
"BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
@@ -1121,13 +1214,6 @@ do { \
} \
info->dma_debug_func = __FILE__; \
info->dma_debug_lineno = __LINE__; \
- if (!info->indirectBuffer) { \
- info->indirectBuffer = RADEONCPGetBuffer(pScrn); \
- info->indirectStart = 0; \
- } else if (info->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \
- info->indirectBuffer->total) { \
- RADEONCPFlushIndirect(pScrn, 1); \
- } \
__expected = n; \
__head = (pointer)((char *)info->indirectBuffer->address + \
info->indirectBuffer->used); \
@@ -1170,6 +1256,14 @@ do { \
OUT_RING(val); \
} while (0)
+/* TODO - VRAM is wrong in general but true for now - all EXA stuff
+ is in VRAM */
+#define OUT_RING_RELOC(x, read_domains, write_domains) \
+ do { \
+ radeon_bufmgr_emit_reloc(x, __head, &__count, read_domains, write_domains); \
+ } while(0)
+
+
#define FLUSH_RING() \
do { \
if (RADEON_VERBOSE) \
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index e617fd5..09aa7f6 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -313,6 +313,9 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ if (info->drm_mode_setting)
+ return;
+
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"EngineRestore (%d/%d)\n",
info->CurrentLayout.pixel_code,
@@ -371,7 +374,7 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
info->CurrentLayout.bitsPerPixel);
#ifdef XF86DRI
- if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) {
+ if ((info->directRenderingEnabled || info->drm_mode_setting) && (IS_R300_3D || IS_R500_3D)) {
drmRadeonGetParam np;
int num_pipes;
@@ -391,60 +394,62 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
}
#endif
- if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
- (info->ChipFamily == CHIP_FAMILY_R420) ||
- (info->ChipFamily == CHIP_FAMILY_RS600) ||
- (info->ChipFamily == CHIP_FAMILY_RS690) ||
- (info->ChipFamily == CHIP_FAMILY_RS740) ||
- (info->ChipFamily == CHIP_FAMILY_RS400) ||
- (info->ChipFamily == CHIP_FAMILY_RS480) ||
- IS_R500_3D) {
- if (info->num_gb_pipes == 0) {
- uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
-
- info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
- if (IS_R500_3D)
- OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
- }
- } else {
- if (info->num_gb_pipes == 0) {
- if ((info->ChipFamily == CHIP_FAMILY_R300) ||
- (info->ChipFamily == CHIP_FAMILY_R350)) {
- /* R3xx chips */
- info->num_gb_pipes = 2;
- } else {
- /* RV3xx chips */
- info->num_gb_pipes = 1;
+ if (!info->drm_mode_setting) {
+ if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
+ (info->ChipFamily == CHIP_FAMILY_R420) ||
+ (info->ChipFamily == CHIP_FAMILY_RS600) ||
+ (info->ChipFamily == CHIP_FAMILY_RS690) ||
+ (info->ChipFamily == CHIP_FAMILY_RS740) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400) ||
+ (info->ChipFamily == CHIP_FAMILY_RS480) ||
+ IS_R500_3D) {
+ if (info->num_gb_pipes == 0) {
+ uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
+
+ info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+ if (IS_R500_3D)
+ OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+ }
+ } else {
+ if (info->num_gb_pipes == 0) {
+ if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+ (info->ChipFamily == CHIP_FAMILY_R350)) {
+ /* R3xx chips */
+ info->num_gb_pipes = 2;
+ } else {
+ /* RV3xx chips */
+ info->num_gb_pipes = 1;
+ }
}
}
+
+ if (IS_R300_3D || IS_R500_3D)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "num pipes is %d\n", info->num_gb_pipes);
+
+ if (IS_R300_3D || IS_R500_3D) {
+ uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
+
+ switch(info->num_gb_pipes) {
+ case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+ case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+ case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+ default:
+ case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+ }
+
+ OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
+ OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+ OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+ OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
+ R300_DC_AUTOFLUSH_ENABLE |
+ R300_DC_DC_DISABLE_IGNORE_PE));
+ } else
+ OUTREG(RADEON_RB3D_CNTL, 0);
+
+ RADEONEngineReset(pScrn);
}
- if (IS_R300_3D || IS_R500_3D)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "num pipes is %d\n", info->num_gb_pipes);
-
- if (IS_R300_3D || IS_R500_3D) {
- uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
-
- switch(info->num_gb_pipes) {
- case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
- case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
- case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
- default:
- case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
- }
-
- OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
- OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
- OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
- OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
- R300_DC_AUTOFLUSH_ENABLE |
- R300_DC_DC_DISABLE_IGNORE_PE));
- } else
- OUTREG(RADEON_RB3D_CNTL, 0);
-
- RADEONEngineReset(pScrn);
-
switch (info->CurrentLayout.pixel_code) {
case 8: info->datatype = 2; break;
case 15: info->datatype = 3; break;
@@ -556,6 +561,149 @@ int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info)
}
}
+drmBufPtr RADEONCSGetBuffer(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ info->ib_gem_fake.address = xcalloc(1, RADEON_BUFFER_SIZE);
+ if (!info->ib_gem_fake.address)
+ return NULL;
+
+ info->ib_gem_fake.used = 0;
+ info->ib_gem_fake.total = RADEON_BUFFER_SIZE - (16*4); // reserve 16 dwords
+ return &info->ib_gem_fake;
+}
+
+void RADEONCSFlushIndirect(ScrnInfoPtr pScrn, int discard)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct drm_radeon_cs args;
+ int ret;
+ RING_LOCALS;
+
+ /* always add the cache flushes to the end of the IB */
+ info->indirectBuffer->total += 16 * 4;
+
+ /* end of IB purge caches */
+ if (info->cs_used_depth) {
+ RADEON_PURGE_ZCACHE();
+ info->cs_used_depth = 0;
+ }
+
+ RADEON_PURGE_CACHE();
+ RADEON_WAIT_UNTIL_IDLE();
+
+ args.packets = (unsigned long)info->ib_gem_fake.address;
+ args.dwords = info->indirectBuffer->used / sizeof(uint32_t);
+
+ ret = drmCommandWriteRead(info->drmFD, DRM_RADEON_CS,
+ &args, sizeof(args));
+
+ if (ret) {
+ FatalError("DRM Command submission failure %d\n", ret);
+ return;
+ }
+
+
+ info->indirectStart = 0;
+ info->indirectBuffer->used = 0;
+ info->indirectBuffer->total -= 16*4;
+
+ if (info->bufmgr)
+ radeon_gem_bufmgr_post_submit(info->bufmgr);
+
+ /* copy some state into the buffer now - we need to add 2D state to each
+ buffer as the kernel needs to use the blit engine to move stuff around */
+ if (info->reemit_current2d)
+ info->reemit_current2d(pScrn, 0);
+}
+
+void RADEONCSReleaseIndirect(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (!info->indirectBuffer) return;
+ RADEONCSFlushIndirect(pScrn, 0);
+ xfree(info->ib_gem_fake.address);
+ info->ib_gem_fake.address = NULL;
+ info->indirectBuffer = NULL;
+
+}
+
+drmBufPtr RADEONGEMGetBuffer(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int ret;
+
+ info->mm.gem_ib_memory = radeon_allocate_memory(pScrn, RADEON_POOL_GART, RADEON_BUFFER_SIZE,
+ 0, 0, "Accel IB", 0);
+
+ if (!info->mm.gem_ib_memory) {
+ ErrorF("Unable to map allocate IB\n");
+ return NULL;
+ }
+
+ radeon_bind_memory(pScrn, info->mm.gem_ib_memory);
+ ret = radeon_map_memory(pScrn, info->mm.gem_ib_memory);
+ if (ret) {
+ ErrorF("Unable to map IB\n");
+ radeon_free_memory(pScrn, info->mm.gem_ib_memory);
+ return NULL;
+ }
+ info->ib_gem_fake.address = info->mm.gem_ib_memory->map;
+ info->ib_gem_fake.used = 0;
+ info->ib_gem_fake.total = RADEON_BUFFER_SIZE;
+
+ return &info->ib_gem_fake;
+}
+
+void RADEONGEMFlushIndirect(ScrnInfoPtr pScrn, int discard)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct drm_radeon_gem_indirect args;
+ struct drm_radeon_gem_set_domain dom_args;
+
+ if (RADEON_VERBOSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Flushing IB\n");
+ }
+
+ args.handle = info->mm.gem_ib_memory->kernel_bo_handle;
+ args.used = info->indirectBuffer->used;
+
+
+ drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_INDIRECT,
+ &args, sizeof(args));
+
+ /* for now just wait for the buffer to come around again */
+
+ dom_args.handle = info->mm.gem_ib_memory->kernel_bo_handle;
+ dom_args.read_domains = RADEON_GEM_DOMAIN_GTT;
+ dom_args.write_domain = 0;
+
+ drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_SET_DOMAIN,
+ &dom_args, sizeof(dom_args));
+
+ info->indirectStart = 0;
+ info->indirectBuffer->used = 0;
+}
+
+void RADEONGEMReleaseIndirect(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (RADEON_VERBOSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Releasing IB\n");
+ }
+
+ if (!info->indirectBuffer) return;
+
+ RADEONGEMFlushIndirect(pScrn, 0);
+
+ radeon_free_memory(pScrn, info->mm.gem_ib_memory);
+ info->mm.gem_ib_memory = NULL;
+ info->indirectBuffer = NULL;
+}
+
/* Get an indirect buffer for the CP 2D acceleration commands */
drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
{
@@ -566,6 +714,9 @@ drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
int size = 0;
int i = 0;
int ret;
+
+ if (info->new_cs)
+ return RADEONCSGetBuffer(pScrn);
#if 0
/* FIXME: pScrn->pScreen has not been initialized when this is first
@@ -631,6 +782,11 @@ void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard)
if (!buffer) return;
if (start == buffer->used && !discard) return;
+ if (info->new_cs) {
+ RADEONCSFlushIndirect(pScrn, discard);
+ return;
+ }
+
if (RADEON_VERBOSE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Flushing buffer %d\n",
buffer->idx);
@@ -665,10 +821,17 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn)
int start = info->indirectStart;
drmRadeonIndirect indirect;
+
+ if (info->new_cs) {
+ RADEONCSReleaseIndirect(pScrn);
+ return;
+ }
+
info->indirectBuffer = NULL;
info->indirectStart = 0;
if (!buffer) return;
+
if (RADEON_VERBOSE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Releasing buffer %d\n",
@@ -795,6 +958,7 @@ RADEONHostDataBlit(
ret = ( uint8_t* )&__head[__count];
__count += dwords;
+
ADVANCE_RING();
*y += *hpass;
@@ -932,7 +1096,7 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
#ifdef USE_EXA
if (info->useEXA) {
# ifdef XF86DRI
- if (info->directRenderingEnabled) {
+ if (info->directRenderingEnabled || info->drm_mode_setting) {
if (!RADEONDrawInitCP(pScreen))
return FALSE;
} else
@@ -953,7 +1117,7 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
}
#ifdef XF86DRI
- if (info->directRenderingEnabled)
+ if (info->directRenderingEnabled || info->drm_mode_setting)
RADEONAccelInitCP(pScreen, a);
else
#endif /* XF86DRI */
@@ -975,11 +1139,13 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR (pScrn);
#ifdef XF86DRI
- if (info->directRenderingEnabled) {
- RADEONSAREAPrivPtr pSAREAPriv;
-
- pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
- pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
+ if (info->directRenderingEnabled || info->drm_mode_setting) {
+ if (info->directRenderingEnabled) {
+ RADEONSAREAPrivPtr pSAREAPriv;
+
+ pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+ pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen);
+ }
RADEONInit3DEngineCP(pScrn);
} else
#endif
diff --git a/src/radeon_bufmgr.h b/src/radeon_bufmgr.h
new file mode 100644
index 0000000..a16ad9a
--- /dev/null
+++ b/src/radeon_bufmgr.h
@@ -0,0 +1,30 @@
+/**
+ * @file intel_bufmgr.h
+ *
+ * Public definitions of Intel-specific bufmgr functions.
+ */
+
+#ifndef RADEON_BUFMGR_H
+#define RADEON_BUFMGR_H
+
+#include "dri_bufmgr.h"
+
+struct radeon_bufmgr {
+ void (*emit_reloc)(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+};
+
+dri_bufmgr *radeon_bufmgr_gem_init(int fd);
+dri_bo *radeon_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
+ unsigned int handle);
+
+void radeon_bufmgr_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+
+dri_bufmgr *radeon_bufmgr_exa_init(ScrnInfoPtr pScrn);
+extern void radeon_bufmgr_exa_wait_rendering(dri_bo *bo);
+extern dri_bo *radeon_bufmgr_exa_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
+void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
+void radeon_bufmgr_pin(dri_bo *buf);
+void radeon_bufmgr_unpin(dri_bo *buf);
+uint32_t radeon_bufmgr_get_handle(dri_bo *buf);
+void radeon_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr);
+#endif
diff --git a/src/radeon_bufmgr_exa.c b/src/radeon_bufmgr_exa.c
new file mode 100644
index 0000000..64537a6
--- /dev/null
+++ b/src/radeon_bufmgr_exa.c
@@ -0,0 +1,324 @@
+/**************************************************************************
+ *
+ * Copyright © 2007-2008 Red Hat Inc.
+ * Copyright © 2007 Intel Corporation
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ * Eric Anholt <eric@anholt.net>
+ * Dave Airlie <airlied@linux.ie>
+ * Kristian Høgsberg <krh@redhat.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86drm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "xf86.h"
+#include "errno.h"
+#include "dri_bufmgr.h"
+#include "string.h"
+
+#include "radeon_reg.h"
+#include "radeon_probe.h"
+#include "radeon.h"
+#include "radeon_bufmgr.h"
+
+
+typedef struct _dri_bo_exa {
+ dri_bo bo;
+ struct radeon_memory *mem;
+ int refcount;
+ int reloc_count;
+ int map_count;
+ /* reloc list - add to list for relocs */
+ struct _dri_bo_exa *next;
+} dri_bo_exa;
+
+typedef struct _dri_bufmgr_exa {
+ dri_bufmgr bufmgr;
+ struct radeon_bufmgr radeon_bufmgr;
+ ScrnInfoPtr pScrn;
+ struct _dri_bo_exa *reloc_head;
+} dri_bufmgr_exa;
+
+static dri_bo *
+dri_exa_alloc(dri_bufmgr *bufmgr, const char *name,
+ unsigned long size, unsigned int alignment)
+
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)bufmgr;
+ RADEONInfoPtr info = RADEONPTR(bufmgr_exa->pScrn);
+ dri_bo_exa *exa_buf;
+
+ exa_buf = malloc(sizeof(*exa_buf));
+ if (!exa_buf)
+ return NULL;
+
+ exa_buf->refcount = 1;
+ exa_buf->mem = radeon_allocate_memory(bufmgr_exa->pScrn, RADEON_POOL_GART,
+ size, alignment, 0, name, 0);
+
+ exa_buf->bo.size = exa_buf->mem->size;
+ exa_buf->bo.offset = exa_buf->mem->offset;
+ exa_buf->bo.bufmgr = bufmgr;
+ exa_buf->next = NULL;
+ exa_buf->reloc_count = 0;
+ exa_buf->map_count = 0;
+
+ return &exa_buf->bo;
+}
+
+static void
+dri_exa_bo_reference(dri_bo *buf)
+{
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+ exa_buf->refcount++;
+}
+
+static void
+dri_exa_bo_unreference(dri_bo *buf)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+
+ if (!buf)
+ return;
+
+ if (--exa_buf->refcount == 0)
+ radeon_free_memory(bufmgr_exa->pScrn, exa_buf->mem);
+}
+
+static int
+dri_exa_bo_map(dri_bo *buf, int write_enable)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+
+ if (exa_buf->map_count++ != 0)
+ return 0;
+
+ radeon_map_memory(bufmgr_exa->pScrn, exa_buf->mem);
+ exa_buf->bo.virtual = exa_buf->mem->map;
+ return 0;
+}
+
+static int
+dri_exa_bo_unmap(dri_bo *buf)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+
+ if (--exa_buf->map_count > 0)
+ return 0;
+
+ radeon_unmap_memory(bufmgr_exa->pScrn, exa_buf->mem);
+ exa_buf->bo.virtual = 0;
+ return 0;
+}
+
+static void
+dri_bufmgr_exa_destroy(dri_bufmgr *bufmgr)
+{
+ free(bufmgr);
+}
+
+void radeon_bufmgr_exa_wait_rendering(dri_bo *buf)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ RADEONInfoPtr info = RADEONPTR(bufmgr_exa->pScrn);
+ struct drm_radeon_gem_set_domain dom_args;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+ int ret;
+
+ dom_args.handle = exa_buf->mem->kernel_bo_handle;
+ dom_args.read_domains = RADEON_GEM_DOMAIN_GTT;
+ dom_args.write_domain = 0;
+ ret = drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_SET_DOMAIN,
+ &dom_args, sizeof(dom_args));
+
+ return;
+}
+
+int radeon_bufmgr_subdata(dri_bo *buf, unsigned long offset,
+ unsigned long size, const void *data)
+{
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ RADEONInfoPtr info = RADEONPTR(bufmgr_exa->pScrn);
+ int ret;
+ /* go to pwrite */
+ struct drm_radeon_gem_pwrite pwrite;
+
+ pwrite.handle = exa_buf->mem->kernel_bo_handle;
+ pwrite.offset = offset;
+ pwrite.size = size;
+ pwrite.data_ptr = (uint64_t)(uintptr_t)data;
+
+ do {
+ ret = drmCommandWriteRead(info->drmFD, DRM_IOCTL_RADEON_GEM_PWRITE,
+ &pwrite, sizeof(pwrite));
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret != 0) {
+ fprintf(stderr,"Pwrite %lx at %lx failed\n", size, offset);
+ return -1;
+ }
+ return 0;
+}
+
+
+dri_bo *
+radeon_bufmgr_exa_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)bufmgr;
+ dri_bo_exa *exa_buf;
+
+ exa_buf = malloc(sizeof(*exa_buf));
+ if (!exa_buf)
+ return NULL;
+ exa_buf->refcount = 1;
+ exa_buf->mem = mem;
+ exa_buf->bo.size = exa_buf->mem->size;
+ exa_buf->bo.offset = exa_buf->mem->offset;
+ exa_buf->bo.bufmgr = bufmgr;
+ exa_buf->bo.virtual = exa_buf->mem->map;
+ exa_buf->next = NULL;
+ exa_buf->reloc_count = 0;
+ /* get map count right */
+ exa_buf->map_count = 1;
+
+ return &exa_buf->bo;
+}
+
+static void radeon_bufmgr_exa_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ ScrnInfoPtr pScrn = bufmgr_exa->pScrn;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+ uint32_t *__head = head;
+ uint32_t __count = *count_p;
+ dri_bo_exa *trav;
+
+ if (exa_buf->reloc_count == 0) {
+ dri_bo_reference(buf);
+
+ if (bufmgr_exa->reloc_head == NULL)
+ bufmgr_exa->reloc_head = exa_buf;
+ else {
+ trav = bufmgr_exa->reloc_head;
+ while (trav->next != NULL)
+ trav = trav->next;
+ trav->next = exa_buf;
+ }
+ }
+ exa_buf->reloc_count++;
+ OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 2));
+ OUT_RING(exa_buf->mem->kernel_bo_handle);
+ OUT_RING(read_domains);
+ OUT_RING(write_domain);
+ *count_p = __count;
+}
+
+/**
+ * Initializes the EXA buffer manager, which is just a thin wrapper
+ * around the EXA allocator.
+ *
+ * \param fd File descriptor of the opened DRM device.
+ * \param fence_type Driver-specific fence type used for fences with no flush.
+ * \param fence_type_flush Driver-specific fence type used for fences with a
+ * flush.
+ */
+dri_bufmgr *
+radeon_bufmgr_exa_init(ScrnInfoPtr pScrn)
+{
+ dri_bufmgr_exa *bufmgr_exa;
+
+ bufmgr_exa = calloc(1, sizeof(*bufmgr_exa));
+ bufmgr_exa->pScrn = pScrn;
+
+ bufmgr_exa->bufmgr.bo_alloc = dri_exa_alloc;
+ bufmgr_exa->bufmgr.bo_reference = dri_exa_bo_reference;
+ bufmgr_exa->bufmgr.bo_unreference = dri_exa_bo_unreference;
+ bufmgr_exa->bufmgr.bo_map = dri_exa_bo_map;
+ bufmgr_exa->bufmgr.bo_unmap = dri_exa_bo_unmap;
+ bufmgr_exa->bufmgr.destroy = dri_bufmgr_exa_destroy;
+ bufmgr_exa->bufmgr.bo_wait_rendering = radeon_bufmgr_exa_wait_rendering;
+ bufmgr_exa->radeon_bufmgr.emit_reloc = radeon_bufmgr_exa_emit_reloc;
+ return &bufmgr_exa->bufmgr;
+}
+
+void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)bufmgr;
+ struct _dri_bo_exa *trav, *prev;
+
+ if (!bufmgr_exa->reloc_head)
+ return;
+
+ trav = bufmgr_exa->reloc_head;
+ while (trav) {
+ prev = trav;
+ trav = trav->next;
+
+ prev->reloc_count = 0;
+ prev->next = NULL;
+ dri_bo_unreference(&prev->bo);
+ }
+ bufmgr_exa->reloc_head = NULL;
+
+}
+
+void radeon_bufmgr_pin(dri_bo *buf)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+
+ radeon_bind_memory(bufmgr_exa->pScrn, exa_buf->mem);
+}
+
+void radeon_bufmgr_unpin(dri_bo *buf)
+{
+ dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+
+ radeon_unbind_memory(bufmgr_exa->pScrn, exa_buf->mem);
+}
+
+uint32_t radeon_bufmgr_get_handle(dri_bo *buf)
+{
+ dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
+
+ return exa_buf->mem->kernel_bo_handle;
+}
diff --git a/src/radeon_bufmgr_exa.h b/src/radeon_bufmgr_exa.h
new file mode 100644
index 0000000..260322c
--- /dev/null
+++ b/src/radeon_bufmgr_exa.h
@@ -0,0 +1,14 @@
+#ifndef RADEON_BUFMGR_EXA_H
+#define RADEON_BUFMGR_EXA_H
+
+#include "dri_bufmgr.h"
+
+dri_bufmgr *radeon_bufmgr_exa_init(ScrnInfoPtr pScrn);
+extern void radeon_bufmgr_exa_wait_rendering(dri_bo *bo);
+extern dri_bo *radeon_bufmgr_exa_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
+void radeon_bufmgr_exa_emit_reloc(dri_bo *bo, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
+void radeon_bufmgr_pin(dri_bo *buf);
+void radeon_bufmgr_unpin(dri_bo *buf);
+uint32_t radeon_bufmgr_get_handle(dri_bo *buf);
+#endif
diff --git a/src/radeon_bufmgr_gem.c b/src/radeon_bufmgr_gem.c
new file mode 100644
index 0000000..db28edc
--- /dev/null
+++ b/src/radeon_bufmgr_gem.c
@@ -0,0 +1,530 @@
+/**************************************************************************
+ *
+ * Copyright © 2007-2008 Red Hat Inc.
+ * Copyright © 2007 Intel Corporation
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ * Eric Anholt <eric@anholt.net>
+ * Dave Airlie <airlied@linux.ie>
+ * Kristian Høgsberg <krh@redhat.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86drm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+#include "xf86.h"
+#include "errno.h"
+#include "dri_bufmgr.h"
+#include "string.h"
+
+#include "radeon_reg.h"
+#include "radeon_probe.h"
+#include "radeon.h"
+#include "radeon_bufmgr.h"
+
+#define DBG(...) do { \
+ if (bufmgr_gem->bufmgr.debug) \
+ fprintf(stderr, __VA_ARGS__); \
+} while (0)
+
+typedef struct _dri_bo_gem {
+ dri_bo bo;
+ int refcount;
+ int reloc_count;
+ int map_count;
+ /* reloc list - add to list for relocs */
+ uint32_t gem_handle;
+ const char *name;
+ struct _dri_bo_gem *next;
+ struct _dri_bo_gem *reloc_next;
+ int in_vram; /* have we migrated this bo to VRAM ever */
+} dri_bo_gem;
+
+struct dri_gem_bo_bucket {
+ dri_bo_gem *head, **tail;
+ /**
+ * Limit on the number of entries in this bucket.
+ *
+ * 0 means that this caching at this bucket size is disabled.
+ * -1 means that there is no limit to caching at this size.
+ */
+ int max_entries;
+ int num_entries;
+};
+
+/* Arbitrarily chosen, 16 means that the maximum size we'll cache for reuse
+ * is 1 << 16 pages, or 256MB.
+ */
+#define RADEON_GEM_BO_BUCKETS 16
+
+typedef struct _dri_bufmgr_gem {
+ dri_bufmgr bufmgr;
+ struct radeon_bufmgr radeon_bufmgr;
+ int fd;
+ struct _dri_bo_gem *reloc_head;
+
+ /** Array of lists of cached gem objects of power-of-two sizes */
+ struct dri_gem_bo_bucket cache_bucket[RADEON_GEM_BO_BUCKETS];
+} dri_bufmgr_gem;
+
+static int
+logbase2(int n)
+{
+ int i = 1;
+ int log2 = 0;
+
+ while (n > i) {
+ i *= 2;
+ log2++;
+ }
+
+ return log2;
+}
+
+static struct dri_gem_bo_bucket *
+dri_gem_bo_bucket_for_size(dri_bufmgr_gem *bufmgr_gem, unsigned long size)
+{
+ int i;
+
+ /* We only do buckets in power of two increments */
+ if ((size & (size - 1)) != 0)
+ return NULL;
+
+ /* We should only see sizes rounded to pages. */
+ assert((size % 4096) == 0);
+
+ /* We always allocate in units of pages */
+ i = ffs(size / 4096) - 1;
+ if (i >= RADEON_GEM_BO_BUCKETS)
+ return NULL;
+
+ return &bufmgr_gem->cache_bucket[i];
+}
+
+
+static dri_bo *
+dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
+ unsigned long size, unsigned int alignment)
+
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+ struct drm_radeon_gem_create args;
+ int ret;
+ unsigned int page_size = getpagesize();
+ dri_bo_gem *gem_bo;
+ struct dri_gem_bo_bucket *bucket;
+ int alloc_from_cache = 0;
+ unsigned long bo_size;
+
+ /* Round the allocated size up to a power of two number of pages. */
+ bo_size = 1 << logbase2(size);
+ if (bo_size < page_size)
+ bo_size = page_size;
+ bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo_size);
+
+ /* If we don't have caching at this size, don't actually round the
+ * allocation up.
+ */
+ if (bucket == NULL || bucket->max_entries == 0) {
+ bo_size = size;
+ if (bo_size < page_size)
+ bo_size = page_size;
+ }
+
+ /* Get a buffer out of the cache if available */
+ if (bucket != NULL && bucket->num_entries > 0) {
+ struct drm_radeon_gem_set_domain args;
+
+ gem_bo = bucket->head;
+ args.handle = gem_bo->gem_handle;
+ args.read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+ args.write_domain = 0;
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_RADEON_GEM_SET_DOMAIN, &args);
+ alloc_from_cache = (ret == 0);
+
+ if (alloc_from_cache) {
+ bucket->head = gem_bo->next;
+ if (gem_bo->next == NULL)
+ bucket->tail = &bucket->head;
+ bucket->num_entries--;
+ }
+ }
+
+ if (!alloc_from_cache) {
+
+ gem_bo = calloc(1, sizeof(*gem_bo));
+ if (!gem_bo)
+ return NULL;
+
+ gem_bo->bo.size = bo_size;
+ args.size = bo_size;
+ args.alignment = alignment;
+ args.initial_domain = RADEON_GEM_DOMAIN_CPU;
+ args.no_backing_store = 0;
+
+ ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_CREATE, &args, sizeof(args));
+ gem_bo->gem_handle = args.handle;
+ if (ret != 0) {
+ free(gem_bo);
+ return NULL;
+ }
+ gem_bo->bo.bufmgr = bufmgr;
+ }
+
+ gem_bo->refcount = 1;
+ gem_bo->reloc_count = 0;
+ gem_bo->map_count = 0;
+ gem_bo->in_vram = 0;
+ gem_bo->name = name;
+
+ DBG("bo_create: buf %d (%s) %ldb: %d\n",
+ gem_bo->gem_handle, gem_bo->name, size, alloc_from_cache);
+
+ return &gem_bo->bo;
+}
+
+static void
+dri_gem_bo_reference(dri_bo *bo)
+{
+ dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+ gem_bo->refcount++;
+}
+
+static void dri_gem_bo_free(dri_bo *bo)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+ struct drm_gem_close args;
+
+ if (gem_bo->map_count)
+ munmap(gem_bo->bo.virtual, gem_bo->bo.size);
+
+ /* close object */
+ args.handle = gem_bo->gem_handle;
+ ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &args);
+ free(gem_bo);
+}
+
+static void
+dri_gem_bo_unreference(dri_bo *bo)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+
+ if (!bo)
+ return;
+
+ if (--gem_bo->refcount == 0) {
+ struct dri_gem_bo_bucket *bucket;
+
+
+ bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo->size);
+ /* Put the buffer into our internal cache for reuse if we can. */
+ if ((gem_bo->in_vram == 0) && (bucket != NULL &&
+ (bucket->max_entries == -1 ||
+ (bucket->max_entries > 0 &&
+ bucket->num_entries < bucket->max_entries))))
+ {
+ DBG("bo_unreference final: %d (%s) 1\n",
+ gem_bo->gem_handle, gem_bo->name);
+
+ gem_bo->name = 0;
+
+ gem_bo->next = NULL;
+ *bucket->tail = gem_bo;
+ bucket->tail = &gem_bo->next;
+ bucket->num_entries++;
+ } else {
+ DBG("bo_unreference final: %d (%s) 0 - free %d\n",
+ gem_bo->gem_handle, gem_bo->name, gem_bo->in_vram);
+ dri_gem_bo_free(bo);
+ }
+
+ return;
+ }
+}
+
+static int
+dri_gem_bo_map(dri_bo *bo, int write_enable)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+ struct drm_radeon_gem_mmap args;
+ int ret;
+
+ if (gem_bo->map_count++ != 0)
+ return 0;
+
+ args.handle = gem_bo->gem_handle;
+ args.offset = 0;
+ args.size = gem_bo->bo.size;
+
+ ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_MMAP, &args, sizeof(args));
+ if (!ret)
+ gem_bo->bo.virtual = (void *)(unsigned long)args.addr_ptr;
+
+ return ret;
+}
+
+static int
+dri_gem_bo_unmap(dri_bo *buf)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
+ dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+
+ if (--gem_bo->map_count > 0)
+ return 0;
+
+ munmap(gem_bo->bo.virtual, gem_bo->bo.size);
+ gem_bo->bo.virtual = 0;
+ return 0;
+}
+
+static void
+dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+ int i;
+
+ /* Free any cached buffer objects we were going to reuse */
+ for (i = 0; i < RADEON_GEM_BO_BUCKETS; i++) {
+ struct dri_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i];
+ dri_bo_gem *bo_gem;
+
+ while ((bo_gem = bucket->head) != NULL) {
+ bucket->head = bo_gem->next;
+ if (bo_gem->next == NULL)
+ bucket->tail = &bucket->head;
+ bucket->num_entries--;
+
+ dri_gem_bo_free(&bo_gem->bo);
+ }
+ }
+ free(bufmgr);
+}
+
+void radeon_bufmgr_gem_wait_rendering(dri_bo *buf)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
+ struct drm_radeon_gem_set_domain dom_args;
+ dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+ int ret;
+
+ dom_args.handle = gem_bo->gem_handle;
+ dom_args.read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+ dom_args.write_domain = 0;
+ ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_SET_DOMAIN,
+ &dom_args, sizeof(dom_args));
+ return;
+}
+
+/**
+ * Returns a dri_bo wrapping the given buffer object handle.
+ *
+ * This can be used when one application needs to pass a buffer object
+ * to another.
+ */
+dri_bo *
+radeon_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
+ unsigned int handle)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+ dri_bo_gem *bo_gem;
+ int ret;
+ struct drm_gem_open open_arg;
+
+ bo_gem = calloc(1, sizeof(*bo_gem));
+ if (!bo_gem)
+ return NULL;
+
+ memset(&open_arg, 0, sizeof(open_arg));
+ open_arg.name = handle;
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
+ if (ret != 0) {
+ fprintf(stderr, "Couldn't reference %s handle 0x%08x: %s\n",
+ name, handle, strerror(-ret));
+ free(bo_gem);
+ return NULL;
+ }
+ bo_gem->bo.size = open_arg.size;
+ bo_gem->bo.offset = 0;
+ bo_gem->bo.virtual = NULL;
+ bo_gem->bo.bufmgr = bufmgr;
+ bo_gem->name = name;
+ bo_gem->refcount = 1;
+ bo_gem->gem_handle = open_arg.handle;
+
+ return &bo_gem->bo;
+}
+
+#define BUF_OUT_RING(x) do { \
+ __head[__count++] = (x); \
+ } while (0)
+
+void radeon_bufmgr_gem_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
+ dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+ uint32_t *__head = head;
+ uint32_t __count = *count_p;
+ dri_bo_gem *trav;
+
+ if (gem_bo->reloc_count == 0) {
+ dri_bo_reference(buf);
+
+ if (bufmgr_gem->reloc_head == NULL)
+ bufmgr_gem->reloc_head = gem_bo;
+ else {
+ trav = bufmgr_gem->reloc_head;
+ while (trav->reloc_next != NULL)
+ trav = trav->reloc_next;
+ trav->reloc_next = gem_bo;
+ }
+ }
+
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ if (gem_bo->in_vram == 0)
+ DBG("bo_into vram: buf %d (%s) %d %d\n",
+ gem_bo->gem_handle, gem_bo->name, read_domains, write_domain);
+
+ gem_bo->in_vram = 1;
+ }
+
+ gem_bo->reloc_count++;
+ BUF_OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 2));
+ BUF_OUT_RING(gem_bo->gem_handle);
+ BUF_OUT_RING(read_domains);
+ BUF_OUT_RING(write_domain);
+ *count_p = __count;
+}
+
+/**
+ * Enables unlimited caching of buffer objects for reuse.
+ *
+ * This is potentially very memory expensive, as the cache at each bucket
+ * size is only bounded by how many buffers of that size we've managed to have
+ * in flight at once.
+ */
+void
+radeon_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+ int i;
+
+ for (i = 0; i < RADEON_GEM_BO_BUCKETS; i++) {
+ bufmgr_gem->cache_bucket[i].max_entries = -1;
+ }
+}
+
+/**
+ * Initializes the GEM buffer manager, which is just a thin wrapper
+ * around the GEM allocator.
+ *
+ * \param fd File descriptor of the opened DRM device.
+ * \param fence_type Driver-specific fence type used for fences with no flush.
+ * \param fence_type_flush Driver-specific fence type used for fences with a
+ * flush.
+ */
+dri_bufmgr *
+radeon_bufmgr_gem_init(int fd)
+{
+ dri_bufmgr_gem *bufmgr_gem;
+ int i;
+
+ bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
+ bufmgr_gem->fd = fd;
+
+ bufmgr_gem->bufmgr.bo_alloc = dri_gem_bo_alloc;
+ bufmgr_gem->bufmgr.bo_reference = dri_gem_bo_reference;
+ bufmgr_gem->bufmgr.bo_unreference = dri_gem_bo_unreference;
+ bufmgr_gem->bufmgr.bo_map = dri_gem_bo_map;
+ bufmgr_gem->bufmgr.bo_unmap = dri_gem_bo_unmap;
+ bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy;
+ bufmgr_gem->bufmgr.bo_wait_rendering = radeon_bufmgr_gem_wait_rendering;
+ bufmgr_gem->radeon_bufmgr.emit_reloc = radeon_bufmgr_gem_emit_reloc;
+ /* Initialize the linked lists for BO reuse cache. */
+ for (i = 0; i < RADEON_GEM_BO_BUCKETS; i++)
+ bufmgr_gem->cache_bucket[i].tail = &bufmgr_gem->cache_bucket[i].head;
+ bufmgr_gem->bufmgr.debug = 0;
+ return &bufmgr_gem->bufmgr;
+}
+
+
+void radeon_gem_bufmgr_post_submit(dri_bufmgr *bufmgr)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+ struct _dri_bo_gem *trav, *prev;
+
+ if (!bufmgr_gem->reloc_head)
+ return;
+
+ trav = bufmgr_gem->reloc_head;
+ while (trav) {
+ prev = trav;
+ trav = trav->reloc_next;
+
+ prev->reloc_count = 0;
+ prev->reloc_next = NULL;
+ dri_bo_unreference(&prev->bo);
+ }
+ bufmgr_gem->reloc_head = NULL;
+
+}
+
+void radeon_gem_bufmgr_pin(dri_bo *buf)
+{
+}
+
+void radeon_gem_bufmgr_unpin(dri_bo *buf)
+{
+}
+
+uint32_t radeon_gem_bufmgr_get_handle(dri_bo *buf)
+{
+ dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+
+ return gem_bo->gem_handle;
+}
+
+void radeon_bufmgr_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
+{
+ struct radeon_bufmgr *radeon_bufmgr;
+
+ radeon_bufmgr = (struct radeon_bufmgr *)(buf->bufmgr + 1);
+ radeon_bufmgr->emit_reloc(buf, head, count_p, read_domains, write_domain);
+}
diff --git a/src/radeon_bufmgr_gem.h b/src/radeon_bufmgr_gem.h
new file mode 100644
index 0000000..e2f1ca6
--- /dev/null
+++ b/src/radeon_bufmgr_gem.h
@@ -0,0 +1,14 @@
+#ifndef RADEON_BUFMGR_GEM_H
+#define RADEON_BUFMGR_GEM_H
+
+#include "dri_bufmgr.h"
+
+dri_bufmgr *radeon_bufmgr_gem_init(ScrnInfoPtr pScrn);
+extern void radeon_bufmgr_gem_wait_rendering(dri_bo *bo);
+extern dri_bo *radeon_bufmgr_gem_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
+void radeon_bufmgr_gem_emit_reloc(dri_bo *bo, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
+void radeon_bufmgr_pin(dri_bo *buf);
+void radeon_bufmgr_unpin(dri_bo *buf);
+uint32_t radeon_bufmgr_get_handle(dri_bo *buf);
+#endif
diff --git a/src/radeon_common.h b/src/radeon_common.h
index 193c1f9..c3b7e3b 100644
--- a/src/radeon_common.h
+++ b/src/radeon_common.h
@@ -39,6 +39,9 @@
#include <inttypes.h>
#include "xf86drm.h"
+#include "radeon_drm.h"
+
+#if 0
/* WARNING: If you change any of these defines, make sure to change
* the kernel include file as well (radeon_drm.h)
*/
@@ -494,3 +497,13 @@ typedef struct drm_radeon_surface_free {
#define DRM_RADEON_VBLANK_CRTC2 2
#endif
+
+typedef drm_radeon_indirect_t drmRadeonIndirect;
+typedef drm_radeon_getparam_t drmRadeonGetParam;
+typedef drm_radeon_cp_stop_t drmRadeonCPStop;
+typedef drm_radeon_surface_alloc_t drmRadeonSurfaceAlloc;
+typedef drm_radeon_surface_free_t drmRadeonSurfaceFree;
+typedef drm_radeon_init_t drmRadeonInit;
+typedef drm_radeon_mem_init_heap_t drmRadeonMemInitHeap;
+typedef drm_radeon_setparam_t drmRadeonSetParam;
+#endif
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index d0c5229..15a3beb 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -62,11 +62,13 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
if (IS_R300_3D || IS_R500_3D) {
- BEGIN_ACCEL(3);
- OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
- OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
- OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
- FINISH_ACCEL();
+ if (!info->new_cs) {
+ BEGIN_ACCEL(3);
+ OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
+ OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
+ OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+ FINISH_ACCEL();
+ }
gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
@@ -688,7 +690,7 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
#ifdef ACCEL_CP
/* Make sure the CP is idle first */
- if (info->CPStarted) {
+ if (info->CPStarted || info->drm_mode_setting) {
int ret;
FLUSH_RING();
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 13c2b9c..1e1835a 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -96,12 +96,19 @@ avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable)
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(crtc->scrn);
unsigned char *RADEONMMIO = info->MMIO;
-
+ uint32_t location;
+
OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, 0);
if (enable) {
+
+ if (info->drm_mm)
+ location = info->fbLocation + radeon_crtc->cursor->offset;
+ else
+ location = info->fbLocation + radeon_crtc->cursor_offset + pScrn->fbOffset;
+
OUTREG(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
- info->fbLocation + radeon_crtc->cursor_offset + pScrn->fbOffset);
+ location);
OUTREG(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
((CURSOR_WIDTH - 1) << 16) | (CURSOR_HEIGHT - 1));
OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
@@ -203,6 +210,7 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
int xorigin = 0, yorigin = 0;
int stride = 256;
DisplayModePtr mode = &crtc->mode;
+ uint32_t offset;
if (x < 0) xorigin = -x+1;
if (y < 0) yorigin = -y+1;
@@ -235,8 +243,12 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
| (yorigin ? 0 : y)));
RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+ if (info->drm_mm)
+ offset = radeon_crtc->cursor->offset;
+ else
+ offset = radeon_crtc->cursor_offset + pScrn->fbOffset;
OUTREG(RADEON_CUR_OFFSET,
- radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+ offset + yorigin * stride);
} else if (crtc_id == 1) {
OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK
| (xorigin << 16)
@@ -246,8 +258,12 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
| (yorigin ? 0 : y)));
RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+ if (info->drm_mm)
+ offset = radeon_crtc->cursor->offset;
+ else
+ offset = radeon_crtc->cursor_offset + pScrn->fbOffset;
OUTREG(RADEON_CUR2_OFFSET,
- radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+ offset + yorigin * stride);
}
}
}
@@ -301,10 +317,15 @@ radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(pScrn);
CURSOR_SWAPPING_DECL_MMIO
- uint32_t *d = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset);
+ uint32_t *d;
RADEONCTRACE(("RADEONLoadCursorARGB\n"));
+ if (info->drm_mm)
+ d = (uint32_t *)radeon_crtc->cursor->map;
+ else
+ d = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset);
+
info->cursor_argb = TRUE;
CURSOR_SWAPPING_START();
@@ -336,7 +357,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
height = ((size_bytes * xf86_config->num_crtc) + width_bytes - 1) / width_bytes;
#ifdef USE_XAA
- if (!info->useEXA) {
+ if (!info->useEXA && !info->drm_mm) {
int align = IS_AVIVO_VARIANT ? 4096 : 256;
FBAreaPtr fbarea;
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index a192811..9fa0add 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -40,6 +40,8 @@
#include <string.h>
#include <stdio.h>
+#include <errno.h>
+#include <sys/ioctl.h>
/* Driver data structures */
#include "radeon.h"
@@ -49,6 +51,8 @@
#include "radeon_dri.h"
#include "radeon_version.h"
+#include "radeon_drm.h"
+
/* X and server generic header files */
#include "xf86.h"
#include "xf86PciInfo.h"
@@ -62,17 +66,31 @@
static size_t radeon_drm_page_size;
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+#define DRI_SUPPORTS_CLIP_NOTIFY 1
+#else
+#define DRI_SUPPORTS_CLIP_NOTIFY 0
+#endif
+
+#if (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 4))
+#define DRI_DRIVER_FRAMEBUFFER_MAP 1
+#else
+#define DRI_DRIVER_FRAMEBUFFER_MAP 0
+#endif
static void RADEONDRITransitionTo2d(ScreenPtr pScreen);
static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
+static Bool radeon_dri_gart_init(ScreenPtr pScreen);
+
#ifdef DAMAGE
static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg);
-#if (DRIINFO_MAJOR_VERSION > 5 || \
- (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+#if DRI_SUPPORTS_CLIP_NOTIFY
static void RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
#endif
#endif
@@ -345,6 +363,120 @@ static void RADEONDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
#endif
}
+
+uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct drm_gem_flink flink;
+ int ret;
+
+ if (mem && mem->kernel_bo_handle) {
+ if (!mem->kernel_name) {
+ flink.handle = mem->kernel_bo_handle;
+ ret = ioctl(info->drmFD, DRM_IOCTL_GEM_FLINK, &flink);
+ if (ret != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to name buffer %d\n", -errno);
+ return -1;
+ }
+ mem->kernel_name = flink.name;
+ }
+ return mem->kernel_name;
+ }
+ return -1;
+}
+
+static void radeon_update_sarea(ScrnInfoPtr pScrn, RADEONSAREAPrivPtr sarea)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int cpp = info->CurrentLayout.pixel_bytes;
+ sarea->front_handle = -1;
+ sarea->back_handle = -1;
+ sarea->depth_handle = -1;
+
+ if (info->drm_mm){
+ /* get handles and use them */
+ sarea->front_handle = radeon_name_buffer(pScrn, info->mm.front_buffer);
+
+ sarea->front_pitch = info->frontPitch * cpp;
+ sarea->back_pitch = info->backPitch * cpp;
+ sarea->depth_pitch = info->depthPitch * cpp;
+ ErrorF("front handle is %x\n", sarea->front_handle);
+ sarea->back_handle = radeon_name_buffer(pScrn, info->mm.back_buffer);
+ sarea->depth_handle = radeon_name_buffer(pScrn, info->mm.depth_buffer);
+
+ }
+}
+
+/* so we need to add a frontbuffer map no matter what */
+#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
+#define ROUND_TO_PAGE(x) ROUND_TO((x), radeon_drm_page_size)
+
+static void
+radeon_update_screen_private(ScrnInfoPtr pScrn, RADEONSAREAPrivPtr sarea)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONDRIPtr pRADEONDRI;
+
+ pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate;
+ info->pDRIInfo->frameBufferPhysicalAddress = (char *) info->LinearAddr;
+ info->pDRIInfo->frameBufferStride = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+ info->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes);
+#if DRI_DRIVER_FRAMEBUFFER_MAP
+ info->pDRIInfo->hFrameBuffer = info->fb_map_handle;
+#endif
+ /* overload these */
+ pRADEONDRI->gartTexHandle = radeon_name_buffer(pScrn, info->mm.gart_texture_buffer);
+ pRADEONDRI->textureOffset = radeon_name_buffer(pScrn, info->mm.texture_buffer);
+ pRADEONDRI->frontOffset = radeon_name_buffer(pScrn, info->mm.front_buffer);
+ pRADEONDRI->backOffset = radeon_name_buffer(pScrn, info->mm.back_buffer);
+ pRADEONDRI->depthOffset = radeon_name_buffer(pScrn, info->mm.depth_buffer);
+}
+
+static Bool
+radeon_update_dri_mappings(ScrnInfoPtr pScrn, RADEONSAREAPrivPtr sarea)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ uint32_t fb_addr, fb_size;
+ int ret;
+
+ if (!info->drm_mm)
+ return TRUE;
+
+ fb_addr = info->mm.front_buffer->offset + info->LinearAddr;
+ fb_size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes);
+
+ if (info->fb_map_handle) {
+ drmRmMap(info->drmFD, info->fb_map_handle);
+ info->fb_map_handle = 0;
+ }
+
+ ret = drmAddMap(info->drmFD, fb_addr, fb_size, DRM_FRAME_BUFFER, 0,
+ &info->fb_map_handle);
+
+ ErrorF("adding fb map from %x for %x ret %d %x\n", fb_addr, fb_size, ret, info->fb_map_handle);
+
+ if (ret < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool radeon_update_dri_buffers(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ Bool success;
+ RADEONSAREAPrivPtr sarea = DRIGetSAREAPrivate(pScrn->pScreen);
+ success = radeon_update_dri_mappings(pScrn, sarea);
+
+ if (!success)
+ return FALSE;
+
+ radeon_update_sarea(pScrn, sarea);
+ radeon_update_screen_private(pScrn, sarea);
+ return TRUE;
+}
+
/* Called when the X server is woken up to allow the last client's
* context to be saved and the X server's context to be loaded. This is
* not necessary for the Radeon since the client detects when it's
@@ -362,7 +494,7 @@ static void RADEONEnterServer(ScreenPtr pScreen)
RADEON_MARK_SYNC(info, pScrn);
pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
- if (pSAREAPriv->ctxOwner != DRIGetContext(pScrn->pScreen)) {
+ if (pSAREAPriv->ctx_owner != DRIGetContext(pScrn->pScreen)) {
info->XInited3D = FALSE;
info->needCacheFlush = (info->ChipFamily >= CHIP_FAMILY_R300);
}
@@ -694,25 +826,37 @@ static void RADEONDRIInitGARTValues(RADEONInfoPtr info)
info->gartOffset = 0;
- /* Initialize the CP ring buffer data */
- info->ringStart = info->gartOffset;
- info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size;
- info->ringSizeLog2QW = RADEONMinBits(info->ringSize*1024*1024/8)-1;
+ if (!info->drm_mm) {
+ /* Initialize the CP ring buffer data */
+ info->ringStart = info->gartOffset;
+ info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size;
+ info->ringSizeLog2QW = RADEONMinBits(info->ringSize*1024*1024/8)-1;
- info->ringReadOffset = info->ringStart + info->ringMapSize;
- info->ringReadMapSize = radeon_drm_page_size;
+ info->ringReadOffset = info->ringStart + info->ringMapSize;
+ info->ringReadMapSize = radeon_drm_page_size;
/* Reserve space for vertex/indirect buffers */
- info->bufStart = info->ringReadOffset + info->ringReadMapSize;
- info->bufMapSize = info->bufSize*1024*1024;
-
- /* Reserve the rest for GART textures */
- info->gartTexStart = info->bufStart + info->bufMapSize;
- s = (info->gartSize*1024*1024 - info->gartTexStart);
- l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
- info->gartTexMapSize = (s >> l) << l;
- info->log2GARTTexGran = l;
+ info->bufStart = info->ringReadOffset + info->ringReadMapSize;
+ info->bufMapSize = info->bufSize*1024*1024;
+
+ /* Reserve the rest for GART textures */
+ info->gartTexStart = info->bufStart + info->bufMapSize;
+ s = (info->gartSize*1024*1024 - info->gartTexStart);
+ l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+ if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
+ info->gartTexMapSize = (s >> l) << l;
+ info->log2GARTTexGran = l;
+
+ } else {
+ s = (8*1024*1024);
+ l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+ l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+ if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
+ info->gartTexMapSize = (s >> l) << l;
+ info->log2GARTTexGran = l;
+ }
+
+
}
/* Set AGP transfer mode according to requests and constraints */
@@ -884,6 +1028,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO,
"[agp] ring handle = 0x%08x\n", info->ringHandle);
+#if 0
if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,
&info->ring) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n");
@@ -892,7 +1037,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO,
"[agp] Ring mapped at 0x%08lx\n",
(unsigned long)info->ring);
-
+#endif
if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize,
DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -903,6 +1048,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
"[agp] ring read ptr handle = 0x%08x\n",
info->ringReadPtrHandle);
+#if 0
if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
&info->ringReadPtr) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -912,7 +1058,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO,
"[agp] Ring read ptr mapped at 0x%08lx\n",
(unsigned long)info->ringReadPtr);
-
+#endif
if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize,
DRM_AGP, 0, &info->bufHandle) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -986,7 +1132,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
}
xf86DrvMsg(pScreen->myNum, X_INFO,
"[pci] ring handle = 0x%08x\n", info->ringHandle);
-
+#if 0
if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,
&info->ring) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n");
@@ -998,6 +1144,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO,
"[pci] Ring contents 0x%08lx\n",
*(unsigned long *)(pointer)info->ring);
+#endif
if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize,
DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
@@ -1008,7 +1155,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO,
"[pci] ring read ptr handle = 0x%08x\n",
info->ringReadPtrHandle);
-
+#if 0
if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,
&info->ringReadPtr) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -1021,6 +1168,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO,
"[pci] Ring read ptr contents 0x%08lx\n",
*(unsigned long *)(pointer)info->ringReadPtr);
+#endif
if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize,
DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
@@ -1073,6 +1221,9 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
*/
static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen)
{
+
+ if (info->drm_mm)
+ return TRUE;
/* Map registers */
info->registerSize = info->MMIOSize;
if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize,
@@ -1094,12 +1245,12 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
memset(&drmInfo, 0, sizeof(drmRadeonInit));
if ( info->ChipFamily >= CHIP_FAMILY_R300 )
- drmInfo.func = DRM_RADEON_INIT_R300_CP;
+ drmInfo.func = RADEON_INIT_R300_CP;
else
if ( info->ChipFamily >= CHIP_FAMILY_R200 )
- drmInfo.func = DRM_RADEON_INIT_R200_CP;
+ drmInfo.func = RADEON_INIT_R200_CP;
else
- drmInfo.func = DRM_RADEON_INIT_CP;
+ drmInfo.func = RADEON_INIT_CP;
drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec);
drmInfo.is_pci = (info->cardType!=CARD_AGP);
@@ -1111,19 +1262,22 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
drmInfo.fb_bpp = info->CurrentLayout.pixel_code;
drmInfo.depth_bpp = (info->depthBits - 8) * 2;
- drmInfo.front_offset = info->frontOffset;
- drmInfo.front_pitch = info->frontPitch * cpp;
- drmInfo.back_offset = info->backOffset;
- drmInfo.back_pitch = info->backPitch * cpp;
- drmInfo.depth_offset = info->depthOffset;
- drmInfo.depth_pitch = info->depthPitch * drmInfo.depth_bpp / 8;
-
- drmInfo.fb_offset = info->fbHandle;
- drmInfo.mmio_offset = info->registerHandle;
- drmInfo.ring_offset = info->ringHandle;
- drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
- drmInfo.buffers_offset = info->bufHandle;
- drmInfo.gart_textures_offset= info->gartTexHandle;
+ if (!info->drm_mm) {
+ drmInfo.front_offset = info->frontOffset;
+ drmInfo.front_pitch = info->frontPitch * cpp;
+ drmInfo.back_offset = info->backOffset;
+ drmInfo.back_pitch = info->backPitch * cpp;
+ drmInfo.depth_offset = info->depthOffset;
+ drmInfo.depth_pitch = info->depthPitch * drmInfo.depth_bpp / 8;
+
+ drmInfo.fb_offset = info->fbHandle;
+ drmInfo.mmio_offset = info->registerHandle;
+ drmInfo.ring_offset = info->ringHandle;
+ drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
+ drmInfo.buffers_offset = info->bufHandle;
+ drmInfo.gart_textures_offset= info->gartTexHandle;
+ } else {
+ }
if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT,
&drmInfo, sizeof(drmRadeonInit)) < 0)
@@ -1133,7 +1287,8 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
* registers back to their default values, so we need to restore
* those engine register here.
*/
- RADEONEngineRestore(pScrn);
+ if (!info->drm_mm)
+ RADEONEngineRestore(pScrn);
return TRUE;
}
@@ -1329,12 +1484,11 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
/* Get DRM version & close DRM */
info->pKernelDRMVersion = drmGetVersion(fd);
- drmClose(fd);
if (info->pKernelDRMVersion == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] RADEONDRIGetVersion failed to get the DRM version\n"
"[dri] Disabling DRI.\n");
- return FALSE;
+ goto fail;
}
/* Now check if we qualify */
@@ -1368,10 +1522,29 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
req_patch);
drmFreeVersion(info->pKernelDRMVersion);
info->pKernelDRMVersion = NULL;
- return FALSE;
+ goto fail;
+ }
+
+ if (info->pKernelDRMVersion->version_minor >= 30) {
+ struct drm_radeon_gem_info mminfo;
+
+ if (!drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
+ {
+ info->drm_mm = TRUE;
+ info->mm.vram_start = mminfo.vram_start;
+ info->mm.vram_size = mminfo.vram_size;
+ info->mm.gart_start = mminfo.vram_start;
+ info->mm.gart_size = mminfo.gart_size;
+ ErrorF("initing %llx %llx %llx %llx\n", mminfo.gart_start,
+ mminfo.gart_size, mminfo.vram_start, mminfo.vram_size);
+ }
}
+ drmClose(fd);
return TRUE;
+fail:
+ drmClose(fd);
+ return FALSE;
}
Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
@@ -1380,6 +1553,9 @@ Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int value = 0;
+ if (info->drm_mode_setting)
+ return TRUE;
+
if (!info->want_vblank_interrupts)
on = FALSE;
@@ -1399,6 +1575,44 @@ Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
return TRUE;
}
+Bool RADEONDRIDoMappings(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ /* DRIScreenInit doesn't add all the
+ * common mappings. Add additional
+ * mappings here.
+ */
+ if (!RADEONDRIMapInit(info, pScreen)) {
+ RADEONDRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ radeon_update_sarea(pScrn, pSAREAPriv);
+
+ /* DRIScreenInit adds the frame buffer
+ map, but we need it as well */
+ {
+ void *scratch_ptr;
+ int scratch_int;
+
+ DRIGetDeviceInfo(pScreen, &info->fbHandle,
+ &scratch_int, &scratch_int,
+ &scratch_int, &scratch_int,
+ &scratch_ptr);
+ }
+
+ /* FIXME: When are these mappings unmapped? */
+
+ if (!RADEONInitVisualConfigs(pScreen)) {
+ RADEONDRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n");
+ return TRUE;
+
+}
/* Initialize the screen-specific data structures for the DRI and the
* Radeon. This is the main entry point to the device-specific
@@ -1462,10 +1676,23 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->ddxDriverMajorVersion = info->allowColorTiling ? 5 : 4;
pDRIInfo->ddxDriverMinorVersion = 3;
pDRIInfo->ddxDriverPatchVersion = 0;
- pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr + info->frontOffset;
- pDRIInfo->frameBufferSize = info->FbMapSize - info->FbSecureSize;
- pDRIInfo->frameBufferStride = (pScrn->displayWidth *
- info->CurrentLayout.pixel_bytes);
+
+#if DRI_DRIVER_FRAMEBUFFER_MAP
+ /* only map the fb ourselves if we have the memory manager in place */
+ if (info->drm_mm) {
+ pDRIInfo->frameBufferPhysicalAddress = 0;
+ pDRIInfo->frameBufferSize = 0;
+ pDRIInfo->frameBufferStride = 0;
+ pDRIInfo->dontMapFrameBuffer = TRUE;
+ } else
+#endif
+ {
+ pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr + info->frontOffset;
+ pDRIInfo->frameBufferSize = info->FbMapSize - info->FbSecureSize;
+ pDRIInfo->frameBufferStride = (pScrn->displayWidth *
+ info->CurrentLayout.pixel_bytes);
+ }
+
pDRIInfo->ddxDrawableTableEntry = RADEON_MAX_DRAWABLES;
pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES
< RADEON_MAX_DRAWABLES
@@ -1518,9 +1745,7 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
-#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \
- (DRIINFO_MAJOR_VERSION == 5 && \
- DRIINFO_MINOR_VERSION >= 1))
+#if DRI_SUPPORT_CLIP_NOTIFY
pDRIInfo->ClipNotify = RADEONDRIClipNotify;
#endif
@@ -1552,57 +1777,61 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo = NULL;
return FALSE;
}
- /* Initialize AGP */
- if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[agp] AGP failed to initialize. Disabling the DRI.\n" );
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "[agp] You may want to make sure the agpgart kernel "
- "module\nis loaded before the radeon kernel module.\n");
- RADEONDRICloseScreen(pScreen);
- return FALSE;
- }
-
- /* Initialize PCI */
- if ((info->cardType!=CARD_AGP) && !RADEONDRIPciInit(info, pScreen)) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[pci] PCI failed to initialize. Disabling the DRI.\n" );
- RADEONDRICloseScreen(pScreen);
- return FALSE;
- }
-
- /* DRIScreenInit doesn't add all the
- * common mappings. Add additional
- * mappings here.
- */
- if (!RADEONDRIMapInit(info, pScreen)) {
- RADEONDRICloseScreen(pScreen);
- return FALSE;
- }
- /* DRIScreenInit adds the frame buffer
- map, but we need it as well */
- {
- void *scratch_ptr;
- int scratch_int;
+ /* Now, nuke dri.c's dummy frontbuffer map setup if we did that. */
+ if (pDRIInfo->frameBufferSize != 0 && info->drm_mm) {
+ int tmp;
+ drm_handle_t fb_handle;
+ void *ptmp;
- DRIGetDeviceInfo(pScreen, &info->fbHandle,
- &scratch_int, &scratch_int,
- &scratch_int, &scratch_int,
- &scratch_ptr);
+ /* With the compat method, it will continue to report
+ * the wrong map out of GetDeviceInfo, which will break AIGLX.
+ */
+ DRIGetDeviceInfo(pScreen, &fb_handle, &tmp, &tmp, &tmp, &tmp, &ptmp);
+ drmRmMap(info->drmFD, fb_handle);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Removed DRI frontbuffer mapping in compatibility mode.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "DRIGetDeviceInfo will report incorrect frontbuffer "
+ "handle.\n");
+ }
+
+ if (info->drm_mm) {
+ int ret;
+ ret = radeon_dri_gart_init(pScreen);
+ if (!ret) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[gart] GART failed to initialize. Disabling the DRI.\n" );
+ RADEONDRICloseScreen(pScreen);
+ return FALSE;
+ }
+ } else {
+ if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) {
+ /* Initialize AGP */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] AGP failed to initialize. Disabling the DRI.\n" );
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] You may want to make sure the agpgart kernel "
+ "module\nis loaded before the radeon kernel module.\n");
+ RADEONDRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Initialize PCI */
+ if ((info->cardType!=CARD_AGP) && !RADEONDRIPciInit(info, pScreen)) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[pci] PCI failed to initialize. Disabling the DRI.\n" );
+ RADEONDRICloseScreen(pScreen);
+ return FALSE;
+ }
}
- /* FIXME: When are these mappings unmapped? */
-
- if (!RADEONInitVisualConfigs(pScreen)) {
- RADEONDRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n");
return TRUE;
}
+
static Bool RADEONDRIDoCloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -1644,14 +1873,18 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
return FALSE;
}
- /* Initialize the vertex buffers list */
- if (!RADEONDRIBufInit(info, pScreen)) {
- RADEONDRICloseScreen(pScreen);
- return FALSE;
+ if (!info->drm_mm) {
+ /* Initialize the vertex buffers list */
+ if (!RADEONDRIBufInit(info, pScreen)) {
+ RADEONDRICloseScreen(pScreen);
+ return FALSE;
+ }
}
- /* Initialize IRQ */
- RADEONDRIIrqInit(info, pScreen);
+ if (!info->drm_mode_setting) {
+ /* Initialize IRQ */
+ RADEONDRIIrqInit(info, pScreen);
+ }
/* Initialize kernel GART memory manager */
RADEONDRIGartHeapInit(info, pScreen);
@@ -1663,6 +1896,10 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+ if (info->drm_mm) {
+ /* init the handles into the sarea */
+
+ }
pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate;
pRADEONDRI->deviceID = info->Chipset;
@@ -1806,7 +2043,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
/* De-allocate all kernel resources */
memset(&drmInfo, 0, sizeof(drmRadeonInit));
- drmInfo.func = DRM_RADEON_CLEANUP_CP;
+ drmInfo.func = RADEON_CLEANUP_CP;
drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT,
&drmInfo, sizeof(drmRadeonInit));
@@ -1819,6 +2056,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
drmUnmap(info->buf, info->bufMapSize);
info->buf = NULL;
}
+#if 0
if (info->ringReadPtr) {
drmUnmap(info->ringReadPtr, info->ringReadMapSize);
info->ringReadPtr = NULL;
@@ -1827,6 +2065,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
drmUnmap(info->ring, info->ringMapSize);
info->ring = NULL;
}
+#endif
if (info->agpMemHandle != DRM_AGP_NO_HANDLE) {
drmAgpUnbind(info->drmFD, info->agpMemHandle);
drmAgpFree(info->drmFD, info->agpMemHandle);
@@ -1903,7 +2142,7 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg)
/* Don't want to do this when no 3d is active and pages are
* right-way-round
*/
- if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0)
+ if (!pSAREAPriv->pfState && pSAREAPriv->pfCurrentPage == 0)
return;
REGION_NULL(pScreen, ®ion);
@@ -1992,7 +2231,7 @@ static void RADEONEnablePageFlip(ScreenPtr pScreen)
.y2 = pScrn->virtualY - 1 };
RegionPtr pReg = REGION_CREATE(pScreen, &box, 1);
- pSAREAPriv->pfAllowPageFlip = 1;
+ pSAREAPriv->pfState = 1;
RADEONDRIRefreshArea(pScrn, pReg);
REGION_DESTROY(pScreen, pReg);
}
@@ -2007,7 +2246,7 @@ static void RADEONDisablePageFlip(ScreenPtr pScreen)
*/
RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
- pSAREAPriv->pfAllowPageFlip = 0;
+ pSAREAPriv->pfState = 0;
}
static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen)
@@ -2232,3 +2471,16 @@ int RADEONDRISetParam(ScrnInfoPtr pScrn, unsigned int param, int64_t value)
&radeonsetparam, sizeof(drmRadeonSetParam));
return ret;
}
+
+static Bool radeon_dri_gart_init(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ RADEONDRIInitGARTValues(info);
+
+ /* so we want to allocate the buffers/gart texmap */
+ /* ignore ring stuff */
+ return radeon_setup_gart_mem(pScreen);
+
+}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 45d2c2f..8fa32ab 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1621,6 +1621,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
}
pScrn->videoRam &= ~1023;
+
info->FbMapSize = pScrn->videoRam * 1024;
/* if the card is PCI Express reserve the last 32k for the gart table */
@@ -1748,56 +1749,62 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
from = X_PROBED;
info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffUL;
pScrn->memPhysBase = info->LinearAddr;
- if (dev->MemBase) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Linear address override, using 0x%016lx instead of 0x%016lx\n",
- dev->MemBase,
- info->LinearAddr);
- info->LinearAddr = dev->MemBase;
- from = X_CONFIG;
- } else if (!info->LinearAddr) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "No valid linear framebuffer address\n");
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, from,
- "Linear framebuffer at 0x%016lx\n", info->LinearAddr);
-#ifndef XSERVER_LIBPCIACCESS
- /* BIOS */
- from = X_PROBED;
- info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000;
- if (dev->BiosBase) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "BIOS address override, using 0x%08lx instead of 0x%08lx\n",
- dev->BiosBase,
- info->BIOSAddr);
- info->BIOSAddr = dev->BiosBase;
- from = X_CONFIG;
- }
- if (info->BIOSAddr) {
+ if (!info->drm_mode_setting) {
+ from = X_PROBED;
+ info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffUL;
+ pScrn->memPhysBase = info->LinearAddr;
+ if (dev->MemBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Linear address override, using 0x%016lx instead of 0x%016lx\n",
+ dev->MemBase,
+ info->LinearAddr);
+ info->LinearAddr = dev->MemBase;
+ from = X_CONFIG;
+ } else if (!info->LinearAddr) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid linear framebuffer address\n");
+ return FALSE;
+ }
xf86DrvMsg(pScrn->scrnIndex, from,
- "BIOS at 0x%08lx\n", info->BIOSAddr);
- }
+ "Linear framebuffer at 0x%016lx\n", info->LinearAddr);
+
+#ifndef XSERVER_LIBPCIACCESS
+ /* BIOS */
+ from = X_PROBED;
+ info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000;
+ if (dev->BiosBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "BIOS address override, using 0x%08lx instead of 0x%08lx\n",
+ dev->BiosBase,
+ info->BIOSAddr);
+ info->BIOSAddr = dev->BiosBase;
+ from = X_CONFIG;
+ }
+ if (info->BIOSAddr) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "BIOS at 0x%08lx\n", info->BIOSAddr);
+ }
#endif
- /* Read registers used to determine options */
- /* Check chip errata */
- info->ChipErrata = 0;
+ /* Read registers used to determine options */
+ /* Check chip errata */
+ info->ChipErrata = 0;
- if (info->ChipFamily == CHIP_FAMILY_R300 &&
- (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
- == RADEON_CFG_ATI_REV_A11)
+ if (info->ChipFamily == CHIP_FAMILY_R300 &&
+ (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
+ == RADEON_CFG_ATI_REV_A11)
info->ChipErrata |= CHIP_ERRATA_R300_CG;
-
- if (info->ChipFamily == CHIP_FAMILY_RV200 ||
- info->ChipFamily == CHIP_FAMILY_RS200)
+
+ if (info->ChipFamily == CHIP_FAMILY_RV200 ||
+ info->ChipFamily == CHIP_FAMILY_RS200)
info->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS;
-
- if (info->ChipFamily == CHIP_FAMILY_RV100 ||
- info->ChipFamily == CHIP_FAMILY_RS100 ||
- info->ChipFamily == CHIP_FAMILY_RS200)
+
+ if (info->ChipFamily == CHIP_FAMILY_RV100 ||
+ info->ChipFamily == CHIP_FAMILY_RS100 ||
+ info->ChipFamily == CHIP_FAMILY_RS200)
info->ChipErrata |= CHIP_ERRATA_PLL_DELAY;
+ }
#ifdef XF86DRI
/* AGP/PCI */
@@ -1985,6 +1992,9 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
int errmaj = 0, errmin = 0;
+#if defined(USE_EXA)
+ info->useEXA = TRUE;
+#endif
from = X_DEFAULT;
#if defined(USE_EXA)
#if defined(USE_XAA)
@@ -1995,6 +2005,7 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
info->useEXA = TRUE;
} else if (xf86NameCmp(optstr, "XAA") == 0) {
from = X_CONFIG;
+ info->useEXA = FALSE;
}
}
#else /* USE_XAA */
@@ -2664,6 +2675,37 @@ static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = {
RADEONCRTCResize
};
+#ifdef XF86DRM_MODE
+static Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn)
+{
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *PciInfo;
+#else
+ pciVideoPtr PciInfo;
+#endif
+ EntityInfoPtr pEnt;
+ char *busIdString;
+ int ret;
+
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ PciInfo = xf86GetPciInfoForEntity(pEnt->index);
+
+ if (!xf86LoaderCheckSymbol("DRICreatePCIBusID"))
+ return FALSE;
+
+ busIdString = DRICreatePCIBusID(PciInfo);
+ ret = drmCheckModesettingSupported(busIdString);
+ xfree(busIdString);
+ if (ret)
+ return FALSE;
+
+ return TRUE;
+}
+#else
+#define radeon_kernel_mode_enabled(x) FALSE
+#endif
+
+
Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
{
xf86CrtcConfigPtr xf86_config;
@@ -2684,6 +2726,8 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
info = RADEONPTR(pScrn);
info->MMIO = NULL;
+ info->drm_mode_setting = radeon_kernel_mode_enabled(pScrn);
+
info->IsSecondary = FALSE;
info->IsPrimary = FALSE;
@@ -2718,59 +2762,63 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
}
info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
- info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo),
- PCI_DEV_DEV(info->PciInfo),
- PCI_DEV_FUNC(info->PciInfo));
- info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & ~0xffUL;
- info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2);
- if (info->pEnt->device->IOBase) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "MMIO address override, using 0x%08lx instead of 0x%08lx\n",
- info->pEnt->device->IOBase,
- info->MMIOAddr);
- info->MMIOAddr = info->pEnt->device->IOBase;
- } else if (!info->MMIOAddr) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
- goto fail1;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MMIO registers at 0x%016lx: size %ldKB\n", info->MMIOAddr, info->MMIOSize / 1024);
- if(!RADEONMapMMIO(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Memory map the MMIO region failed\n");
- goto fail1;
- }
+ if (!info->drm_mode_setting) {
+ info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo),
+ PCI_DEV_DEV(info->PciInfo),
+ PCI_DEV_FUNC(info->PciInfo));
+ info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & ~0xffUL;
+ info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2);
+ if (info->pEnt->device->IOBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "MMIO address override, using 0x%08lx instead of 0x%08lx\n",
+ info->pEnt->device->IOBase,
+ info->MMIOAddr);
+ info->MMIOAddr = info->pEnt->device->IOBase;
+ } else if (!info->MMIOAddr) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
+ goto fail1;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MMIO registers at 0x%016lx: size %ldKB\n", info->MMIOAddr, info->MMIOSize / 1024);
+
+ if(!RADEONMapMMIO(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Memory map the MMIO region failed\n");
+ goto fail1;
+ }
+
#if !defined(__alpha__)
- if (
+ if (
#ifndef XSERVER_LIBPCIACCESS
- xf86GetPciDomain(info->PciTag) ||
+ xf86GetPciDomain(info->PciTag) ||
#endif
- !xf86IsPrimaryPci(info->PciInfo))
- RADEONPreInt10Save(pScrn, &int10_save);
+ !xf86IsPrimaryPci(info->PciInfo))
+ RADEONPreInt10Save(pScrn, &int10_save);
#else
- /* [Alpha] On the primary, the console already ran the BIOS and we're
- * going to run it again - so make sure to "fix up" the card
- * so that (1) we can read the BIOS ROM and (2) the BIOS will
- * get the memory config right.
- */
- RADEONPreInt10Save(pScrn, &int10_save);
+ /* [Alpha] On the primary, the console already ran the BIOS and we're
+ * going to run it again - so make sure to "fix up" the card
+ * so that (1) we can read the BIOS ROM and (2) the BIOS will
+ * get the memory config right.
+ */
+ RADEONPreInt10Save(pScrn, &int10_save);
#endif
-
- if (flags & PROBE_DETECT) {
- RADEONProbeDDC(pScrn, info->pEnt->index);
- RADEONPostInt10Check(pScrn, int10_save);
- if(info->MMIO) RADEONUnmapMMIO(pScrn);
- return TRUE;
- }
+
+ if (flags & PROBE_DETECT) {
+ RADEONProbeDDC(pScrn, info->pEnt->index);
+ RADEONPostInt10Check(pScrn, int10_save);
+ if(info->MMIO) RADEONUnmapMMIO(pScrn);
+ return TRUE;
+ }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "PCI bus %d card %d func %d\n",
- PCI_DEV_BUS(info->PciInfo),
- PCI_DEV_DEV(info->PciInfo),
- PCI_DEV_FUNC(info->PciInfo));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI bus %d card %d func %d\n",
+ PCI_DEV_BUS(info->PciInfo),
+ PCI_DEV_DEV(info->PciInfo),
+ PCI_DEV_FUNC(info->PciInfo));
+ }
if (xf86RegisterResources(info->pEnt->index, 0, ResExclusive))
goto fail;
@@ -2780,10 +2828,12 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
pScrn->monitor = pScrn->confScreen->monitor;
- /* Allocate an xf86CrtcConfig */
- xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
- xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
+ if (!info->drm_mode_setting) {
+ /* Allocate an xf86CrtcConfig */
+ xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
+ xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+ }
if (!RADEONPreInitVisual(pScrn))
goto fail;
@@ -2797,136 +2847,192 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
memcpy(info->Options, RADEONOptions, sizeof(RADEONOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
- /* By default, don't do VGA IOs on ppc/sparc */
+ if (!info->drm_mode_setting) {
+ /* By default, don't do VGA IOs on ppc/sparc */
#if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
- info->VGAAccess = FALSE;
+ info->VGAAccess = FALSE;
#else
- info->VGAAccess = TRUE;
+ info->VGAAccess = TRUE;
#endif
-
+
#ifdef WITH_VGAHW
- xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess);
- if (info->VGAAccess) {
- if (!xf86LoadSubModule(pScrn, "vgahw"))
- info->VGAAccess = FALSE;
- else {
- if (!vgaHWGetHWRec(pScrn))
- info->VGAAccess = FALSE;
- }
- if (!info->VGAAccess)
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed,"
- " trying to run without it\n");
- } else
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE,"
- " VGA module load skipped\n");
- if (info->VGAAccess)
- vgaHWGetIOBase(VGAHWPTR(pScrn));
+ xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess);
+ if (info->VGAAccess) {
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ info->VGAAccess = FALSE;
+ else {
+ if (!vgaHWGetHWRec(pScrn))
+ info->VGAAccess = FALSE;
+ }
+ if (!info->VGAAccess)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed,"
+ " trying to run without it\n");
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE,"
+ " VGA module load skipped\n");
+ if (info->VGAAccess)
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
#endif
-
-
+
+ }
+
if (!RADEONPreInitWeight(pScrn))
goto fail;
- info->DispPriority = 1;
- if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) {
- if (strcmp(s, "AUTO") == 0) {
- info->DispPriority = 1;
- } else if (strcmp(s, "BIOS") == 0) {
- info->DispPriority = 0;
- } else if (strcmp(s, "HIGH") == 0) {
- info->DispPriority = 2;
- } else
- info->DispPriority = 1;
- }
-
if (!RADEONPreInitChipType(pScrn))
- goto fail;
-
- if (!RADEONPreInitInt10(pScrn, &pInt10))
- goto fail;
-
- RADEONPostInt10Check(pScrn, int10_save);
-
- if (!RADEONPreInitBIOS(pScrn, pInt10))
- goto fail;
+ goto fail;
+
+ if (!info->drm_mode_setting) {
+ info->DispPriority = 1;
+ if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) {
+ if (strcmp(s, "AUTO") == 0) {
+ info->DispPriority = 1;
+ } else if (strcmp(s, "BIOS") == 0) {
+ info->DispPriority = 0;
+ } else if (strcmp(s, "HIGH") == 0) {
+ info->DispPriority = 2;
+ } else
+ info->DispPriority = 1;
+ }
+
+
+ if (!RADEONPreInitInt10(pScrn, &pInt10))
+ goto fail;
+
+ RADEONPostInt10Check(pScrn, int10_save);
+ if (!RADEONPreInitBIOS(pScrn, pInt10))
+ goto fail;
#ifdef XF86DRI
- /* PreInit DRI first of all since we need that for getting a proper
- * memory map
- */
- info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
+ /* PreInit DRI first of all since we need that for getting a proper
+ * memory map
+ */
+ info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
#endif
- if (!RADEONPreInitVRAM(pScrn))
- goto fail;
-
- RADEONPreInitColorTiling(pScrn);
-
- /* we really need an FB manager... */
- if (pScrn->display->virtualX) {
- crtc_max_X = pScrn->display->virtualX;
- crtc_max_Y = pScrn->display->virtualY;
- if (info->allowColorTiling) {
- if (crtc_max_X > info->MaxSurfaceWidth ||
- crtc_max_Y > info->MaxLines) {
- info->allowColorTiling = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Requested desktop size exceeds surface limts for tiling, ColorTiling disabled\n");
+
+ if (!RADEONPreInitVRAM(pScrn))
+ goto fail;
+
+ RADEONPreInitColorTiling(pScrn);
+
+ /* we really need an FB manager... */
+ if (pScrn->display->virtualX) {
+ crtc_max_X = pScrn->display->virtualX;
+ crtc_max_Y = pScrn->display->virtualY;
+ if (info->allowColorTiling) {
+ if (crtc_max_X > info->MaxSurfaceWidth ||
+ crtc_max_Y > info->MaxLines) {
+ info->allowColorTiling = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Requested desktop size exceeds surface limts for tiling, ColorTiling disabled\n");
+ }
}
- }
- if (crtc_max_X > 8192)
- crtc_max_X = 8192;
- if (crtc_max_Y > 8192)
- crtc_max_Y = 8192;
- } else {
- /*
- * note that these aren't really the CRTC limits, they're just
- * heuristics until we have a better memory manager.
- */
- if (pScrn->videoRam <= 16384) {
- crtc_max_X = 1600;
- crtc_max_Y = 1200;
- } else if (IS_R300_VARIANT) {
- crtc_max_X = 2560;
- crtc_max_Y = 1200;
- } else if (IS_AVIVO_VARIANT) {
- crtc_max_X = 2560;
- crtc_max_Y = 1600;
+ if (crtc_max_X > 8192)
+ crtc_max_X = 8192;
+ if (crtc_max_Y > 8192)
+ crtc_max_Y = 8192;
} else {
- crtc_max_X = 2048;
- crtc_max_Y = 1200;
+ /*
+ * note that these aren't really the CRTC limits, they're just
+ * heuristics until we have a better memory manager.
+ */
+ if (pScrn->videoRam <= 16384) {
+ crtc_max_X = 1600;
+ crtc_max_Y = 1200;
+ } else if (IS_R300_VARIANT) {
+ crtc_max_X = 2560;
+ crtc_max_Y = 1200;
+ } else if (IS_AVIVO_VARIANT) {
+ crtc_max_X = 2560;
+ crtc_max_Y = 1600;
+ } else {
+ crtc_max_X = 2048;
+ crtc_max_Y = 1200;
}
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
- crtc_max_X, crtc_max_Y);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n");
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "If you are having trouble with 3D, "
- "reduce the desktop size by adjusting the Virtual line to your xorg.conf\n");
-
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
+ crtc_max_X, crtc_max_Y);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "If you are having trouble with 3D, "
+ "reduce the desktop size by adjusting the Virtual line to your xorg.conf\n");
+
/*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/
- xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
+ xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
+
+ RADEONPreInitDDC(pScrn);
- RADEONPreInitDDC(pScrn);
+ if (!RADEONPreInitControllers(pScrn))
+ goto fail;
- if (!RADEONPreInitControllers(pScrn))
- goto fail;
+ ErrorF("before xf86InitialConfiguration\n");
+
+ if (!xf86InitialConfiguration (pScrn, FALSE))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+ goto fail;
+ }
+
+ ErrorF("after xf86InitialConfiguration\n");
+
+ } else {
+#ifdef XF86DRM_MODE
+ char *bus_id;
+ bus_id = DRICreatePCIBusID(info->PciInfo);
+ if (drmmode_pre_init(pScrn, &info->drmmode, bus_id, "radeon", pScrn->bitsPerPixel / 8) == FALSE) {
+ xfree(bus_id);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
+ goto fail;
+ }
- ErrorF("before xf86InitialConfiguration\n");
+ info->drmmode.create_new_fb = radeon_create_new_fb;
+ info->drmFD = info->drmmode.fd;
+ xfree(bus_id);
+
+ {
+ struct drm_radeon_gem_info mminfo;
+
+ if (!drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
+ {
+ info->mm.vram_start = mminfo.vram_start;
+ info->mm.vram_size = mminfo.vram_visible;
+ info->mm.gart_start = mminfo.gart_start;
+ info->mm.gart_size = mminfo.gart_size;
+ ErrorF("initing %llx %llx %llx %llx %llx\n", mminfo.gart_start,
+ mminfo.gart_size, mminfo.vram_start, mminfo.vram_size, mminfo.vram_visible);
+ }
+ {
+ drmRadeonGetParam gp;
+ int value;
- if (!xf86InitialConfiguration (pScrn, FALSE))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
- goto fail;
- }
+ memset(&gp, 0, sizeof(gp));
+ gp.param = RADEON_PARAM_FB_LOCATION;
+ gp.value = &value;
- ErrorF("after xf86InitialConfiguration\n");
+ if (drmCommandWriteRead(info->drmFD, DRM_RADEON_GETPARAM, &gp,
+ sizeof(gp)) < 0) {
+ goto fail;
+ }
+ if (info->ChipFamily >= CHIP_FAMILY_R600)
+ info->fbLocation = (value & 0xffff) << 24;
+ else
+ info->fbLocation = (value & 0xffff) << 16;
+ }
+ }
+ info->useEXA = TRUE;
+ info->drm_mm = TRUE;
+ info->directRenderingEnabled = TRUE;
+ info->new_cs = TRUE;
+ // info->directRenderingDisabled = FALSE;
+#endif
+ }
RADEONSetPitch(pScrn);
- /* Set display resolution */
- xf86SetDpi(pScrn, 0, 0);
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
/* Get ScreenInit function */
if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
@@ -2941,10 +3047,12 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
if (!RADEONPreInitXv(pScrn)) goto fail;
}
- if (!xf86RandR12PreInit (pScrn))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
- goto fail;
+ if (!info->drm_mode_setting) {
+ if (!xf86RandR12PreInit (pScrn))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
+ goto fail;
+ }
}
if (pScrn->modes == NULL) {
@@ -3185,7 +3293,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
int subPixelOrder = SubPixelUnknown;
char* s;
#endif
-
+ void *front_ptr;
info->accelOn = FALSE;
#ifdef USE_XAA
@@ -3205,52 +3313,55 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
"RADEONScreenInit %lx %ld\n",
pScrn->memPhysBase, pScrn->fbOffset);
#endif
- if (!RADEONMapMem(pScrn)) return FALSE;
+
+ if (!info->drm_mode_setting) {
+ if (!RADEONMapMem(pScrn)) return FALSE;
#ifdef XF86DRI
- info->fbX = 0;
- info->fbY = 0;
+ info->fbX = 0;
+ info->fbY = 0;
#endif
+
+ info->PaletteSavedOnVT = FALSE;
- info->PaletteSavedOnVT = FALSE;
+ info->crtc_on = FALSE;
+ info->crtc2_on = FALSE;
- info->crtc_on = FALSE;
- info->crtc2_on = FALSE;
+ RADEONSave(pScrn);
- RADEONSave(pScrn);
+ /* set initial bios scratch reg state */
+ RADEONInitBIOSRegisters(pScrn);
- /* set initial bios scratch reg state */
- RADEONInitBIOSRegisters(pScrn);
+ /* blank the outputs/crtcs */
+ RADEONBlank(pScrn);
- /* blank the outputs/crtcs */
- RADEONBlank(pScrn);
+ if (info->IsMobility && !IS_AVIVO_VARIANT) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+ RADEONSetDynamicClock(pScrn, 1);
+ } else {
+ RADEONSetDynamicClock(pScrn, 0);
+ }
+ } else if (IS_AVIVO_VARIANT) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+ atombios_static_pwrmgt_setup(pScrn, 1);
+ atombios_dyn_clk_setup(pScrn, 1);
+ }
+ }
+
+ if (IS_R300_VARIANT || IS_RV100_VARIANT)
+ RADEONForceSomeClocks(pScrn);
- if (info->IsMobility && !IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- RADEONSetDynamicClock(pScrn, 1);
- } else {
- RADEONSetDynamicClock(pScrn, 0);
+ if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Color tiling not supported with virtual x resolutions larger than %d, disabling\n",
+ info->MaxSurfaceWidth);
+ info->allowColorTiling = FALSE;
}
- } else if (IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- atombios_static_pwrmgt_setup(pScrn, 1);
- atombios_dyn_clk_setup(pScrn, 1);
+ if (info->allowColorTiling) {
+ info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
}
+
}
-
- if (IS_R300_VARIANT || IS_RV100_VARIANT)
- RADEONForceSomeClocks(pScrn);
-
- if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Color tiling not supported with virtual x resolutions larger than %d, disabling\n",
- info->MaxSurfaceWidth);
- info->allowColorTiling = FALSE;
- }
- if (info->allowColorTiling) {
- info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
- }
-
/* Visual setup */
miClearVisualTypes();
if (!miSetVisualTypes(pScrn->depth,
@@ -3284,19 +3395,21 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
hasDRI = info->directRenderingEnabled;
#endif /* XF86DRI */
- /* Initialize the memory map, this basically calculates the values
- * we'll use later on for MC_FB_LOCATION & MC_AGP_LOCATION
- */
- RADEONInitMemoryMap(pScrn);
+ if (!info->drm_mode_setting) {
+ /* Initialize the memory map, this basically calculates the values
+ * we'll use later on for MC_FB_LOCATION & MC_AGP_LOCATION
+ */
+ RADEONInitMemoryMap(pScrn);
- /* empty the surfaces */
- {
- unsigned char *RADEONMMIO = info->MMIO;
- unsigned int j;
- for (j = 0; j < 8; j++) {
- OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
- OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
- OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
+ /* empty the surfaces */
+ {
+ unsigned char *RADEONMMIO = info->MMIO;
+ unsigned int j;
+ for (j = 0; j < 8; j++) {
+ OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
+ OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
+ OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
+ }
}
}
@@ -3341,6 +3454,9 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
from = X_CONFIG;
}
+ if (info->drm_mm)
+ info->accelDFS = FALSE;
+
/* Reserve approx. half of offscreen memory for local textures by
* default, can be overridden with Option "FBTexPercent".
* Round down to a whole number of texture regions.
@@ -3407,7 +3523,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
info->CurrentLayout.pixel_bytes);
int maxy = info->FbMapSize / width_bytes;
- if (maxy <= pScrn->virtualY * 3) {
+ if (maxy <= pScrn->virtualY * 3 && !info->drm_mm) {
xf86DrvMsg(scrnIndex, X_ERROR,
"Static buffer allocation failed. Disabling DRI.\n");
xf86DrvMsg(scrnIndex, X_ERROR,
@@ -3421,15 +3537,39 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
}
}
- /* Tell DRI about new memory map */
- if (info->directRenderingEnabled && info->newMemoryMap) {
- if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
+ front_ptr = info->FB;
+ if (info->drm_mm) {
+ if (info->directRenderingEnabled && info->newMemoryMap) {
+ if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"[drm] failed to enable new memory map\n");
RADEONDRICloseScreen(pScreen);
info->directRenderingEnabled = FALSE;
+ }
+ }
+ info->bufmgr = radeon_bufmgr_gem_init(info->drmFD);
+ drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
+ //radeon_bufmgr_gem_enable_reuse(info->bufmgr);
+ radeon_setup_kernel_mem(pScreen);
+ front_ptr = info->mm.front_buffer->map;
+ pScrn->fbOffset = info->mm.front_buffer->offset;
+ info->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64)
+ << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10));
+ } else {
+
+ /* Tell DRI about new memory map */
+ if (info->directRenderingEnabled && info->newMemoryMap) {
+ if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[drm] failed to enable new memory map\n");
+ RADEONDRICloseScreen(pScreen);
+ info->directRenderingEnabled = FALSE;
+ }
}
}
+
+ RADEONDRIDoMappings(pScreen);
+
#endif
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"Initializing fb layer\n");
@@ -3453,7 +3593,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
if (info->r600_shadow_fb == FALSE) {
/* Init fb layer */
- if (!fbScreenInit(pScreen, info->FB,
+ if (!fbScreenInit(pScreen, front_ptr,
pScrn->virtualX, pScrn->virtualY,
pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
pScrn->bitsPerPixel))
@@ -3508,7 +3648,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
/* DRI finalisation */
#ifdef XF86DRI
- if (info->directRenderingEnabled && info->cardType==CARD_PCIE &&
+ if (!info->drm_mm && info->directRenderingEnabled && info->cardType==CARD_PCIE &&
info->pKernelDRMVersion->version_minor >= 19)
{
if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_PCIGART_LOCATION, info->pciGartOffset) < 0)
@@ -3527,15 +3667,21 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen);
}
if (info->directRenderingEnabled) {
+
+ if (info->drm_mm)
+ radeon_update_dri_buffers(pScrn);
+
/* DRI final init might have changed the memory map, we need to adjust
* our local image to make sure we restore them properly on mode
* changes or VT switches
*/
- RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
+ if (!info->drm_mode_setting) {
+ RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
- if ((info->DispPriority == 1) && (info->cardType==CARD_AGP)) {
- /* we need to re-calculate bandwidth because of AGPMode difference. */
- RADEONInitDispBandwidth(pScrn);
+ if ((info->DispPriority == 1) && (info->cardType==CARD_AGP)) {
+ /* we need to re-calculate bandwidth because of AGPMode difference. */
+ RADEONInitDispBandwidth(pScrn);
+ }
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
@@ -5355,6 +5501,11 @@ void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
xf86OutputPtr output = config->output[config->compat_output];
xf86CrtcPtr crtc = output->crtc;
+ if (info->drm_mode_setting) {
+ drmmode_adjust_frame(pScrn, &info->drmmode, x, y, flags);
+ return;
+ }
+
#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
#endif
@@ -5390,67 +5541,76 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONEnterVT\n");
- if (!radeon_card_posted(pScrn)) { /* Softboot V_BIOS */
- if (info->IsAtomBios) {
- rhdAtomASICInit(info->atomBIOS);
- } else {
- xf86Int10InfoPtr pInt;
-
- pInt = xf86InitInt10 (info->pEnt->index);
- if (pInt) {
- pInt->num = 0xe6;
- xf86ExecX86int10 (pInt);
- xf86FreeInt10 (pInt);
+ if (!info->drm_mode_setting) {
+ if (!radeon_card_posted(pScrn)) { /* Softboot V_BIOS */
+ if (info->IsAtomBios) {
+ rhdAtomASICInit(info->atomBIOS);
} else {
- RADEONGetBIOSInitTableOffsets(pScrn);
- RADEONPostCardFromBIOSTables(pScrn);
+ xf86Int10InfoPtr pInt;
+ pInt = xf86InitInt10 (info->pEnt->index);
+ if (pInt) {
+ pInt->num = 0xe6;
+ xf86ExecX86int10 (pInt);
+ xf86FreeInt10 (pInt);
+ } else {
+ RADEONGetBIOSInitTableOffsets(pScrn);
+ RADEONPostCardFromBIOSTables(pScrn);
+ }
}
}
- }
-
- /* Makes sure the engine is idle before doing anything */
- RADEONWaitForIdleMMIO(pScrn);
+ /* Makes sure the engine is idle before doing anything */
+ RADEONWaitForIdleMMIO(pScrn);
- if (info->IsMobility && !IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- RADEONSetDynamicClock(pScrn, 1);
- } else {
- RADEONSetDynamicClock(pScrn, 0);
- }
- } else if (IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
- atombios_static_pwrmgt_setup(pScrn, 1);
- atombios_dyn_clk_setup(pScrn, 1);
+ if (info->IsMobility && !IS_AVIVO_VARIANT) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+ RADEONSetDynamicClock(pScrn, 1);
+ } else {
+ RADEONSetDynamicClock(pScrn, 0);
+ }
+ } else if (IS_AVIVO_VARIANT) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+ atombios_static_pwrmgt_setup(pScrn, 1);
+ atombios_dyn_clk_setup(pScrn, 1);
+ }
}
+
+ if (IS_R300_VARIANT || IS_RV100_VARIANT)
+ RADEONForceSomeClocks(pScrn);
+
}
- if (IS_R300_VARIANT || IS_RV100_VARIANT)
- RADEONForceSomeClocks(pScrn);
+ if (info->drm_mm)
+ radeon_bind_all_memory(pScrn);
- for (i = 0; i < config->num_crtc; i++)
- radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
+ radeon_update_dri_buffers(pScrn);
pScrn->vtSema = TRUE;
+ if (!info->drm_mode_setting)
+ for (i = 0; i < config->num_crtc; i++)
+ radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
+
if (!xf86SetDesiredModes(pScrn))
return FALSE;
- if (info->ChipFamily < CHIP_FAMILY_R600)
- RADEONRestoreSurfaces(pScrn, info->ModeReg);
+ if (!info->drm_mode_setting) {
+ if (info->ChipFamily < CHIP_FAMILY_R600)
+ RADEONRestoreSurfaces(pScrn, info->ModeReg);
#ifdef XF86DRI
- if (info->directRenderingEnabled) {
- if (info->cardType == CARD_PCIE &&
- info->pKernelDRMVersion->version_minor >= 19 &&
- info->FbSecureSize) {
- /* we need to backup the PCIE GART TABLE from fb memory */
- memcpy(info->FB + info->pciGartOffset, info->pciGartBackup, info->pciGartSize);
- }
-
- /* get the DRI back into shape after resume */
- RADEONDRISetVBlankInterrupt (pScrn, TRUE);
- RADEONDRIResume(pScrn->pScreen);
- RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
-
+ if (info->directRenderingEnabled) {
+ if (info->cardType == CARD_PCIE &&
+ info->pKernelDRMVersion->version_minor >= 19 &&
+ info->FbSecureSize) {
+ /* we need to backup the PCIE GART TABLE from fb memory */
+ memcpy(info->FB + info->pciGartOffset, info->pciGartBackup, info->pciGartSize);
+ }
+
+ /* get the DRI back into shape after resume */
+ RADEONDRISetVBlankInterrupt (pScrn, TRUE);
+ RADEONDRIResume(pScrn->pScreen);
+ RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
+
+ }
}
#endif
/* this will get XVideo going again, but only if XVideo was initialised
@@ -5462,7 +5622,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
RADEONEngineRestore(pScrn);
#ifdef XF86DRI
- if (info->directRenderingEnabled) {
+ if (info->directRenderingEnabled && !info->drm_mode_setting) {
RADEONCP_START(pScrn, info);
DRIUnlock(pScrn->pScreen);
}
@@ -5485,24 +5645,26 @@ void RADEONLeaveVT(int scrnIndex, int flags)
"RADEONLeaveVT\n");
#ifdef XF86DRI
if (RADEONPTR(pScrn)->directRenderingInited) {
-
- RADEONDRISetVBlankInterrupt (pScrn, FALSE);
- DRILock(pScrn->pScreen, 0);
- RADEONCP_STOP(pScrn, info);
-
- if (info->cardType == CARD_PCIE &&
- info->pKernelDRMVersion->version_minor >= 19 &&
- info->FbSecureSize) {
- /* we need to backup the PCIE GART TABLE from fb memory */
- memcpy(info->pciGartBackup, (info->FB + info->pciGartOffset), info->pciGartSize);
- }
+
+ if (!info->drm_mode_setting) {
+ RADEONDRISetVBlankInterrupt (pScrn, FALSE);
+ DRILock(pScrn->pScreen, 0);
+ RADEONCP_STOP(pScrn, info);
+
+ if (info->cardType == CARD_PCIE &&
+ info->pKernelDRMVersion->version_minor >= 19 &&
+ info->FbSecureSize) {
+ /* we need to backup the PCIE GART TABLE from fb memory */
+ memcpy(info->pciGartBackup, (info->FB + info->pciGartOffset), info->pciGartSize);
+ }
+ }
/* Make sure 3D clients will re-upload textures to video RAM */
if (info->textureSize) {
RADEONSAREAPrivPtr pSAREAPriv =
(RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
- drmTextureRegionPtr list = pSAREAPriv->texList[0];
- int age = ++pSAREAPriv->texAge[0];
+ drmTextureRegionPtr list = pSAREAPriv->tex_list[0];
+ int age = ++pSAREAPriv->tex_age[0];
i = 0;
@@ -5531,10 +5693,15 @@ void RADEONLeaveVT(int scrnIndex, int flags)
xf86_hide_cursors (pScrn);
- RADEONRestore(pScrn);
+ if (info->drm_mm)
+ radeon_unbind_all_memory(pScrn);
- for (i = 0; i < config->num_crtc; i++)
- radeon_crtc_modeset_ioctl(config->crtc[i], FALSE);
+ if (!info->drm_mode_setting) {
+ RADEONRestore(pScrn);
+
+ for (i = 0; i < config->num_crtc; i++)
+ radeon_crtc_modeset_ioctl(config->crtc[i], FALSE);
+ }
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"Ok, leaving now...\n");
@@ -5579,7 +5746,8 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
#endif /* USE_XAA */
if (pScrn->vtSema) {
- RADEONRestore(pScrn);
+ if (!info->drm_mode_setting)
+ RADEONRestore(pScrn);
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -5614,6 +5782,12 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
info->DGAModes = NULL;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"Unmapping memory\n");
+
+ if (info->drm_mm) {
+ radeon_unbind_all_memory(pScrn);
+ radeon_free_all_memory(pScrn);
+ }
+
RADEONUnmapMem(pScrn);
pScrn->vtSema = FALSE;
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 02fd4fc..555ae16 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -47,6 +47,13 @@
#include "xf86.h"
+#define RADEON_PIXMAP_IS_FRONTBUFFER 1
+
+/* quick hacks lolz */
+struct radeon_exa_pixmap_priv {
+ dri_bo *bo;
+ int flags;
+};
/***********************************************************************/
#define RINFO_FROM_SCREEN(pScr) ScrnInfoPtr pScrn = xf86Screens[pScr->myNum]; \
@@ -184,14 +191,26 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
uint32_t pitch, offset;
int bpp;
+ struct radeon_exa_pixmap_priv *driver_priv;
bpp = pPix->drawable.bitsPerPixel;
if (bpp == 24)
bpp = 8;
- offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+ /* validate the pixmap somewhere */
+ if (info->new_cs)
+ offset = 0;
+ else {
+ if (driver_priv)
+ offset = driver_priv->bo->offset;
+ else
+ offset = exaGetPixmapOffset(pPix);
+
+ offset += info->fbLocation + pScrn->fbOffset;
+ }
pitch = exaGetPixmapPitch(pPix);
-
return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
}
@@ -199,6 +218,8 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
static unsigned long swapper_surfaces[3];
+#endif
+
static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
@@ -206,7 +227,30 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
uint32_t offset = exaGetPixmapOffset(pPix);
int bpp, soff;
uint32_t size, flags;
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (driver_priv) {
+
+ if (driver_priv->bo) {
+ int ret;
+
+ RADEONCPFlushIndirect(pScrn, 0);
+
+ //radeon_bufmgr_gem_wait_rendering(driver_priv->bo);
+
+ /* flush IB */
+ ret = dri_bo_map(driver_priv->bo, 1);
+ if (ret) {
+ FatalError("failed to map pixmap %d\n", ret);
+ return FALSE;
+ }
+
+ pPix->devPrivate.ptr = driver_priv->bo->virtual;
+ }
+ }
+#if X_BYTE_ORDER == X_BIG_ENDIAN
/* Front buffer is always set with proper swappers */
if (offset == 0)
return TRUE;
@@ -262,6 +306,7 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, offset);
OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, offset + size - 1);
swapper_surfaces[index] = offset;
+#endif
return TRUE;
}
@@ -271,7 +316,16 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
unsigned char *RADEONMMIO = info->MMIO;
uint32_t offset = exaGetPixmapOffset(pPix);
int soff;
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+ if (driver_priv) {
+ dri_bo_unmap(driver_priv->bo);
+ }
+ pPix->devPrivate.ptr = NULL;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
/* Front buffer is always set with proper swappers */
if (offset == 0)
return;
@@ -294,13 +348,100 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, 0);
OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, 0);
swapper_surfaces[index] = 0;
+#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
}
-#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
+void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *new_priv;
+
+ new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv));
+ if (!new_priv)
+ return NULL;
+
+ if (size == 0)
+ return new_priv;
+
+ new_priv->bo = dri_bo_alloc(info->bufmgr, "exa pixmap", size,
+ align);
+ if (!new_priv->bo) {
+ xfree(new_priv);
+ ErrorF("Failed to alloc memory\n");
+ return NULL;
+ }
+
+ return new_priv;
+
+}
+
+static void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *driver_priv = driverPriv;
+ int ret;
+
+ dri_bo_unreference(driver_priv->bo);
+ xfree(driverPriv);
+}
+
+static Bool RADEONEXAModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPixmap);
+ if (!driver_priv)
+ return FALSE;
+
+
+ if (info->drm_mode_setting && drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)){
+ dri_bo_unmap(driver_priv->bo);
+ dri_bo_reference(driver_priv->bo);
+ miModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, NULL);
+
+ return TRUE;
+ }
+
+ if (pPixData == info->mm.front_buffer->map) {
+ driver_priv->flags |= RADEON_PIXMAP_IS_FRONTBUFFER;
+
+ if (info->new_cs)
+ driver_priv->bo = radeon_bo_gem_create_from_name(info->bufmgr, "front",
+ radeon_name_buffer(pScrn, info->mm.front_buffer));
+ else
+ driver_priv->bo = radeon_bufmgr_exa_create_bo(info->bufmgr, info->mm.front_buffer);
+
+ miModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix)
+{
+ struct radeon_exa_pixmap_priv *driver_priv;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+ if (!driver_priv)
+ return FALSE;
+ if (driver_priv->bo)
+ return TRUE;
+ return FALSE;
+}
#define RADEON_SWITCH_TO_2D() \
do { \
- uint32_t wait_until = 0; \
+ uint32_t wait_until = 0; \
BEGIN_ACCEL(1); \
switch (info->engineMode) { \
case EXA_ENGINEMODE_UNKNOWN: \
@@ -317,7 +458,7 @@ do { \
#define RADEON_SWITCH_TO_3D() \
do { \
- uint32_t wait_until = 0; \
+ uint32_t wait_until = 0; \
BEGIN_ACCEL(1); \
switch (info->engineMode) { \
case EXA_ENGINEMODE_UNKNOWN: \
@@ -341,6 +482,7 @@ do { \
#define BEGIN_ACCEL(n) RADEONWaitForFifo(pScrn, (n))
#define OUT_ACCEL_REG(reg, val) OUTREG(reg, val)
#define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
+#define OUT_RELOC(x, read, write) do {} while(0)
#define FINISH_ACCEL()
#ifdef RENDER
@@ -353,6 +495,7 @@ do { \
#undef BEGIN_ACCEL
#undef OUT_ACCEL_REG
#undef FINISH_ACCEL
+#undef OUT_RELOC
#ifdef XF86DRI
@@ -363,6 +506,7 @@ do { \
#define BEGIN_ACCEL(n) BEGIN_RING(2*(n))
#define OUT_ACCEL_REG(reg, val) OUT_RING_REG(reg, val)
#define FINISH_ACCEL() ADVANCE_RING()
+#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
@@ -373,6 +517,8 @@ do { \
#endif /* XF86DRI */
+
+
/*
* Once screen->off_screen_base is set, this function
* allocates the remaining memory appropriately
@@ -394,125 +540,124 @@ Bool RADEONSetupMemEXA (ScreenPtr pScreen)
if (info->exa == NULL)
return FALSE;
- /* Need to adjust screen size for 16 line tiles, and then make it align to.
- * the buffer alignment requirement.
- */
- if (info->allowColorTiling)
- screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * byteStride;
- else
- screen_size = pScrn->virtualY * byteStride;
-
- info->exa->memoryBase = info->FB;
- info->exa->memorySize = info->FbMapSize - info->FbSecureSize;
- info->exa->offScreenBase = screen_size;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocating from a screen of %ld kb\n",
- info->exa->memorySize / 1024);
-
-
- /* Reserve static area for hardware cursor */
- if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
- int cursor_size = 64 * 4 * 64;
- int align = IS_AVIVO_VARIANT ? 4096 : 256;
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++) {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-
- radeon_crtc->cursor_offset =
- RADEON_ALIGN(info->exa->offScreenBase, align);
- info->exa->offScreenBase = radeon_crtc->cursor_offset + cursor_size;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use %d kb for hardware cursor %d at offset 0x%08x\n",
- (cursor_size * xf86_config->num_crtc) / 1024,
- c,
- (unsigned int)radeon_crtc->cursor_offset);
- }
-
-
- }
-
-#if defined(XF86DRI)
- if (info->directRenderingEnabled) {
- int depthCpp = (info->depthBits - 8) / 4, l, next, depth_size;
-
- info->frontOffset = 0;
- info->frontPitch = pScrn->displayWidth;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use %d kb for front buffer at offset 0x%08x\n",
- screen_size / 1024, info->frontOffset);
- RADEONDRIAllocatePCIGARTTable(pScreen);
-
- if (info->cardType==CARD_PCIE)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use %d kb for PCI GART at offset 0x%08x\n",
- info->pciGartSize / 1024,
- (int)info->pciGartOffset);
-
- /* Reserve a static area for the back buffer the same size as the
- * visible screen. XXX: This would be better initialized in ati_dri.c
- * when GLX is set up, but the offscreen memory manager's allocations
- * don't last through VT switches, while the kernel's understanding of
- * offscreen locations does.
- */
- info->backPitch = pScrn->displayWidth;
- next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
- if (!info->noBackBuffer &&
- next + screen_size <= info->exa->memorySize)
- {
- info->backOffset = next;
- info->exa->offScreenBase = next + screen_size;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use %d kb for back buffer at offset 0x%08x\n",
- screen_size / 1024, info->backOffset);
- }
-
- /* Reserve the static depth buffer, and adjust pitch and height to
- * handle tiling.
+ if (info->drm_mm == FALSE) {
+ /* Need to adjust screen size for 16 line tiles, and then make it align to.
+ * the buffer alignment requirement.
*/
- info->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
- depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->depthPitch * depthCpp;
- next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
- if (next + depth_size <= info->exa->memorySize)
- {
- info->depthOffset = next;
- info->exa->offScreenBase = next + depth_size;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use %d kb for depth buffer at offset 0x%08x\n",
- depth_size / 1024, info->depthOffset);
+ if (info->allowColorTiling)
+ screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * byteStride;
+ else
+ screen_size = pScrn->virtualY * byteStride;
+
+ info->exa->memoryBase = info->FB;
+ info->exa->memorySize = info->FbMapSize - info->FbSecureSize;
+ info->exa->offScreenBase = screen_size;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocating from a screen of %ld kb\n",
+ info->exa->memorySize / 1024);
+
+
+ /* Reserve static area for hardware cursor */
+ if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
+ int cursor_size = 64 * 4 * 64;
+ int align = IS_AVIVO_VARIANT ? 4096 : 256;
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+ radeon_crtc->cursor_offset =
+ RADEON_ALIGN(info->exa->offScreenBase, align);
+ info->exa->offScreenBase = radeon_crtc->cursor_offset + cursor_size;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use %d kb for hardware cursor %d at offset 0x%08x\n",
+ (cursor_size * xf86_config->num_crtc) / 1024,
+ c,
+ (unsigned int)radeon_crtc->cursor_offset);
+ }
}
- info->textureSize *= (info->exa->memorySize -
- info->exa->offScreenBase) / 100;
-
- l = RADEONLog2(info->textureSize / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY)
- l = RADEON_LOG_TEX_GRANULARITY;
- info->textureSize = (info->textureSize >> l) << l;
- if (info->textureSize >= 512 * 1024) {
- info->textureOffset = info->exa->offScreenBase;
- info->exa->offScreenBase += info->textureSize;
+#if defined(XF86DRI)
+ if (info->directRenderingEnabled) {
+ int depthCpp = (info->depthBits - 8) / 4, l, next, depth_size;
+
+ info->frontOffset = 0;
+ info->frontPitch = pScrn->displayWidth;
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use %d kb for textures at offset 0x%08x\n",
- info->textureSize / 1024, info->textureOffset);
- } else {
- /* Minimum texture size is for 2 256x256x32bpp textures */
- info->textureSize = 0;
- }
- } else
+ "Will use %d kb for front buffer at offset 0x%08x\n",
+ screen_size / 1024, info->frontOffset);
+ RADEONDRIAllocatePCIGARTTable(pScreen);
+
+ if (info->cardType==CARD_PCIE)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use %d kb for PCI GART at offset 0x%08x\n",
+ info->pciGartSize / 1024,
+ (int)info->pciGartOffset);
+
+ /* Reserve a static area for the back buffer the same size as the
+ * visible screen. XXX: This would be better initialized in ati_dri.c
+ * when GLX is set up, but the offscreen memory manager's allocations
+ * don't last through VT switches, while the kernel's understanding of
+ * offscreen locations does.
+ */
+ info->backPitch = pScrn->displayWidth;
+ next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
+ if (!info->noBackBuffer &&
+ next + screen_size <= info->exa->memorySize)
+ {
+ info->backOffset = next;
+ info->exa->offScreenBase = next + screen_size;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use %d kb for back buffer at offset 0x%08x\n",
+ screen_size / 1024, info->backOffset);
+ }
+
+ /* Reserve the static depth buffer, and adjust pitch and height to
+ * handle tiling.
+ */
+ info->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
+ depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->depthPitch * depthCpp;
+ next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
+ if (next + depth_size <= info->exa->memorySize)
+ {
+ info->depthOffset = next;
+ info->exa->offScreenBase = next + depth_size;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use %d kb for depth buffer at offset 0x%08x\n",
+ depth_size / 1024, info->depthOffset);
+ }
+
+ info->textureSize *= (info->exa->memorySize -
+ info->exa->offScreenBase) / 100;
+
+ l = RADEONLog2(info->textureSize / RADEON_NR_TEX_REGIONS);
+ if (l < RADEON_LOG_TEX_GRANULARITY)
+ l = RADEON_LOG_TEX_GRANULARITY;
+ info->textureSize = (info->textureSize >> l) << l;
+ if (info->textureSize >= 512 * 1024) {
+ info->textureOffset = info->exa->offScreenBase;
+ info->exa->offScreenBase += info->textureSize;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use %d kb for textures at offset 0x%08x\n",
+ info->textureSize / 1024, info->textureOffset);
+ } else {
+ /* Minimum texture size is for 2 256x256x32bpp textures */
+ info->textureSize = 0;
+ }
+ } else
#endif /* XF86DRI */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Will use %d kb for front buffer at offset 0x%08x\n",
screen_size / 1024, 0);
-
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Will use %ld kb for X Server offscreen at offset 0x%08lx\n",
(info->exa->memorySize - info->exa->offScreenBase) /
1024, info->exa->offScreenBase);
-
+ }
return TRUE;
}
@@ -525,10 +670,21 @@ extern void ExaOffscreenMarkUsed(PixmapPtr);
unsigned long long
RADEONTexOffsetStart(PixmapPtr pPix)
{
+ struct radeon_exa_pixmap_priv *driver_priv;
+ uint32_t offset;
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+ if (driver_priv) {
+ offset = driver_priv->bo->offset;
+
+ } else {
+ offset = exaGetPixmapOffset(pPix);
+ offset += RADEONPTR(xf86Screens[pPix->drawable.pScreen->myNum])->fbLocation;
+ }
exaMoveInPixmap(pPix);
ExaOffscreenMarkUsed(pPix);
+
- return RADEONPTR(xf86Screens[pPix->drawable.pScreen->myNum])->fbLocation +
- exaGetPixmapOffset(pPix);
+ return offset;
}
#endif
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 56de23e..628d2c7 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -74,21 +74,69 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
+ if (info->new_cs)
+ return;
+
TRACE;
if (info->exaMarkerSynced != marker) {
- FUNC_NAME(RADEONWaitForIdle)(pScrn);
+ FUNC_NAME(RADEONWaitForIdle)(pScrn);
info->exaMarkerSynced = marker;
}
RADEONPTR(pScrn)->engineMode = EXA_ENGINEMODE_UNKNOWN;
}
+static void FUNC_NAME(Emit2DState)(ScrnInfoPtr pScrn, int op)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ uint32_t qwords;
+ int has_src;
+ ACCEL_PREAMBLE();
+
+ /* don't emit if no operation in progress */
+ if (info->state_2d.op == 0 && op == 0)
+ return;
+
+ has_src = info->state_2d.src_pitch_offset || (info->new_cs && info->state_2d.src_bo);
+
+ qwords = info->new_cs ? 11 : 9;
+ qwords += (has_src ? (info->new_cs ? 3 : 1) : 0);
+
+ BEGIN_ACCEL(qwords);
+ OUT_ACCEL_REG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
+ OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
+ OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr);
+ OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, info->state_2d.dp_write_mask);
+ OUT_ACCEL_REG(RADEON_DP_CNTL, info->state_2d.dp_cntl);
+
+ OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
+ if (info->new_cs)
+ OUT_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+
+ if (has_src) {
+ OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
+ if (info->new_cs)
+ OUT_RELOC(info->state_2d.src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
+
+ }
+ FINISH_ACCEL();
+
+ if (op)
+ info->state_2d.op = op;
+ if (info->new_cs)
+ info->reemit_current2d = FUNC_NAME(Emit2DState);
+}
+
static Bool
FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
uint32_t datatype, dst_pitch_offset;
+ struct radeon_exa_pixmap_priv *driver_priv;
ACCEL_PREAMBLE();
TRACE;
@@ -97,25 +145,35 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
RADEON_FALLBACK(("24bpp unsupported\n"));
if (!RADEONGetDatatypeBpp(pPix->drawable.bitsPerPixel, &datatype))
RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n"));
+
if (!RADEONGetPixmapOffsetPitch(pPix, &dst_pitch_offset))
- RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n"));
+ RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n"));
RADEON_SWITCH_TO_2D();
- BEGIN_ACCEL(5);
- OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_SOLID_COLOR |
- (datatype << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP[alu].pattern |
- RADEON_GMC_CLR_CMP_CNTL_DIS);
- OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg);
- OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, pm);
- OUT_ACCEL_REG(RADEON_DP_CNTL,
- (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
- OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
- FINISH_ACCEL();
+ info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX |
+ RADEON_DEFAULT_SC_BOTTOM_MAX);
+ info->state_2d.dp_brush_bkgd_clr = 0x00000000;
+ info->state_2d.dp_src_frgd_clr = 0xffffffff;
+ info->state_2d.dp_src_bkgd_clr = 0x00000000;
+ info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_SOLID_COLOR |
+ (datatype << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP[alu].pattern |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+ info->state_2d.dp_brush_frgd_clr = fg;
+ info->state_2d.dp_cntl = (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM);
+ info->state_2d.dp_write_mask = pm;
+ info->state_2d.dst_pitch_offset = dst_pitch_offset;
+ info->state_2d.src_pitch_offset = 0;
+ info->state_2d.src_bo = NULL;
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (driver_priv)
+ info->state_2d.dst_bo = driver_priv->bo;
+
+ FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID);
return TRUE;
}
@@ -148,8 +206,10 @@ FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPix)
OUT_ACCEL_REG(RADEON_WAIT_UNTIL,
RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE);
FINISH_ACCEL();
+ info->state_2d.op = 0;
}
+
void
FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
uint32_t dst_pitch_offset, uint32_t datatype, int rop,
@@ -160,23 +220,28 @@ FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
RADEON_SWITCH_TO_2D();
- BEGIN_ACCEL(5);
- OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (datatype << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP[rop].rop |
- RADEON_DP_SRC_SOURCE_MEMORY |
- RADEON_GMC_CLR_CMP_CNTL_DIS);
- OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask);
- OUT_ACCEL_REG(RADEON_DP_CNTL,
- ((info->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
- (info->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
- OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
- OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
- FINISH_ACCEL();
+ /* setup 2D state */
+ info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (datatype << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP[rop].rop |
+ RADEON_DP_SRC_SOURCE_MEMORY |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+ info->state_2d.dp_cntl = ((info->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
+ (info->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0));
+ info->state_2d.dp_brush_frgd_clr = 0xffffffff;
+ info->state_2d.dp_brush_bkgd_clr = 0x00000000;
+ info->state_2d.dp_src_frgd_clr = 0xffffffff;
+ info->state_2d.dp_src_bkgd_clr = 0x00000000;
+ info->state_2d.dp_write_mask = planemask;
+ info->state_2d.dst_pitch_offset = dst_pitch_offset;
+ info->state_2d.src_pitch_offset = src_pitch_offset;
+ info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX
+ | RADEON_DEFAULT_SC_BOTTOM_MAX);
+
+ FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_COPY);
}
static Bool
@@ -187,7 +252,7 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
{
RINFO_FROM_SCREEN(pDst->drawable.pScreen);
uint32_t datatype, src_pitch_offset, dst_pitch_offset;
-
+ struct radeon_exa_pixmap_priv *driver_priv;
TRACE;
info->xdir = xdir;
@@ -197,10 +262,19 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
RADEON_FALLBACK(("24bpp unsupported"));
if (!RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype))
RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n"));
+
if (!RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset))
- RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch source failed\n"));
+ RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch source failed\n"));
if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset))
- RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n"));
+ RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n"));
+
+ driver_priv = exaGetPixmapDriverPrivate(pSrc);
+ if (driver_priv)
+ info->state_2d.src_bo = driver_priv->bo;
+
+ driver_priv = exaGetPixmapDriverPrivate(pDst);
+ if (driver_priv)
+ info->state_2d.dst_bo = driver_priv->bo;
FUNC_NAME(RADEONDoPrepareCopy)(pScrn, src_pitch_offset, dst_pitch_offset,
datatype, rop, planemask);
@@ -250,6 +324,8 @@ FUNC_NAME(RADEONDoneCopy)(PixmapPtr pDst)
OUT_ACCEL_REG(RADEON_WAIT_UNTIL,
RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE);
FINISH_ACCEL();
+
+ info->state_2d.op = 0;
}
static Bool
@@ -260,6 +336,8 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
uint8_t *dst = info->FB + exaGetPixmapOffset(pDst);
unsigned int dst_pitch = exaGetPixmapPitch(pDst);
unsigned int bpp = pDst->drawable.bitsPerPixel;
+ int ret;
+ struct radeon_exa_pixmap_priv *driver_priv;
#ifdef ACCEL_CP
unsigned int hpass;
uint32_t buf_pitch, dst_pitch_off;
@@ -276,10 +354,47 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
if (bpp < 8)
return FALSE;
+ if (info->new_cs)
+ dst = info->mm.front_buffer->map + exaGetPixmapOffset(pDst);
+
#ifdef ACCEL_CP
- if (info->directRenderingEnabled &&
- RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off)) {
- uint8_t *buf;
+
+ if (info->new_cs){
+
+ if (info->drm_mm) {
+ uint32_t offset, bo_width, bo_height = h;
+
+ driver_priv = exaGetPixmapDriverPrivate(pDst);
+ if (!driver_priv)
+ return FALSE;
+
+
+ /* use pwrites - maybe require some sort of fallback */
+ bo_width = w * (bpp / 8);
+ offset = (x * bpp / 8) + (y * dst_pitch);
+
+ while (bo_height--) {
+ ret = dri_bo_subdata(driver_priv->bo, offset, bo_width,
+ src);
+ if (ret == -1)
+ return FALSE;
+
+ src += src_pitch;
+ offset += dst_pitch;
+ }
+
+ return TRUE;
+ }
+ }
+ if (!info->directRenderingEnabled && !info->drm_mode_setting)
+ goto fallback;
+
+ if (RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off))
+ goto fallback;
+
+ if (!info->new_cs)
+ {
+ uint8_t *buf;
int cpp = bpp / 8;
ACCEL_PREAMBLE();
@@ -294,9 +409,10 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
exaMarkSync(pDst->drawable.pScreen);
return TRUE;
- }
-#endif
+ }
+ fallback:
+#endif
/* Do we need that sync here ? probably not .... */
exaWaitSync(pDst->drawable.pScreen);
@@ -388,13 +504,17 @@ FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
TRACE;
+ if (info->drm_mode_setting)
+ src = info->mm.front_buffer->map + exaGetPixmapOffset(pSrc);
+
#ifdef ACCEL_CP
/*
* Try to accelerate download. Use an indirect buffer as scratch space,
* blitting the bits to one half while copying them out of the other one and
* then swapping the halves.
*/
- if (info->accelDFS && bpp != 24 && RADEONGetDatatypeBpp(bpp, &datatype) &&
+ if (!info->drm_mm && info->accelDFS && bpp != 24 &&
+ RADEONGetDatatypeBpp(bpp, &datatype) &&
RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset) &&
(scratch = RADEONCPGetBuffer(pScrn)))
{
@@ -540,17 +660,23 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
info->exa->MarkSync = FUNC_NAME(RADEONMarkSync);
info->exa->WaitMarker = FUNC_NAME(RADEONSync);
+
info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen);
- info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);
+ if (!info->drm_mm) {
+ info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);
+ }
-#if X_BYTE_ORDER == X_BIG_ENDIAN
info->exa->PrepareAccess = RADEONPrepareAccess;
info->exa->FinishAccess = RADEONFinishAccess;
-#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
info->exa->flags = EXA_OFFSCREEN_PIXMAPS;
- info->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1;
info->exa->pixmapPitchAlign = 64;
+ info->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1;
+
+ if (info->drm_mm) {
+ info->exa->flags |= EXA_HANDLES_PIXMAPS;
+ } else {
+ }
#ifdef RENDER
if (info->RenderAccel) {
@@ -560,7 +686,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
else if (IS_R300_3D || IS_R500_3D) {
if ((info->ChipFamily < CHIP_FAMILY_RS400)
#ifdef XF86DRI
- || (info->directRenderingEnabled)
+ || (info->directRenderingEnabled || info->drm_mode_setting)
#endif
) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
@@ -595,6 +721,16 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
}
#endif
+#if EXA_VERSION_MINOR >= 4
+ if (info->drm_mm) {
+ info->exa->CreatePixmap = RADEONEXACreatePixmap;
+ info->exa->DestroyPixmap = RADEONEXADestroyPixmap;
+ info->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
+ info->exa->ModifyPixmapHeader = RADEONEXAModifyPixmapHeader;
+ }
+#endif
+
+
#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index 5d28d80..6426736 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -410,19 +410,22 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
if (unit == 0) {
OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset);
OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0,
(pPix->drawable.width - 1) |
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, txpitch - 32);
+ OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset);
+ /* emit a texture relocation */
} else {
OUT_ACCEL_REG(RADEON_PP_TXFILTER_1, txfilter);
OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat);
- OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset);
+
OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_1,
(pPix->drawable.width - 1) |
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_1, txpitch - 32);
+ OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset);
+ /* emit a texture relocation */
}
FINISH_ACCEL();
@@ -730,6 +733,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(R200_PP_TXPITCH_0, txpitch - 32);
OUT_ACCEL_REG(R200_PP_TXOFFSET_0, txoffset);
+ /* emit a texture relocation */
} else {
OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter);
OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat);
@@ -738,6 +742,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch - 32);
OUT_ACCEL_REG(R200_PP_TXOFFSET_1, txoffset);
+ /* emit a texture relocation */
}
FINISH_ACCEL();
@@ -1002,12 +1007,14 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
int w = pPict->pDrawable->width;
int h = pPict->pDrawable->height;
int i, pixel_shift;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int qwords;
ACCEL_PREAMBLE();
TRACE;
txpitch = exaGetPixmapPitch(pPix);
- txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+ txoffset = exaGetPixmapOffset(pPix);
if ((txoffset & 0x1f) != 0)
RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
@@ -1071,13 +1078,25 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
}
- BEGIN_ACCEL(pPict->repeat ? 6 : 7);
+ qwords = pPict->repeat ? 6 : 7;
+ qwords += info->new_cs ? 2 : 0;
+
+ BEGIN_ACCEL(qwords);
OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0);
OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
- OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
+
+ driver_priv = exaGetPixmapDriverPrivate(pPix);
+ if (info->new_cs) {
+ uint32_t handle = 0;
+ OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), driver_priv ? 0 : txoffset);
+ OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+ } else {
+ txoffset += info->fbLocation + pScrn->fbOffset;
+ OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
+ }
if (!pPict->repeat)
OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
FINISH_ACCEL();
@@ -1187,6 +1206,8 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
uint32_t txenable, colorpitch;
uint32_t blendcntl;
int pixel_shift;
+ int qwords;
+ struct radeon_exa_pixmap_priv *driver_priv;
ACCEL_PREAMBLE();
TRACE;
@@ -1204,7 +1225,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
pixel_shift = pDst->drawable.bitsPerPixel >> 4;
- dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
+ dst_offset = exaGetPixmapOffset(pDst);
dst_pitch = exaGetPixmapPitch(pDst);
colorpitch = dst_pitch >> pixel_shift;
@@ -1830,9 +1851,18 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
FINISH_ACCEL();
}
- BEGIN_ACCEL(3);
+ qwords = info->new_cs ? 5 : 3;
+ BEGIN_ACCEL(qwords);
+ if (info->new_cs) {
+ driver_priv = exaGetPixmapDriverPrivate(pDst);
+ assert(driver_priv);
- OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, 0);
+ OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+ } else {
+ dst_offset += info->fbLocation + pScrn->fbOffset;
+ OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ }
OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
diff --git a/src/radeon_memory.c b/src/radeon_memory.c
new file mode 100644
index 0000000..ccc3bb8
--- /dev/null
+++ b/src/radeon_memory.c
@@ -0,0 +1,424 @@
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include "radeon.h"
+#include "radeon_drm.h"
+
+Bool
+radeon_bind_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (mem == NULL || mem->bound)
+ return TRUE;
+
+ if (!info->drm_mm)
+ return FALSE;
+
+ if (mem->kernel_bo_handle) {
+ struct drm_radeon_gem_pin pin;
+
+ int ret;
+
+ pin.handle = mem->kernel_bo_handle;
+ pin.alignment = mem->alignment;
+
+ ret = ioctl(info->drmFD, DRM_IOCTL_RADEON_GEM_PIN, &pin);
+ if (ret != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to pin %s: %s\n", mem->name, strerror(errno));
+ return FALSE;
+ }
+
+ mem->bound = TRUE;
+ mem->offset = pin.offset;
+ // ErrorF("pin returned 0x%llx\n", pin.offset);
+ mem->end = mem->offset + mem->size;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static Bool
+radeon_unbind_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int ret;
+
+ if (mem == NULL || !mem->bound)
+ return TRUE;
+
+ if (!info->drm_mm)
+ return FALSE;
+
+
+ if (mem->kernel_bo_handle) {
+ struct drm_radeon_gem_unpin unpin;
+
+ unpin.handle = mem->kernel_bo_handle;
+ ret = ioctl(info->drmFD, DRM_IOCTL_RADEON_GEM_UNPIN, &unpin);
+
+ if (ret == 0) {
+ mem->bound = FALSE;
+ mem->offset = -1;
+ mem->end = -1;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+void radeon_free_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (mem == NULL)
+ return;
+
+ if (mem->map)
+ radeon_unmap_memory(pScrn, mem);
+
+ radeon_unbind_memory(pScrn, mem);
+
+ if (mem->kernel_bo_handle) {
+ struct drm_gem_close close;
+
+ close.handle = mem->kernel_bo_handle;
+ ioctl(info->drmFD, DRM_IOCTL_GEM_CLOSE, &close);
+ }
+
+ if (info->mm.bo_list[mem->pool] == mem) {
+ info->mm.bo_list[mem->pool] = mem->next;
+ if (mem->next)
+ mem->next->prev = NULL;
+ } else {
+ if (mem->prev)
+ mem->prev->next = mem->next;
+ if (mem->next)
+ mem->next->prev = mem->prev;
+ }
+ xfree(mem->name);
+ xfree(mem);
+ return;
+}
+
+struct radeon_memory *radeon_allocate_memory(ScrnInfoPtr pScrn, int pool, int size, int alignment, Bool no_backing_store, char *name,
+ int static_alloc)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct drm_radeon_gem_create args;
+ struct radeon_memory *mem;
+ int ret;
+
+ mem = xcalloc(1, sizeof(*mem));
+ if (!mem)
+ return NULL;
+
+ mem->name = xstrdup(name);
+ if (!mem->name) {
+ xfree(mem);
+ return NULL;
+ }
+
+ mem->size = size;
+ mem->pool = pool;
+ mem->next = mem->prev = NULL;
+ mem->vt_bind = static_alloc;
+ args.size = size;
+ args.alignment = alignment;
+ if (pool == RADEON_POOL_VRAM)
+ args.initial_domain = RADEON_GEM_DOMAIN_VRAM;
+ else
+ args.initial_domain = RADEON_GEM_DOMAIN_GTT;
+ args.no_backing_store = no_backing_store;
+
+ ret = drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_CREATE, &args, sizeof(args));
+ if (ret) {
+ ErrorF("Failed to allocate %s\n", mem->name);
+ xfree(mem);
+ return NULL;
+ }
+
+ mem->kernel_bo_handle = args.handle;
+ // xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ // "%s allocated %d with handle %x\n", mem->name, mem->size, mem->kernel_bo_handle);
+
+ /* add to VRAM linked list for now */
+
+ mem->prev = NULL;
+ mem->next = info->mm.bo_list[pool];
+ if (info->mm.bo_list[pool] != NULL)
+ info->mm.bo_list[pool]->prev = mem;
+ info->mm.bo_list[pool] = mem;
+ return mem;
+}
+
+Bool radeon_bind_all_memory(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_memory *mem;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ for (mem = info->mm.bo_list[i]; mem != NULL;
+ mem = mem->next) {
+ if (mem->vt_bind)
+ if (!radeon_bind_memory(pScrn, mem)) {
+ FatalError("Couldn't bind %s\n", mem->name);
+ }
+ }
+ }
+ return TRUE;
+}
+
+Bool radeon_unbind_all_memory(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_memory *mem;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ for (mem = info->mm.bo_list[i]; mem != NULL;
+ mem = mem->next) {
+ if (mem->vt_bind)
+ radeon_unbind_memory(pScrn, mem);
+ }
+ }
+ return TRUE;
+}
+
+Bool radeon_free_all_memory(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ struct radeon_memory *mem;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ for (mem = info->mm.bo_list[i]; mem != NULL;
+ mem = mem->next) {
+ radeon_free_memory(pScrn, mem);
+ }
+ }
+ return TRUE;
+}
+
+int radeon_map_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+ struct drm_radeon_gem_mmap args;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int ret;
+
+ assert(!mem->map);
+
+
+ args.handle = mem->kernel_bo_handle;
+ args.size = mem->size;
+ ret = drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_MMAP, &args, sizeof(args));
+
+ if (!ret)
+ mem->map = (void *)(unsigned long)args.addr_ptr;
+ // ErrorF("Mapped %s size %ld at %x %p\n", mem->name, mem->size, mem->offset, mem->map);
+ return ret;
+}
+
+void radeon_unmap_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+ assert(mem->map);
+ if (mem->map) {
+ munmap(mem->map, mem->size);
+ mem->map = NULL;
+ }
+}
+
+/* Okay radeon
+ 2D allocations
+ - Front buffer
+ - cursors
+ - EXA space
+
+ 3D related:
+ - Backbuffer
+ - Depth buffer
+ - textures
+*/
+
+
+Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int cpp = info->CurrentLayout.pixel_bytes;
+ int screen_size;
+ int stride = pScrn->displayWidth * cpp;
+ int total_size_bytes = (20*1024*1024)+32*1024, remain_size_bytes;
+ int fb_size_bytes;
+
+ screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * stride;
+
+ ErrorF("%d x %d x %d = %dK\n", pScrn->displayWidth, pScrn->virtualY, cpp, screen_size / 1024);
+
+ {
+ int cursor_size = 64 * 4 * 64;
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ /* cursor objects */
+ info->mm.cursor[c] = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, cursor_size, 0, 1, "Cursor", 1);
+ if (!info->mm.cursor[c]) {
+ return FALSE;
+ }
+
+ radeon_bind_memory(pScrn, info->mm.cursor[c]);
+
+ if (radeon_map_memory(pScrn, info->mm.cursor[c])) {
+ ErrorF("Failed to map front buffer memory\n");
+ }
+
+ if (!info->drm_mode_setting) {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ radeon_crtc->cursor = info->mm.cursor[c];
+ } else {
+ drmmode_set_cursor(pScrn, &info->drmmode, c, (void *)info->mm.cursor[c]->map, info->mm.cursor[c]->kernel_bo_handle);
+ }
+ total_size_bytes += cursor_size;
+ }
+ }
+
+#if 0
+ info->mm.front_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, screen_size, 0, 1, "Front Buffer");
+ if (!info->mm.front_buffer) {
+ return FALSE;
+ }
+
+ radeon_bind_memory(pScrn, info->mm.front_buffer);
+
+ if (radeon_map_memory(pScrn, info->mm.front_buffer)) {
+ ErrorF("Failed to map front buffer memory\n");
+ }
+#endif
+ /* keep area front front buffer - but don't allocate it yet */
+ total_size_bytes += screen_size;
+
+ if (info->directRenderingEnabled) {
+ info->backPitch = pScrn->displayWidth;
+ info->mm.back_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, screen_size, 0, 1, "Back Buffer", 1);
+ if (!info->mm.back_buffer) {
+ return FALSE;
+ }
+ radeon_bind_memory(pScrn, info->mm.back_buffer);
+ total_size_bytes += screen_size;
+
+ info->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
+ {
+ int depthCpp = (info->depthBits - 8) / 4;
+ int depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->depthPitch * depthCpp;
+ info->mm.depth_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, depth_size, 0, 1, "Depth Buffer", 1);
+ if (!info->mm.depth_buffer) {
+ return FALSE;
+ }
+ radeon_bind_memory(pScrn, info->mm.depth_buffer);
+ total_size_bytes += depth_size;
+ }
+ }
+ /* work out from the mm size what the exa / tex sizes need to be */
+ remain_size_bytes = info->mm.vram_size - total_size_bytes;
+
+ info->textureSize = remain_size_bytes / 2;
+
+ ErrorF("texture size is %dK, exa is %dK\n", info->textureSize / 1024, (remain_size_bytes - info->textureSize)/1024);
+
+ /* allocate an object for all the EXA bits */
+ /* shove EXA + frontbuffer together until we have EXA pixmap hooks */
+ fb_size_bytes = screen_size + (remain_size_bytes - info->textureSize);
+
+ if (info->new_cs)
+ fb_size_bytes = screen_size;
+ ErrorF("fb size is %dK %dK\n", fb_size_bytes / 1024, total_size_bytes / 1024);
+
+ info->mm.front_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, fb_size_bytes, 0, 1, "Front Buffer + EXA", 1);
+ if (!info->mm.front_buffer) {
+ return FALSE;
+ }
+
+ radeon_bind_memory(pScrn, info->mm.front_buffer);
+ if (radeon_map_memory(pScrn, info->mm.front_buffer)) {
+ ErrorF("Failed to map front buffer memory\n");
+ }
+ info->frontPitch = pScrn->displayWidth;
+#if 0
+ info->mm.exa_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, remain_size_bytes - info->textureSize, 0, 1, "EXA Memory Buffer");
+ if (!info->mm.exa_buffer) {
+ return FALSE;
+ }
+ radeon_bind_memory(pScrn, info->mm.exa_buffer);
+ if (radeon_map_memory(pScrn, info->mm.exa_buffer)) {
+ ErrorF("Failed to map front buffer memory\n");
+ }
+#endif
+
+ if (!info->new_cs) {
+ info->exa->memoryBase = info->mm.front_buffer->map;
+ info->exa->offScreenBase = screen_size;
+ info->exa->memorySize = fb_size_bytes;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use %ld kb for X Server offscreen at offset 0x%08lx\n",
+ (info->exa->memorySize - info->exa->offScreenBase) /
+ 1024, info->exa->offScreenBase);
+ }
+
+ if (info->directRenderingEnabled) {
+ info->textureSize /= 2;
+ info->mm.texture_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, info->textureSize, 0, 1, "Texture Buffer", 1);
+ if (!info->mm.texture_buffer) {
+ return FALSE;
+ }
+ radeon_bind_memory(pScrn, info->mm.texture_buffer);
+ }
+
+ if (info->drm_mode_setting) {
+ drmmode_set_fb(pScrn, &info->drmmode, pScrn->virtualX, RADEON_ALIGN(pScrn->virtualY, 16), stride, info->mm.front_buffer->kernel_bo_handle);
+ }
+ return TRUE;
+}
+
+Bool radeon_setup_gart_mem(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+
+ info->mm.gart_texture_buffer =
+ radeon_allocate_memory(pScrn, RADEON_POOL_GART,
+ info->gartTexMapSize,
+ 0, 1, "GART texture buffers", 1);
+
+ if (!info->mm.gart_texture_buffer) {
+ return FALSE;
+ }
+
+ radeon_bind_memory(pScrn, info->mm.gart_texture_buffer);
+ return TRUE;
+}
+
+uint32_t radeon_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
+{
+ return 0;
+}
+
+
+dri_bo *radeon_create_rotate_bo(ScrnInfoPtr pScrn, int size)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ dri_bo *bo;
+
+ bo = dri_bo_alloc(info->bufmgr, "rotate", size, 0);
+
+ radeon_bufmgr_pin(bo);
+ return bo;
+}
+
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 3770abf..e8505b7 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -182,6 +182,27 @@ typedef struct
uint32_t a_data_mask;
} RADEONI2CBusRec, *RADEONI2CBusPtr;
+struct radeon_memory {
+ int pool; // memory is VRAM vs GART
+ unsigned long offset;
+ unsigned long end;
+
+ unsigned long size;
+ unsigned long allocated_size;
+ void *map;
+ int key;
+
+ Bool bound;
+ unsigned long agp_offset;
+ unsigned int pitch;
+ char *name;
+ struct radeon_memory *next, *prev;
+ uint32_t alignment;
+ uint32_t kernel_bo_handle;
+ uint32_t kernel_name;
+ Bool vt_bind;
+};
+
typedef struct _RADEONCrtcPrivateRec {
#ifdef USE_XAA
FBLinearPtr rotate_mem_xaa;
@@ -198,6 +219,8 @@ typedef struct _RADEONCrtcPrivateRec {
uint32_t crtc_offset;
int can_tile;
Bool enabled;
+ struct radeon_memory *cursor;
+
} RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
typedef struct {
diff --git a/src/radeon_sarea.h b/src/radeon_sarea.h
index 80333a4..c33632b 100644
--- a/src/radeon_sarea.h
+++ b/src/radeon_sarea.h
@@ -36,6 +36,7 @@
#ifndef _RADEON_SAREA_H_
#define _RADEON_SAREA_H_
+#if 0
/* WARNING: If you change any of these defines, make sure to change the
* defines in the kernel file (radeon_drm.h)
*/
@@ -229,3 +230,6 @@ typedef struct {
} RADEONSAREAPriv, *RADEONSAREAPrivPtr;
#endif
+
+typedef drm_radeon_sarea_t RADEONSAREAPriv, *RADEONSAREAPrivPtr;
+#endif
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index cfa349d..ef05c72 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -85,6 +85,7 @@ static __inline__ uint32_t F_TO_DW(float val)
#define BEGIN_VIDEO(n) RADEONWaitForFifo(pScrn, (n))
#define OUT_VIDEO_REG(reg, val) OUTREG(reg, val)
#define OUT_VIDEO_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
+#define OUT_RELOC(x, read, write) do {} while(0)
#define FINISH_VIDEO()
#include "radeon_textured_videofuncs.c"
@@ -93,6 +94,7 @@ static __inline__ uint32_t F_TO_DW(float val)
#undef VIDEO_PREAMBLE
#undef BEGIN_VIDEO
#undef OUT_VIDEO_REG
+#undef OUT_RELOC
#undef FINISH_VIDEO
#ifdef XF86DRI
@@ -105,6 +107,7 @@ static __inline__ uint32_t F_TO_DW(float val)
#define OUT_VIDEO_REG(reg, val) OUT_RING_REG(reg, val)
#define FINISH_VIDEO() ADVANCE_RING()
#define OUT_VIDEO_RING_F(x) OUT_RING(F_TO_DW(x))
+#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
#include "radeon_textured_videofuncs.c"
@@ -179,7 +182,8 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
}
#ifdef XF86DRI
- if (info->directRenderingEnabled && info->DMAForXv)
+ if ((info->directRenderingEnabled || info->drm_mode_setting)
+ && info->DMAForXv )
/* The upload blit only supports multiples of 64 bytes */
dstPitch = (dstPitch + 63) & ~63;
else
@@ -226,8 +230,12 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
left = (x1 >> 16) & ~1;
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
- pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset;
- pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch));
+ pPriv->src_offset = pPriv->video_offset;
+ if (info->drm_mm) {
+ pPriv->src_addr = (uint8_t *)(info->mm.front_buffer->map + pPriv->video_offset + (top * dstPitch));
+ } else {
+ pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch));
+ }
pPriv->src_pitch = dstPitch;
pPriv->size = size;
pPriv->pDraw = pDraw;
@@ -283,7 +291,7 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
pPriv->h = height;
#ifdef XF86DRI
- if (info->directRenderingEnabled)
+ if (info->directRenderingEnabled || info->drm_mode_setting)
RADEONDisplayTexturedVideoCP(pScrn, pPriv);
else
#endif
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index d39f74d..56d71b1 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -82,19 +82,19 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
int dstxoff, dstyoff, pixel_shift;
BoxPtr pBox = REGION_RECTS(&pPriv->clip);
int nBox = REGION_NUM_RECTS(&pPriv->clip);
+ int qwords;
VIDEO_PREAMBLE();
pixel_shift = pPixmap->drawable.bitsPerPixel >> 4;
#ifdef USE_EXA
if (info->useEXA) {
- dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
+ dst_offset = exaGetPixmapOffset(pPixmap);
dst_pitch = exaGetPixmapPitch(pPixmap);
} else
#endif
{
- dst_offset = (pPixmap->devPrivate.ptr - info->FB) +
- info->fbLocation + pScrn->fbOffset;
+ dst_offset = (pPixmap->devPrivate.ptr - info->FB);
dst_pitch = pPixmap->devKind;
}
@@ -183,13 +183,21 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
txoffset = pPriv->src_offset;
- BEGIN_VIDEO(6);
+ qwords = info->new_cs ? 8 : 6;
+ BEGIN_VIDEO(qwords);
OUT_VIDEO_REG(R300_TX_FILTER0_0, txfilter);
OUT_VIDEO_REG(R300_TX_FILTER1_0, 0);
OUT_VIDEO_REG(R300_TX_FORMAT0_0, txformat0);
OUT_VIDEO_REG(R300_TX_FORMAT1_0, txformat1);
OUT_VIDEO_REG(R300_TX_FORMAT2_0, txpitch);
- OUT_VIDEO_REG(R300_TX_OFFSET_0, txoffset);
+
+ if (info->new_cs) {
+ OUT_VIDEO_REG(R300_TX_OFFSET_0, txoffset);
+ OUT_RELOC(info->mm.front_buffer->kernel_bo_handle, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+ } else {
+ txoffset += info->fbLocation + pScrn->fbOffset;
+ OUT_VIDEO_REG(R300_TX_OFFSET_0, txoffset);
+ }
FINISH_VIDEO();
txenable = R300_TEX_0_ENABLE;
@@ -408,11 +416,18 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
FINISH_VIDEO();
}
- BEGIN_VIDEO(5);
+ qwords = info->new_cs ? 7 : 5;
+ BEGIN_VIDEO(qwords);
OUT_VIDEO_REG(R300_TX_INVALTAGS, 0);
OUT_VIDEO_REG(R300_TX_ENABLE, txenable);
- OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ if (info->new_cs) {
+ OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ OUT_RELOC(info->mm.front_buffer->kernel_bo_handle, 0, RADEON_GEM_DOMAIN_VRAM);
+ } else {
+ dst_offset += info->fbLocation + pScrn->fbOffset;
+ OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+ }
OUT_VIDEO_REG(R300_RB3D_COLORPITCH0, colorpitch);
blendcntl = RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO;
@@ -459,6 +474,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE);
OUT_VIDEO_REG(RADEON_RB3D_CNTL,
dst_format | RADEON_ALPHA_BLEND_ENABLE);
+ dst_offset += info->fbLocation + pScrn->fbOffset;
OUT_VIDEO_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
OUT_VIDEO_REG(RADEON_RB3D_COLORPITCH, colorpitch);
@@ -496,7 +512,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT));
OUT_VIDEO_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32);
- OUT_VIDEO_REG(R200_PP_TXOFFSET_0, pPriv->src_offset);
+ OUT_VIDEO_REG(R200_PP_TXOFFSET_0, pPriv->src_offset +
+ info->fbLocation + pScrn->fbOffset);
OUT_VIDEO_REG(R200_PP_TXCBLEND_0,
R200_TXC_ARG_A_ZERO |
@@ -530,7 +547,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
RADEON_CLAMP_T_CLAMP_LAST |
RADEON_YUV_TO_RGB);
OUT_VIDEO_REG(RADEON_PP_TXFORMAT_0, txformat);
- OUT_VIDEO_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset);
+ OUT_VIDEO_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset +
+ info->fbLocation + pScrn->fbOffset);
OUT_VIDEO_REG(RADEON_PP_TXCBLEND_0,
RADEON_COLOR_ARG_A_ZERO |
RADEON_COLOR_ARG_B_ZERO |
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 57dcd8a..ecd34a1 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -275,7 +275,7 @@ void RADEONInitVideo(ScreenPtr pScreen)
memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
adaptors = newAdaptors;
- if (!IS_AVIVO_VARIANT) {
+ if (!IS_AVIVO_VARIANT && !info->drm_mode_setting) {
overlayAdaptor = RADEONSetupImageVideo(pScreen);
if (overlayAdaptor != NULL) {
adaptors[num_adaptors++] = overlayAdaptor;
@@ -288,7 +288,7 @@ void RADEONInitVideo(ScreenPtr pScreen)
if (info->ChipFamily != CHIP_FAMILY_RV250) {
if ((info->ChipFamily < CHIP_FAMILY_RS400)
#ifdef XF86DRI
- || (info->directRenderingEnabled)
+ || (info->directRenderingEnabled || info->drm_mode_setting)
#endif
) {
texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);