diff -up xf86-video-ati-6.12.2/configure.ac.modeset xf86-video-ati-6.12.2/configure.ac --- xf86-video-ati-6.12.2/configure.ac.modeset 2009-04-08 10:29:53.000000000 -0400 +++ xf86-video-ati-6.12.2/configure.ac 2009-05-21 11:01:45.000000000 -0400 @@ -31,6 +31,7 @@ AM_CONFIG_HEADER([config.h]) AC_CONFIG_AUX_DIR(.) AM_INIT_AUTOMAKE([dist-bzip2]) +AC_SYS_LARGEFILE AM_MAINTAINER_MODE @@ -114,8 +115,19 @@ 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 +#include ]) + if test "x$DRM_MODE" = xyes; then + AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting]) + fi + CFLAGS="$save_CFLAGS" fi +AC_DEFINE(DRI2, 1,[Enable DRI2 code]) + save_CFLAGS="$CFLAGS" CFLAGS="$XORG_CFLAGS" AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"]) diff -up /dev/null xf86-video-ati-6.12.2/src/drmmode_display.c --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/drmmode_display.c 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,1035 @@ +/* + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef XF86DRM_MODE +#include +#include "micmap.h" +#include "xf86cmap.h" +#include "radeon.h" +#include "radeon_reg.h" +#include "radeon_drm.h" +#include "sarea.h" + +/* DPMS */ +#define DPMS_SERVER +#include + +static void +drmmode_ConvertFromKMode(ScrnInfoPtr scrn, + drmModeModeInfo *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, + drmModeModeInfo *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 void +drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) +{ +#if 0 + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); +// drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; +// drmmode_ptr drmmode = drmmode_crtc->drmmode; + + /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */ + if (mode == DPMSModeOff) { +// drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, +// 0, 0, 0, NULL, 0, NULL); + } +#endif +} + +static PixmapPtr +create_pixmap_for_fbcon(drmmode_ptr drmmode, + ScrnInfoPtr pScrn, int crtc_id) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + drmmode_crtc_private_ptr drmmode_crtc; + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr pixmap; + dri_bo *bo; + drmModeFBPtr fbcon; + struct drm_gem_flink flink; + + drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private; + + fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); + if (fbcon == NULL) + return NULL; + + flink.handle = fbcon->handle; + if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't flink fbcon handle\n"); + return NULL; + } + + bo = radeon_bo_gem_create_from_name(drmmode->bufmgr, "fbcon", + flink.name); + if (bo == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate bo for fbcon handle\n"); + return NULL; + } + + pixmap = GetScratchPixmapHeader(pScreen, + fbcon->width, fbcon->height, + fbcon->depth, fbcon->bpp, + fbcon->pitch, NULL); + if (pixmap == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate pixmap fbcon contents\n"); + return NULL; + } + + radeon_set_pixmap_bo(pixmap, bo); + + dri_bo_unreference(bo); + drmModeFreeFB(fbcon); + return pixmap; +} + +void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); + PixmapPtr src, dst; + ScreenPtr pScreen = pScrn->pScreen; + int crtc_id = 0; + int i; + int pitch = pScrn->displayWidth * info->CurrentLayout.pixel_bytes; + + if (info->ChipFamily >= CHIP_FAMILY_R600) + return; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc; + + drmmode_crtc = crtc->driver_private; + if (drmmode_crtc->mode_crtc->buffer_id) + crtc_id = i; + } + + src = create_pixmap_for_fbcon(drmmode, pScrn, crtc_id); + if (!src) + return; + + dst = GetScratchPixmapHeader(pScreen, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pitch, NULL); + radeon_set_pixmap_bo(dst, info->mm.front_buffer); + info->accel_state->exa->PrepareCopy (src, dst, + -1, -1, GXcopy, FB_ALLONES); + info->accel_state->exa->Copy (dst, 0, 0, 0, 0, + pScrn->virtualX, pScrn->virtualY); + info->accel_state->exa->DoneCopy (dst); + RADEONCPFlushIndirect(pScrn, 0); + + (*pScreen->DestroyPixmap)(dst); + (*pScreen->DestroyPixmap)(src); + +} + +static Bool +drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int saved_x, saved_y; + Rotation saved_rotation; + DisplayModeRec saved_mode; + uint32_t *output_ids; + int output_count = 0; + Bool ret = TRUE; + int i; + int fb_id; + drmModeModeInfo kmode; + int pitch = pScrn->displayWidth * info->CurrentLayout.pixel_bytes; + + if (drmmode->fb_id == 0) { + ret = drmModeAddFB(drmmode->fd, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pitch, dri_bo_get_handle(info->mm.front_buffer), + &drmmode->fb_id); + if (ret < 0) { + ErrorF("failed to add fb\n"); + return FALSE; + } + } + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + + if (mode) { + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,5,99,0,0) + crtc->transformPresent = FALSE; +#endif + } + + output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output); + if (!output_ids) { + ret = FALSE; + goto done; + } + + if (mode) { + 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)) { + 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; + x = y = 0; + } + ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, x, y, output_ids, output_count, &kmode); + if (ret) + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "failed to set mode: %s", strerror(-ret)); + else + ret = TRUE; + + if (crtc->scrn->pScreen) + xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); + /* go through all the outputs and force DPMS them back on? */ + 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; + + output->funcs->dpms(output, DPMSModeOn); + } + } + + + +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_bo->virtual; + + 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; + uint32_t handle = dri_bo_get_handle(drmmode_crtc->cursor_bo); + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 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; + dri_bo *rotate_bo; + int ret; + unsigned long rotate_pitch; + + width = RADEON_ALIGN(width, 63); + rotate_pitch = width * drmmode->cpp; + + size = rotate_pitch * height; + + rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate", size, 0, RADEON_GEM_DOMAIN_VRAM); + if (rotate_bo == NULL) + return NULL; + + dri_bo_map(rotate_bo, 1); + + ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, + crtc->scrn->bitsPerPixel, rotate_pitch, dri_bo_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 = RADEON_ALIGN(width, 63) * 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"); + } + + if (drmmode_crtc->rotate_bo) + radeon_set_pixmap_bo(rotate_pixmap, drmmode_crtc->rotate_bo); + 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_unmap(drmmode_crtc->rotate_bo); + dri_bo_unreference(drmmode_crtc->rotate_bo); + drmmode_crtc->rotate_bo = NULL; + } + +} + +static void +drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, + uint16_t *blue, int size) +{ + return; +} + +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, + + .gamma_set = drmmode_crtc_gamma_set, + .shadow_create = drmmode_crtc_shadow_create, + .shadow_allocate = drmmode_crtc_shadow_allocate, + .shadow_destroy = drmmode_crtc_shadow_destroy, + .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) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + + drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, + drmmode_output->dpms_enum_id, 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; + drmModePropertyPtr props; + char name[32]; + int i; + + koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); + if (!koutput) + return; + + kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]); + if (!kencoder) { + drmModeFreeConnector(koutput); + return; + } + + /* need to do smart conversion here for compat with non-kms ATI driver */ + if (koutput->connector_type_id == 1) { + switch(koutput->connector_type) { + case DRM_MODE_CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_DVII: + case DRM_MODE_CONNECTOR_DVID: + case DRM_MODE_CONNECTOR_DVIA: + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); + break; + default: + snprintf(name, 32, "%s", output_names[koutput->connector_type]); + break; + } + } else { + snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); + } + + 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; + + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props && (props->flags && DRM_MODE_PROP_ENUM)) { + if (!strcmp(props->name, "DPMS")) { + drmmode_output->dpms_enum_id = koutput->props[i]; + drmModeFreeProperty(props); + break; + } + drmModeFreeProperty(props); + } + } + + return; +} + +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; + RADEONInfoPtr info = RADEONPTR(scrn); + dri_bo *old_front = NULL; + BoxRec mem_box; + Bool tiled, ret; + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + uint32_t old_fb_id; + int i, pitch, old_width, old_height, old_pitch; + int screen_size; + int cpp = info->CurrentLayout.pixel_bytes; + dri_bo *front_bo; + + if (scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + + front_bo = radeon_get_pixmap_bo(screen->GetScreenPixmap(screen)); + RADEONCPFlushIndirect(scrn, 0); + + if (front_bo) + radeon_bufmgr_gem_wait_rendering(front_bo); + + pitch = RADEON_ALIGN(width, 63); + height = RADEON_ALIGN(height, 16); + + screen_size = pitch * height * cpp; + + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Allocate new frame buffer %dx%d stride %d\n", + width, height, pitch); + + old_width = scrn->virtualX; + old_height = scrn->virtualY; + old_pitch = scrn->displayWidth; + old_fb_id = drmmode->fb_id; + old_front = info->mm.front_buffer; + + scrn->virtualX = width; + scrn->virtualY = height; + scrn->displayWidth = pitch; + + info->mm.front_buffer = dri_bo_alloc(info->bufmgr, "front", screen_size, 0, RADEON_GEM_DOMAIN_VRAM); + if (!info->mm.front_buffer) + goto fail; + + ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, + scrn->bitsPerPixel, pitch * cpp, + dri_bo_get_handle(info->mm.front_buffer), + &drmmode->fb_id); + if (ret) + goto fail; + + radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), info->mm.front_buffer); + screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen), + width, height, -1, -1, pitch * cpp, NULL); + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n", + info->mm.front_buffer->offset); + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if (!crtc->enabled) + continue; + + drmmode_set_mode_major(crtc, &crtc->mode, + crtc->rotation, crtc->x, crtc->y); + } + + if (old_fb_id) + drmModeRmFB(drmmode->fd, old_fb_id); + if (old_front) + dri_bo_unreference(old_front); + + return TRUE; + + fail: + if (info->mm.front_buffer) + radeon_free_memory(scrn, info->mm.front_buffer); + info->mm.front_buffer = old_front; + scrn->virtualX = old_width; + scrn->virtualY = old_height; + scrn->displayWidth = old_pitch; + drmmode->fb_id = old_fb_id; + + return FALSE; +} + +static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { + drmmode_xf86crtc_resize +}; + + +Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp, int zaphod_mask) +{ + xf86CrtcConfigPtr xf86_config; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + int i; + Bool ret; + + /* Create a bus Id */ + /* Low level DRM open */ + if (!pRADEONEnt->fd) { + 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); + pRADEONEnt->fd = drmmode->fd; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + " reusing fd for second head\n"); + drmmode->fd = pRADEONEnt->fd; + } + 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++) + if (zaphod_mask & (1 << i)) + drmmode_crtc_init(pScrn, drmmode, i); + + for (i = 0; i < drmmode->mode_res->count_connectors; i++) + if (zaphod_mask & (1 << i)) + drmmode_output_init(pScrn, drmmode, i); + + xf86InitialConfiguration(pScrn, TRUE); + + return TRUE; +} + +Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr) +{ + drmmode->bufmgr = bufmgr; + return TRUE; +} + + + +void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, dri_bo *bo) +{ + 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_bo = bo; +} + +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); + } +} + +Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c, o; + + drmmode_copy_fb(pScrn, drmmode); + + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + xf86OutputPtr output = NULL; + int o; + + /* Skip disabled CRTCs */ + if (!crtc->enabled) { + drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + 0, 0, 0, NULL, 0, NULL); + continue; + } + + if (config->output[config->compat_output]->crtc == crtc) + output = config->output[config->compat_output]; + else + { + for (o = 0; o < config->num_output; o++) + if (config->output[o]->crtc == crtc) + { + output = config->output[o]; + break; + } + } + /* paranoia */ + if (!output) + continue; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) + { + DisplayModePtr mode = xf86OutputFindClosestMode (output, pScrn->currentMode); + + if (!mode) + return FALSE; + crtc->desiredMode = *mode; + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, + crtc->desiredX, crtc->desiredY)) + return FALSE; + } + return TRUE; +} + +static void drmmode_load_palette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + uint16_t lut_r[256], lut_g[256], lut_b[256]; + int index, j, i; + int c; + + + + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + for (i = 0 ; i < 256; i++) { + lut_r[i] = drmmode_crtc->lut_r[i] << 6; + lut_g[i] = drmmode_crtc->lut_g[i] << 6; + lut_b[i] = drmmode_crtc->lut_b[i] << 6; + } + +#if 0 //TODO + switch (info->CurrentLayout.depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 6; + lut_g[index * 8 + j] = colors[index].green << 6; + lut_b[index * 8 + j] = colors[index].blue << 6; + } + } + break; + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + + if (i <= 31) { + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 6; + lut_b[index * 8 + j] = colors[index].blue << 6; + } + } + + for (j = 0; j < 4; j++) { + lut_g[index * 4 + j] = colors[index].green << 6; + } + } + break; + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 6; + lut_g[index] = colors[index].green << 6; + lut_b[index] = colors[index].blue << 6; + } + break; + } +#endif + + /* Make the change through RandR */ +#ifdef RANDR_12_INTERFACE + if (crtc->randr_crtc) + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); + else +#endif + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); + } +} + +Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) +{ + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Initializing kms color map\n"); + if (!miCreateDefColormap(pScreen)) + return FALSE; + /* all radeons support 10 bit CLUTs */ + if (!xf86HandleColormaps(pScreen, 256, 10, + drmmode_load_palette, NULL, + CMAP_PALETTED_TRUECOLOR +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + | CMAP_RELOAD_ON_MODE_SWITCH)) + return FALSE; + return TRUE; +} +#endif diff -up /dev/null xf86-video-ati-6.12.2/src/drmmode_display.h --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/drmmode_display.h 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,76 @@ +/* + * 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 + * + */ +#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; +} drmmode_rec, *drmmode_ptr; + +typedef struct { + + drmmode_ptr drmmode; + drmModeCrtcPtr mode_crtc; + dri_bo *cursor_bo; + dri_bo *rotate_bo; + int rotate_fb_id; + uint16_t lut_r[256], lut_g[256], lut_b[256]; +} 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; + int dpms_enum_id; +} 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, int zaphod_mask); +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, dri_bo *bo); +extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, dri_bo *bo); +void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags); +extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); +#endif + +#endif diff -up xf86-video-ati-6.12.2/src/Makefile.am.modeset xf86-video-ati-6.12.2/src/Makefile.am --- xf86-video-ati-6.12.2/src/Makefile.am.modeset 2009-03-31 15:11:10.000000000 -0400 +++ xf86-video-ati-6.12.2/src/Makefile.am 2009-05-21 11:01:45.000000000 -0400 @@ -90,12 +90,14 @@ radeon_drv_ladir = @moduledir@/drivers radeon_drv_la_SOURCES = \ radeon_accel.c radeon_cursor.c radeon_dga.c radeon_legacy_memory.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_gem.c \ + radeon_dri_bufmgr.c radeon_dri2.c if XMODES radeon_drv_la_SOURCES += \ @@ -144,6 +146,7 @@ EXTRA_DIST = \ radeon_exa_render.c \ radeon_exa_funcs.c \ radeon.h \ + radeon_dri2.h \ radeon_macros.h \ radeon_probe.h \ radeon_reg.h \ @@ -164,4 +167,6 @@ 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 \ + radeon_dri_bufmgr.h diff -up xf86-video-ati-6.12.2/src/r600_textured_videofuncs.c.modeset xf86-video-ati-6.12.2/src/r600_textured_videofuncs.c --- xf86-video-ati-6.12.2/src/r600_textured_videofuncs.c.modeset 2009-04-07 11:32:33.000000000 -0400 +++ xf86-video-ati-6.12.2/src/r600_textured_videofuncs.c 2009-05-21 11:01:45.000000000 -0400 @@ -215,7 +215,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pSc switch(pPriv->id) { case FOURCC_YV12: case FOURCC_I420: - accel_state->src_mc_addr[0] = pPriv->src_offset; + accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset; accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h; /* flush texture cache */ @@ -316,7 +316,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pSc case FOURCC_UYVY: case FOURCC_YUY2: default: - accel_state->src_mc_addr[0] = pPriv->src_offset; + accel_state->src_mc_addr[0] = pPriv->src_offset + info->fbLocation + pScrn->fbOffset; accel_state->src_size[0] = accel_state->src_pitch[0] * pPriv->h; /* flush texture cache */ diff -up xf86-video-ati-6.12.2/src/radeon_accel.c.modeset xf86-video-ati-6.12.2/src/radeon_accel.c --- xf86-video-ati-6.12.2/src/radeon_accel.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_accel.c 2009-05-21 11:03:18.000000000 -0400 @@ -94,6 +94,7 @@ /* X and server generic header files */ #include "xf86.h" +#include "radeon_bufmgr_gem.h" static void R600EngineReset(ScrnInfoPtr pScrn); @@ -375,6 +376,9 @@ void RADEONEngineRestore(ScrnInfoPtr pSc 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, @@ -435,8 +439,8 @@ void RADEONEngineInit(ScrnInfoPtr pScrn) info->CurrentLayout.bitsPerPixel); #ifdef XF86DRI - if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) { - drm_radeon_getparam_t np; + if ((info->directRenderingEnabled || info->drm_mode_setting) && (IS_R300_3D || IS_R500_3D)) { + drm_radeon_getparam_t np; int num_pipes; memset(&np, 0, sizeof(np)); @@ -455,64 +459,66 @@ 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->accel_state->num_gb_pipes == 0) { - uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); - - info->accel_state->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->accel_state->num_gb_pipes == 0) { - if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_R350)) { - /* R3xx chips */ - info->accel_state->num_gb_pipes = 2; - } else { - /* RV3xx chips */ - info->accel_state->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->accel_state->num_gb_pipes == 0) { + uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT); + + info->accel_state->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->accel_state->num_gb_pipes == 0) { + if ((info->ChipFamily == CHIP_FAMILY_R300) || + (info->ChipFamily == CHIP_FAMILY_R350)) { + /* R3xx chips */ + info->accel_state->num_gb_pipes = 2; + } else { + /* RV3xx chips */ + info->accel_state->num_gb_pipes = 1; + } } } - } - /* RV410 SE cards only have 1 quadpipe */ - if ((info->Chipset == PCI_CHIP_RV410_5E4C) || - (info->Chipset == PCI_CHIP_RV410_5E4F)) - info->accel_state->num_gb_pipes = 1; - - if (IS_R300_3D || IS_R500_3D) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "num quad-pipes is %d\n", info->accel_state->num_gb_pipes); - - if (IS_R300_3D || IS_R500_3D) { - uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); - - switch(info->accel_state->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); + /* RV410 SE cards only have 1 quadpipe */ + if ((info->Chipset == PCI_CHIP_RV410_5E4C) || + (info->Chipset == PCI_CHIP_RV410_5E4F)) + info->accel_state->num_gb_pipes = 1; + + if (IS_R300_3D || IS_R500_3D) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "num quad-pipes is %d\n", info->accel_state->num_gb_pipes); + + if (IS_R300_3D || IS_R500_3D) { + uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); + + switch(info->accel_state->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); + RADEONEngineReset(pScrn); + } switch (info->CurrentLayout.pixel_code) { case 8: datatype = 2; break; @@ -620,6 +626,119 @@ int RADEONCPStop(ScrnInfoPtr pScrn, RADE } } +#define RADEON_IB_RESERVE (16 * sizeof(uint32_t)) +drmBufPtr RADEONCSGetBuffer(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + info->cp->relocs.size = getpagesize(); + info->cp->relocs.num_reloc = 0; + info->cp->relocs.max_bo = info->cp->relocs.size / RADEON_RELOC_SIZE; + info->cp->relocs.buf = xcalloc(1, info->cp->relocs.size); + if (!info->cp->relocs.buf) + return NULL; + + info->cp->relocs.bo_list = xcalloc(info->cp->relocs.max_bo, sizeof(dri_bo *)); + if (!info->cp->relocs.bo_list) { + xfree(info->cp->relocs.buf); + return NULL; + } + + info->cp->ib_gem_fake.address = xcalloc(1, RADEON_BUFFER_SIZE); + if (!info->cp->ib_gem_fake.address) { + xfree(info->cp->relocs.buf); + xfree(info->cp->relocs.bo_list); + return NULL; + } + + + info->cp->ib_gem_fake.used = 0; + info->cp->ib_gem_fake.total = RADEON_BUFFER_SIZE - RADEON_IB_RESERVE; // reserve 16 dwords + return &info->cp->ib_gem_fake; +} + +void RADEONCSFlushIndirect(ScrnInfoPtr pScrn, int discard) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + struct drm_radeon_cs args; + struct drm_radeon_cs_chunk chunk[2]; + uint64_t chunk_array[2]; + int retry = 0; + int ret; + RING_LOCALS; + + if (info->cp->indirectBuffer->used == 0) + return; + + /* always add the cache flushes to the end of the IB */ + info->cp->indirectBuffer->total += RADEON_IB_RESERVE; + + /* end of IB purge caches */ + if (info->cs_used_depth) { + RADEON_PURGE_ZCACHE(); + info->cs_used_depth = 0; + } + + chunk[0].chunk_data = (unsigned long)info->cp->ib_gem_fake.address; + chunk[0].length_dw = info->cp->indirectBuffer->used / sizeof(uint32_t); + chunk[0].chunk_id = RADEON_CHUNK_ID_IB; + + chunk[1].chunk_data = (unsigned long)info->cp->relocs.buf; + chunk[1].length_dw = info->cp->relocs.num_reloc * RADEON_RELOC_SIZE; + chunk[1].chunk_id = RADEON_CHUNK_ID_RELOCS; + + chunk_array[0] = (uint64_t)(unsigned long)&chunk[0]; + chunk_array[1] = (uint64_t)(unsigned long)&chunk[1]; + + args.num_chunks = 2; + args.chunks = (uint64_t)(unsigned long)chunk_array; + + do { + ret = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_CS, + &args, sizeof(args)); + retry++; + } while (ret == -EAGAIN && retry < 1000); + if (ret) { + /* submit failed */ + ErrorF("RADEON DRM CS failure - corruptions/glitches may occur %d\n", ret); + } + + + info->cp->indirectStart = 0; + info->cp->indirectBuffer->used = 0; + info->cp->indirectBuffer->total -= RADEON_IB_RESERVE; + + if (info->bufmgr) + radeon_gem_bufmgr_post_submit(info->bufmgr, &info->cp->relocs, ret); + + info->cp->relocs.num_reloc = 0; + /* 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); + if (info->dri2.enabled) { + info->accel_state->XInited3D = FALSE; + info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; + } +} + +void RADEONCSReleaseIndirect(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!info->cp->indirectBuffer) return; + RADEONCSFlushIndirect(pScrn, 0); + xfree(info->cp->relocs.buf); + xfree(info->cp->relocs.bo_list); + info->cp->relocs.buf = 0; + info->cp->relocs.size = 0; + info->cp->relocs.num_reloc = 0; + xfree(info->cp->ib_gem_fake.address); + info->cp->ib_gem_fake.address = NULL; + info->cp->indirectBuffer = NULL; + +} + /* Get an indirect buffer for the CP 2D acceleration commands */ drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn) { @@ -630,6 +749,9 @@ drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr 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 @@ -699,6 +821,11 @@ void RADEONCPFlushIndirect(ScrnInfoPtr p 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); @@ -757,10 +884,16 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr } } + if (info->new_cs) { + RADEONCSReleaseIndirect(pScrn); + return; + } + info->cp->indirectBuffer = NULL; info->cp->indirectStart = 0; if (!buffer) return; + if (RADEON_VERBOSE) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Releasing buffer %d\n", @@ -887,6 +1020,7 @@ RADEONHostDataBlit( ret = ( uint8_t* )&__head[__count]; __count += dwords; + ADVANCE_RING(); *y += *hpass; @@ -1021,7 +1155,7 @@ Bool RADEONAccelInit(ScreenPtr pScreen) #ifdef USE_EXA if (info->useEXA) { # ifdef XF86DRI - if (info->directRenderingEnabled) { + if (info->directRenderingEnabled || info->drm_mode_setting) { if (info->ChipFamily >= CHIP_FAMILY_R600) { if (!R600DrawInit(pScreen)) return FALSE; @@ -1054,7 +1188,7 @@ Bool RADEONAccelInit(ScreenPtr pScreen) } #ifdef XF86DRI - if (info->directRenderingEnabled) + if (info->directRenderingEnabled || info->drm_mode_setting) RADEONAccelInitCP(pScreen, a); else #endif /* XF86DRI */ @@ -1076,11 +1210,13 @@ void RADEONInit3DEngine(ScrnInfoPtr pScr RADEONInfoPtr info = RADEONPTR (pScrn); #ifdef XF86DRI - if (info->directRenderingEnabled) { - drm_radeon_sarea_t *pSAREAPriv; + if (info->directRenderingEnabled || info->drm_mode_setting) { + if (info->directRenderingEnabled && !info->dri2.enabled) { + drm_radeon_sarea_t *pSAREAPriv; - pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); - pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen); + pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen); + } RADEONInit3DEngineCP(pScrn); } else #endif @@ -1088,7 +1224,7 @@ void RADEONInit3DEngine(ScrnInfoPtr pScr info->accel_state->XInited3D = TRUE; } - + #ifdef USE_XAA #ifdef XF86DRI Bool diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_bufmgr_gem.c --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_bufmgr_gem.c 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,639 @@ +/************************************************************************** + * + * 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 + * Keith Whitwell + * Eric Anholt + * Dave Airlie + * Kristian Høgsberg + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xf86.h" +#include "errno.h" +#include "string.h" + +#include "radeon_reg.h" +#include "radeon_probe.h" +#include "radeon.h" +#include "radeon_bufmgr.h" +#include "radeon_drm.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; + int in_vram; /* have we migrated this bo to VRAM ever */ + int force_gtt; + int pinned; + int touched; + void *priv_map; + uint32_t space_accounted; +} dri_bo_gem; + +typedef struct _dri_bufmgr_gem { + dri_bufmgr bufmgr; + struct radeon_bufmgr radeon_bufmgr; + int fd; + uint32_t vram_limit, gart_limit; + uint32_t vram_write_used, gart_write_used; + uint32_t read_used; + + struct _dri_bo_gem *bo_list; +} dri_bufmgr_gem; + +static dri_bo * +dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, uint64_t location_mask) + +{ + dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr; + struct drm_radeon_gem_create args; + int ret; + dri_bo_gem *gem_bo; + + gem_bo = calloc(1, sizeof(*gem_bo)); + if (!gem_bo) + return NULL; + + gem_bo->bo.size = size; + args.size = size; + args.alignment = alignment; + args.initial_domain = RADEON_GEM_DOMAIN_CPU; + args.flags = 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 = strdup(name); + gem_bo->touched = 0; + + gem_bo->next = bufmgr_gem->bo_list; + bufmgr_gem->bo_list = gem_bo; + + DBG("bo_create: buf %d (%s) %ldb\n", + gem_bo->gem_handle, gem_bo->name, size); + + 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, *trav, *prev; + struct drm_gem_close args; + + if (gem_bo->priv_map) + munmap(gem_bo->priv_map, gem_bo->bo.size); + + /* close object */ + args.handle = gem_bo->gem_handle; + ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &args); + + if (gem_bo == bufmgr_gem->bo_list) + bufmgr_gem->bo_list = gem_bo->next; + else { + prev = trav = bufmgr_gem->bo_list; + while (trav) { + if (trav == gem_bo) { + if (prev) + prev->next = trav->next; + break; + } + prev = trav; + trav = trav->next; + } + } + free(gem_bo->name); + 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) { + 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 = 0; + void *ptr; + + if (gem_bo->map_count++ != 0) + return 0; + + if (!gem_bo->priv_map) { + 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) + return ret; + + ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, bufmgr_gem->fd, args.addr_ptr); + if (ptr == MAP_FAILED) + return -errno; + gem_bo->priv_map = ptr; + } + + gem_bo->bo.virtual = gem_bo->priv_map; + + return ret; +} + +static int +dri_gem_bo_unmap(dri_bo *buf) +{ + dri_bo_gem *gem_bo = (dri_bo_gem *)buf; + + if (--gem_bo->map_count > 0) + return 0; + + gem_bo->bo.virtual = NULL; + return 0; +} + +static void +dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr) +{ + 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_wait_idle args; + struct drm_radeon_gem_set_domain sd_args; + dri_bo_gem *gem_bo = (dri_bo_gem *)buf; + int ret; + + if (!gem_bo->touched) + return; + + /* do a set domain */ + if (gem_bo->force_gtt) { + sd_args.handle = gem_bo->gem_handle; + sd_args.read_domains = RADEON_GEM_DOMAIN_GTT; + sd_args.write_domain = 0; + + ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_SET_DOMAIN, + &sd_args, sizeof(sd_args)); + + } else { + args.handle = gem_bo->gem_handle; + + do { + ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_WAIT_IDLE, + &args, sizeof(args)); + } while (ret == -EBUSY); + } + return; +} + +dri_bo * +radeon_bo_gem_create_from_handle(dri_bufmgr *bufmgr, + uint32_t handle, unsigned long size) +{ + dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr; + dri_bo_gem *bo_gem; + char name[32]; + + sprintf(name, "handle:%8x", handle); + bo_gem = calloc(1, sizeof(*bo_gem)); + if (!bo_gem) + return NULL; + + bo_gem->bo.size = size; + bo_gem->bo.offset = 0; + bo_gem->bo.virtual = NULL; + bo_gem->bo.bufmgr = bufmgr; + bo_gem->name = strdup(name); + bo_gem->refcount = 1; + bo_gem->pinned = 1; + bo_gem->gem_handle = handle; + bo_gem->in_vram = 1; + /* if we get from kernel assume touched */ + bo_gem->touched = 1; + + bo_gem->next = bufmgr_gem->bo_list; + bufmgr_gem->bo_list = bo_gem; + return &bo_gem->bo; +} + +/** + * 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; + int ret; + struct drm_gem_open open_arg; + + 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)); + return NULL; + } + + return radeon_bo_gem_create_from_handle(bufmgr, + open_arg.handle, open_arg.size); +} + +#define BUF_OUT_RING(x) do { \ + __head[__count++] = (x); \ + } while (0) + +void radeon_bufmgr_gem_emit_reloc(dri_bo *buf, struct radeon_relocs_info *reloc_info, 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; + int i; + int index; + int have_reloc = -1; + + for (i = 0; i < reloc_info->num_reloc; i++) { + if (reloc_info->buf[i * 4] == gem_bo->gem_handle) { + have_reloc = i; + break; + } + } + + if (gem_bo->force_gtt && (read_domains & RADEON_GEM_DOMAIN_VRAM)) + read_domains = RADEON_GEM_DOMAIN_GTT; + + if (have_reloc != -1) { + uint32_t old_write, old_read; + + index = have_reloc * 4; + old_read = reloc_info->buf[index + 1]; + old_write = reloc_info->buf[index + 2]; + + /* error up for now - work out new domains - if we have a write */ + if (write_domain && (old_read & write_domain)) { + reloc_info->buf[index + 1] = 0; + reloc_info->buf[index + 2] = write_domain; + } else if (read_domains & old_write) { + reloc_info->buf[index + 1] = 0; + } else { + /* rewrite the domains */ + if (write_domain != old_write) + ErrorF("WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, write_domain, old_write); + if (read_domains != old_read) + ErrorF("READ DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, read_domains, old_read); + } + reloc_info->buf[index + 3]++; + + } else { + + if ((reloc_info->num_reloc + 1) * RADEON_RELOC_SIZE > reloc_info->size) { + /* resize the buffer */ + reloc_info->size += getpagesize(); + reloc_info->buf = xrealloc(reloc_info->buf, reloc_info->size); + if (!reloc_info->buf) + FatalError("failed to increase reloc buffer size\n"); + reloc_info->max_bo = reloc_info->size / RADEON_RELOC_SIZE; + reloc_info->bo_list = xrealloc(reloc_info->bo_list, reloc_info->max_bo * (sizeof(dri_bo *))); + } + + dri_bo_reference(buf); + gem_bo->touched = 1; + + index = reloc_info->num_reloc * 4; + reloc_info->bo_list[index/4] = buf; + reloc_info->buf[index] = gem_bo->gem_handle; + reloc_info->buf[index + 1] = read_domains; + reloc_info->buf[index + 2] = write_domain; + reloc_info->buf[index + 3] = 1; + reloc_info->num_reloc++; + } + + 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; + } + + BUF_OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 0)); + BUF_OUT_RING(index); + *count_p = __count; +} + +static uint32_t radeon_gem_bufmgr_get_handle(dri_bo *buf) +{ + dri_bo_gem *gem_bo = (dri_bo_gem *)buf; + + return gem_bo->gem_handle; +} + +static int radeon_gem_bufmgr_check_aperture_space(struct radeon_space_check *bos, int num_bo) +{ + dri_bufmgr_gem *bufmgr_gem; + dri_bo_gem *gem_bo; + dri_bo *buf; + int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0; + uint32_t read_domains, write_domain; + int i; + /* check the totals for this operation */ + + if (num_bo == 0) + return 0; + + bufmgr_gem = (dri_bufmgr_gem *)bos[0].buf->bufmgr; + + /* prepare */ + for (i = 0; i < num_bo; i++) { + buf = bos[i].buf; + gem_bo = (dri_bo_gem *)buf; + + bos[i].new_accounted = 0; + read_domains = bos[i].read_domains; + write_domain = bos[i].write_domain; + + /* pinned bos don't count */ + if (gem_bo->pinned) + continue; + + /* already accounted this bo */ + if (write_domain && (write_domain == gem_bo->space_accounted)) + continue; + + if (read_domains && ((read_domains << 16) == gem_bo->space_accounted)) + continue; + + if (gem_bo->space_accounted == 0) { + if (write_domain == RADEON_GEM_DOMAIN_VRAM) + this_op_vram_write += buf->size; + else if (write_domain == RADEON_GEM_DOMAIN_GTT) + this_op_gart_write += buf->size; + else + this_op_read += buf->size; + bos[i].new_accounted = (read_domains << 16) | write_domain; + } else { + uint16_t old_read, old_write; + + old_read = gem_bo->space_accounted >> 16; + old_write = gem_bo->space_accounted & 0xffff; + + if (write_domain && (old_read & write_domain)) { + bos[i].new_accounted = write_domain; + /* moving from read to a write domain */ + if (write_domain == RADEON_GEM_DOMAIN_VRAM) { + this_op_read -= buf->size; + this_op_vram_write += buf->size; + } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) { + this_op_read -= buf->size; + this_op_gart_write += buf->size; + } + } else if (read_domains & old_write) { + bos[i].new_accounted = gem_bo->space_accounted & 0xffff; + } else { + /* rewrite the domains */ + if (write_domain != old_write) + ErrorF("WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, write_domain, old_write); + if (read_domains != old_read) + ErrorF("READ DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, read_domains, old_read); + return BUFMGR_SPACE_FLUSH; + } + } + } + + if (this_op_read < 0) + this_op_read = 0; + + /* check sizes - operation first */ + if ((this_op_read + this_op_gart_write > bufmgr_gem->gart_limit) || + (this_op_vram_write > bufmgr_gem->vram_limit)) { + return BUFMGR_SPACE_OP_TO_BIG; + } + + if (((bufmgr_gem->vram_write_used + this_op_vram_write) > bufmgr_gem->vram_limit) || + ((bufmgr_gem->read_used + bufmgr_gem->gart_write_used + this_op_gart_write + this_op_read) > bufmgr_gem->gart_limit)) { + return BUFMGR_SPACE_FLUSH; + } + + bufmgr_gem->gart_write_used += this_op_gart_write; + bufmgr_gem->vram_write_used += this_op_vram_write; + bufmgr_gem->read_used += this_op_read; + /* commit */ + for (i = 0; i < num_bo; i++) { + buf = bos[i].buf; + gem_bo = (dri_bo_gem *)buf; + gem_bo->space_accounted = bos[i].new_accounted; + } + + return BUFMGR_SPACE_OK; +} + +/** + * 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; + + 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; + bufmgr_gem->bufmgr.get_handle = radeon_gem_bufmgr_get_handle; + bufmgr_gem->bufmgr.check_aperture_space = radeon_gem_bufmgr_check_aperture_space; + bufmgr_gem->bufmgr.debug = 0; + return &bufmgr_gem->bufmgr; +} + + +void radeon_gem_bufmgr_post_submit(dri_bufmgr *bufmgr, struct radeon_relocs_info *reloc_info, int error) +{ + dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr; + struct _dri_bo_gem *trav, *prev; + int i; + + if (error) { + ErrorF("bufmgr: last submission : r:%d vs g:%d w:%d vs v:%d\n", + bufmgr_gem->read_used, bufmgr_gem->gart_limit, + bufmgr_gem->vram_write_used, bufmgr_gem->vram_limit); + } + + if (!bufmgr_gem->bo_list) + return; + + for (i = 0; i < reloc_info->num_reloc; i++) { + trav = (dri_bo_gem *)reloc_info->bo_list[i]; + + trav->space_accounted = 0; + dri_bo_unreference(&trav->bo); + } + + bufmgr_gem->read_used = 0; + bufmgr_gem->vram_write_used = 0; + bufmgr_gem->gart_write_used = 0; + +} + + + +void radeon_bufmgr_emit_reloc(dri_bo *buf, struct radeon_relocs_info *relocs, 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, relocs, head, count_p, read_domains, write_domain); +} + +/* if the buffer is references by the current IB we need to flush the IB */ +int radeon_bufmgr_gem_has_references(dri_bo *buf) +{ + dri_bo_gem *gem_bo = (dri_bo_gem *)buf; + + return gem_bo->touched; +} + +void radeon_bufmgr_gem_set_limit(dri_bufmgr *bufmgr, uint32_t domain, uint32_t limit) +{ + dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr; + + if (domain == RADEON_GEM_DOMAIN_VRAM) + bufmgr_gem->vram_limit = limit; + else + bufmgr_gem->gart_limit = limit; + +} + +void radeon_bufmgr_gem_force_gtt(dri_bo *buf) +{ + dri_bo_gem *gem_bo = (dri_bo_gem *)buf; + + if (!gem_bo->pinned && !gem_bo->force_gtt) + gem_bo->force_gtt = 1; +} + +int radeon_bufmgr_gem_in_vram(dri_bo *buf) +{ + dri_bo_gem *gem_bo = (dri_bo_gem *)buf; + return gem_bo->in_vram; +} + +int radeon_bo_gem_name_buffer(dri_bo *bo, uint32_t *name) +{ + dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; + dri_bo_gem *gem_bo = (dri_bo_gem *)bo; + struct drm_gem_flink flink; + int r; + + flink.handle = gem_bo->gem_handle; + fprintf(stderr,"naming attemp %d\n", flink.handle); + r = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink); + if (r) { + DBG("[drm] failed to name buffer %d\n", -errno); + return r; + } + fprintf(stderr,"naming %d with %d\n", flink.handle, flink.name); + *name = flink.name; + return 0; +} diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_bufmgr_gem.h --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_bufmgr_gem.h 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,16 @@ +#ifndef RADEON_BUFMGR_GEM_H +#define RADEON_BUFMGR_GEM_H + +#include "radeon_dri_bufmgr.h" + + +extern void radeon_bufmgr_gem_wait_rendering(dri_bo *bo); +void radeon_bufmgr_gem_emit_reloc(dri_bo *bo, struct radeon_relocs_info *reloc_info, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain); +void radeon_gem_bufmgr_post_submit(dri_bufmgr *bufmgr, struct radeon_relocs_info *reloc_info, int error); +uint32_t radeon_bufmgr_get_handle(dri_bo *buf); +int radeon_bufmgr_gem_has_references(dri_bo *buf); +int radeon_bufmgr_gem_force_gtt(dri_bo *buf); +void radeon_bufmgr_gem_set_limit(dri_bufmgr *bufmgr, uint32_t domain, uint32_t limit); +int radeon_bufmgr_gem_in_vram(dri_bo *buf); +int radeon_bo_gem_name_buffer(dri_bo *bo, uint32_t *name); +#endif diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_bufmgr.h --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_bufmgr.h 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,25 @@ +/** + * @file intel_bufmgr.h + * + * Public definitions of Intel-specific bufmgr functions. + */ + +#ifndef RADEON_BUFMGR_H +#define RADEON_BUFMGR_H + +#include "radeon_dri_bufmgr.h" + +struct radeon_bufmgr { + void (*emit_reloc)(dri_bo *buf, struct radeon_relocs_info *relocs, 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); +dri_bo *radeon_bo_gem_create_from_handle(dri_bufmgr *bufmgr, + uint32_t handle, unsigned long size); + +void radeon_bufmgr_emit_reloc(dri_bo *buf, struct radeon_relocs_info *relocs, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain); + +void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr); +#endif diff -up xf86-video-ati-6.12.2/src/radeon_commonfuncs.c.modeset xf86-video-ati-6.12.2/src/radeon_commonfuncs.c --- xf86-video-ati-6.12.2/src/radeon_commonfuncs.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_commonfuncs.c 2009-05-21 11:05:44.000000000 -0400 @@ -62,12 +62,15 @@ static void FUNC_NAME(RADEONInit3DEngine info->accel_state->texW[1] = info->accel_state->texH[1] = 1; if (IS_R300_3D || IS_R500_3D) { + int size; - 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); @@ -79,10 +82,12 @@ static void FUNC_NAME(RADEONInit3DEngine case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; } - BEGIN_ACCEL(5); + size = (info->ChipFamily >= CHIP_FAMILY_R420) ? 5 : 4; + BEGIN_ACCEL(size); OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG); + if (info->ChipFamily >= CHIP_FAMILY_R420) + OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG); OUT_ACCEL_REG(R300_GB_SELECT, 0); OUT_ACCEL_REG(R300_GB_ENABLE, 0); FINISH_ACCEL(); @@ -626,6 +631,39 @@ static void FUNC_NAME(RADEONInit3DEngine } +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) +void drmmode_wait_for_vline(ScrnInfoPtr pScrn, PixmapPtr pPix, + int crtc, int start, int stop) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + uint32_t offset; + drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[crtc]->driver_private; + ACCEL_PREAMBLE(); + + BEGIN_ACCEL(3); + + if (IS_AVIVO_VARIANT) { + uint32_t reg = AVIVO_D1MODE_VLINE_START_END; /* this is just a marker */ + OUT_ACCEL_REG(reg, + ((start << AVIVO_D1MODE_VLINE_START_SHIFT) | + (stop << AVIVO_D1MODE_VLINE_END_SHIFT) | + AVIVO_D1MODE_VLINE_INV)); + } else { + OUT_ACCEL_REG(RADEON_CRTC_GUI_TRIG_VLINE, /* another placeholder */ + ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) | + (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) | + RADEON_CRTC_GUI_TRIG_VLINE_INV)); + } + OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE | + RADEON_ENG_DISPLAY_SELECT_CRTC0)); + + OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 0)); + OUT_RING(drmmode_crtc->mode_crtc->crtc_id); + FINISH_ACCEL(); +} +#endif + /* inserts a wait for vline in the command stream */ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix, int crtc, int start, int stop) @@ -644,16 +682,19 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnI if (!xf86_config->crtc[crtc]->enabled) return; + if (info->drm_mode_setting) { + if (pPix != pScrn->pScreen->GetScreenPixmap(pScrn->pScreen)) + return; + } else { + if (info->useEXA) #ifdef USE_EXA - if (info->useEXA) - offset = exaGetPixmapOffset(pPix); - else + offset = exaGetPixmapOffset(pPix); + else #endif - offset = pPix->devPrivate.ptr - info->FB; - - /* if drawing to front buffer */ - if (offset != 0) - return; + offset = pPix->devPrivate.ptr - info->FB; + if (offset != 0) + return; + } start = max(start, 0); stop = min(stop, xf86_config->crtc[crtc]->mode.VDisplay); @@ -661,6 +702,13 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnI if (start > xf86_config->crtc[crtc]->mode.VDisplay) return; +#if defined(ACCEL_CP) && defined(XF86DRM_MODE) + if (info->drm_mode_setting) { + drmmode_wait_for_vline(pScrn, pPix, crtc, start, stop); + return; + } +#endif + BEGIN_ACCEL(2); if (IS_AVIVO_VARIANT) { @@ -712,7 +760,7 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnIn #ifdef ACCEL_CP /* Make sure the CP is idle first */ - if (info->cp->CPStarted) { + if (info->cp->CPStarted || info->drm_mode_setting) { int ret; FLUSH_RING(); diff -up xf86-video-ati-6.12.2/src/radeon_cursor.c.modeset xf86-video-ati-6.12.2/src/radeon_cursor.c --- xf86-video-ati-6.12.2/src/radeon_cursor.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_cursor.c 2009-05-21 11:01:45.000000000 -0400 @@ -202,6 +202,7 @@ radeon_crtc_set_cursor_position (xf86Crt 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; @@ -255,8 +256,9 @@ radeon_crtc_set_cursor_position (xf86Crt | (yorigin ? 0 : y))); RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n", radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); + 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) @@ -266,8 +268,9 @@ radeon_crtc_set_cursor_position (xf86Crt | (yorigin ? 0 : y))); RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n", radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); + offset = radeon_crtc->cursor_offset + pScrn->fbOffset; OUTREG(RADEON_CUR2_OFFSET, - radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride); + offset + yorigin * stride); } } } @@ -321,10 +324,12 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt 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")); + d = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset); + info->cursor_argb = TRUE; CURSOR_SWAPPING_START(); diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_dri2.c --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_dri2.c 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,224 @@ +/* + * Copyright 2008 Kristian Høgsberg + * Copyright 2008 Jérôme Glisse + * + * 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 on 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + * THEIR 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. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "radeon.h" +#include "radeon_dri2.h" +#include "radeon_version.h" + +#ifdef DRI2 + +struct dri2_buffer_priv { + PixmapPtr pixmap; +}; + + +static DRI2BufferPtr +radeon_dri2_create_buffers(DrawablePtr drawable, + unsigned int *attachments, + int count) +{ + ScreenPtr pScreen = drawable->pScreen; + DRI2BufferPtr buffers; + struct dri2_buffer_priv *privates; + PixmapPtr pixmap, depth_pixmap; + struct radeon_exa_pixmap_priv *driver_priv; + int i, r; + + buffers = xcalloc(count, sizeof *buffers); + if (buffers == NULL) { + return NULL; + } + privates = xcalloc(count, sizeof(struct dri2_buffer_priv)); + if (privates == NULL) { + xfree(buffers); + return NULL; + } + + depth_pixmap = NULL; + for (i = 0; i < count; i++) { + if (attachments[i] == DRI2BufferFrontLeft) { + if (drawable->type == DRAWABLE_PIXMAP) { + pixmap = (Pixmap*)drawable; + } else { + pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable); + } + pixmap->refcnt++; + } else if (attachments[i] == DRI2BufferStencil && depth_pixmap) { + pixmap = depth_pixmap; + pixmap->refcnt++; + } else { + pixmap = (*pScreen->CreatePixmap)(pScreen, + drawable->width, + drawable->height, + drawable->depth, + 0); + } + + if (attachments[i] == DRI2BufferDepth) { + depth_pixmap = pixmap; + } + driver_priv = exaGetPixmapDriverPrivate(pixmap); + r = radeon_bo_gem_name_buffer(driver_priv->bo, &buffers[i].name); + if (r) { + /* FIXME: cleanup */ + fprintf(stderr, "flink error: %d %s\n", r, strerror(r)); + xfree(buffers); + xfree(privates); + return NULL; + } + buffers[i].attachment = attachments[i]; + buffers[i].pitch = pixmap->devKind; + buffers[i].cpp = pixmap->drawable.bitsPerPixel / 8; + buffers[i].driverPrivate = &privates[i]; + buffers[i].flags = 0; /* not tiled */ + privates[i].pixmap = pixmap; + } + return buffers; +} + +static void +radeon_dri2_destroy_buffers(DrawablePtr drawable, + DRI2BufferPtr buffers, + int count) +{ + ScreenPtr pScreen = drawable->pScreen; + struct dri2_buffer_priv *private; + int i; + + for (i = 0; i < count; i++) { + private = buffers[i].driverPrivate; + (*pScreen->DestroyPixmap)(private->pixmap); + } + if (buffers) { + xfree(buffers[0].driverPrivate); + xfree(buffers); + } +} + +static void +radeon_dri2_copy_region(DrawablePtr drawable, + RegionPtr region, + DRI2BufferPtr dest_buffer, + DRI2BufferPtr src_buffer) +{ + struct dri2_buffer_priv *private = src_buffer->driverPrivate; + ScreenPtr pScreen = drawable->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + PixmapPtr pixmap = private->pixmap; + RegionPtr copy_clip; + GCPtr gc; + + gc = GetScratchGC(drawable->depth, pScreen); + copy_clip = REGION_CREATE(pScreen, NULL, 0); + REGION_COPY(pScreen, copy_clip, region); + (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); + ValidateGC(drawable, gc); + (*gc->ops->CopyArea)(&pixmap->drawable, drawable, gc, + 0, 0, drawable->width, drawable->height, 0, 0); + FreeScratchGC(gc); + RADEONCPReleaseIndirect(pScrn); +} + +Bool +radeon_dri2_screen_init(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + DRI2InfoRec dri2_info; + int fd; + char *bus_id; + char *tmp_bus_id; + int cmp; + int i; + + if (!info->useEXA) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requires EXA\n"); + return FALSE; + } + + /* The whole drmOpen thing is a fiasco and we need to find a way + * back to just using open(2). For now, however, lets just make + * things worse with even more ad hoc directory walking code to + * discover the device file name. */ + bus_id = DRICreatePCIBusID(info->PciInfo); + for (i = 0; i < DRM_MAX_MINOR; i++) { + sprintf(info->dri2.device_name, DRM_DEV_NAME, DRM_DIR_NAME, i); + fd = open(info->dri2.device_name, O_RDWR); + if (fd < 0) + continue; + + tmp_bus_id = drmGetBusid(fd); + close(fd); + if (tmp_bus_id == NULL) + continue; + + cmp = strcmp(tmp_bus_id, bus_id); + drmFree(tmp_bus_id); + if (cmp == 0) + break; + } + xfree(bus_id); + + if (i == DRM_MAX_MINOR) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "DRI2: failed to open drm device\n"); + return FALSE; + } + + if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) { + dri2_info.driverName = R300_DRIVER_NAME; + } else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) { + dri2_info.driverName = R200_DRIVER_NAME; + } else { + dri2_info.driverName = RADEON_DRIVER_NAME; + } + dri2_info.fd = info->dri2.drm_fd; + dri2_info.deviceName = info->dri2.device_name; + dri2_info.version = 1; + dri2_info.CreateBuffers = radeon_dri2_create_buffers; + dri2_info.DestroyBuffers = radeon_dri2_destroy_buffers; + dri2_info.CopyRegion = radeon_dri2_copy_region; + info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); + return info->dri2.enabled; +} + +void +radeon_dri2_close_screen(ScreenPtr pScreen) +{ + DRI2CloseScreen(pScreen); +} + +#endif diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_dri2.h --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_dri2.h 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,42 @@ +/* + * Copyright 2008 Jerome Glisse + * + * 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 on 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + * THEIR 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. + */ +#ifndef RADEON_DRI2_H +#define RADEON_DRI2_H + +struct radeon_dri2 { + int drm_fd; + Bool enabled; + char device_name[64]; +}; + +#ifdef DRI2 +#include "dri2.h" +Bool radeon_dri2_screen_init(ScreenPtr pScreen); +void radeon_dri2_close_screen(ScreenPtr pScreen); +#endif + +#endif diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_dri_bufmgr.c --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_dri_bufmgr.c 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,177 @@ +/* + * Copyright © 2007 Intel Corporation + * + * 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: + * Eric Anholt + * + */ + +#include +#include +#include +#include "radeon_dri_bufmgr.h" + +/** @file dri_bufmgr.c + * + * Convenience functions for buffer management methods. + */ + +dri_bo * +dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, + unsigned int alignment, uint64_t location_mask) +{ + return bufmgr->bo_alloc(bufmgr, name, size, alignment, location_mask); +} + +dri_bo * +dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, + unsigned long size, void *virtual, + uint64_t location_mask) +{ + return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, + location_mask); +} + +void +dri_bo_reference(dri_bo *bo) +{ + bo->bufmgr->bo_reference(bo); +} + +void +dri_bo_unreference(dri_bo *bo) +{ + if (bo == NULL) + return; + + bo->bufmgr->bo_unreference(bo); +} + +int +dri_bo_map(dri_bo *buf, int write_enable) +{ + return buf->bufmgr->bo_map(buf, write_enable); +} + +int +dri_bo_unmap(dri_bo *buf) +{ + return buf->bufmgr->bo_unmap(buf); +} + +void +dri_fence_wait(dri_fence *fence) +{ + fence->bufmgr->fence_wait(fence); +} + +void +dri_fence_reference(dri_fence *fence) +{ + fence->bufmgr->fence_reference(fence); +} + +void +dri_fence_unreference(dri_fence *fence) +{ + if (fence == NULL) + return; + + fence->bufmgr->fence_unreference(fence); +} + +void +dri_bo_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, const void *data) +{ + if (size == 0 || data == NULL) + return; + + dri_bo_map(bo, 1); + memcpy((unsigned char *)bo->virtual + offset, data, size); + dri_bo_unmap(bo); +} + +void +dri_bo_get_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, void *data) +{ + if (size == 0 || data == NULL) + return; + + dri_bo_map(bo, 0); + memcpy(data, (unsigned char *)bo->virtual + offset, size); + dri_bo_unmap(bo); +} + +void +dri_bufmgr_destroy(dri_bufmgr *bufmgr) +{ + bufmgr->destroy(bufmgr); +} + + +int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, uint32_t delta, + uint32_t offset, dri_bo *target_buf) +{ + return reloc_buf->bufmgr->emit_reloc(reloc_buf, flags, delta, offset, target_buf); +} + +void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count) +{ + return batch_buf->bufmgr->process_relocs(batch_buf, count); +} + +void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence) +{ + batch_buf->bufmgr->post_submit(batch_buf, last_fence); +} + +void +dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug) +{ + bufmgr->debug = enable_debug; +} + +int +dri_bufmgr_check_aperture_space(struct radeon_space_check *bos, int num_bo) +{ + if (num_bo == 0) + return BUFMGR_SPACE_OK; + + return bos[0].buf->bufmgr->check_aperture_space(bos, num_bo); +} + +int dri_bo_pin(dri_bo *bo, int domain) +{ + return bo->bufmgr->pin(bo, domain); +} + +void dri_bo_unpin(dri_bo *bo) +{ + bo->bufmgr->unpin(bo); +} + +uint32_t dri_bo_get_handle(dri_bo *bo) +{ + return bo->bufmgr->get_handle(bo); +} diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_dri_bufmgr.h --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_dri_bufmgr.h 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,291 @@ +/************************************************************************** + * + * 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 + * Keith Whitwell + * Eric Anholt + */ + +#ifndef _DRI_BUFMGR_H_ +#define _DRI_BUFMGR_H_ +#include + +typedef struct _dri_bufmgr dri_bufmgr; +typedef struct _dri_bo dri_bo; +typedef struct _dri_fence dri_fence; + +#define BUFMGR_SPACE_OK 0 +#define BUFMGR_SPACE_OP_TO_BIG 1 +#define BUFMGR_SPACE_FLUSH 2 +struct radeon_space_check { + dri_bo *buf; + uint32_t read_domains; + uint32_t write_domain; + uint32_t new_accounted; +}; + +/* reloc format */ +/* gem handle, read_domains, write_domain, reloc_count */ +#define RADEON_RELOC_SIZE 4 +struct radeon_relocs_info { + uint32_t *buf; + dri_bo **bo_list; + int size; + int max_bo; + int num_reloc; +}; + +struct _dri_bo { + /** Size in bytes of the buffer object. */ + unsigned long size; + /** + * Card virtual address (offset from the beginning of the aperture) for the + * object. Only valid while validated. + */ + unsigned long offset; + /** + * Virtual address for accessing the buffer data. Only valid while mapped. + */ + void *virtual; + /** Buffer manager context associated with this buffer object */ + dri_bufmgr *bufmgr; +}; + +struct _dri_fence { + /** + * This is an ORed mask of DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE, and + * DRM_FLAG_EXE indicating the operations associated with this fence. + * + * It is constant for the life of the fence object. + */ + unsigned int type; + /** Buffer manager context associated with this fence */ + dri_bufmgr *bufmgr; +}; + +/** + * Context for a buffer manager instance. + * + * Contains public methods followed by private storage for the buffer manager. + */ +struct _dri_bufmgr { + /** + * Allocate a buffer object. + * + * Buffer objects are not necessarily initially mapped into CPU virtual + * address space or graphics device aperture. They must be mapped using + * bo_map() to be used by the CPU, and validated for use using bo_validate() + * to be used from the graphics device. + */ + dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, + unsigned long size, unsigned int alignment, + uint64_t location_mask); + + /** + * Allocates a buffer object for a static allocation. + * + * Static allocations are ones such as the front buffer that are offered by + * the X Server, which are never evicted and never moved. + */ + dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name, + unsigned long offset, unsigned long size, + void *virtual, uint64_t location_mask); + + /** Takes a reference on a buffer object */ + void (*bo_reference)(dri_bo *bo); + + /** + * Releases a reference on a buffer object, freeing the data if + * rerefences remain. + */ + void (*bo_unreference)(dri_bo *bo); + + /** + * Maps the buffer into userspace. + * + * This function will block waiting for any existing fence on the buffer to + * clear, first. The resulting mapping is available at buf->virtual. +\ */ + int (*bo_map)(dri_bo *buf, int write_enable); + + /** Reduces the refcount on the userspace mapping of the buffer object. */ + int (*bo_unmap)(dri_bo *buf); + + /** Takes a reference on a fence object */ + void (*fence_reference)(dri_fence *fence); + + /** + * Releases a reference on a fence object, freeing the data if + * rerefences remain. + */ + void (*fence_unreference)(dri_fence *fence); + + /** + * Blocks until the given fence is signaled. + */ + void (*fence_wait)(dri_fence *fence); + + /** + * Tears down the buffer manager instance. + */ + void (*destroy)(dri_bufmgr *bufmgr); + + /** + * Add relocation entry in reloc_buf, which will be updated with the + * target buffer's real offset on on command submission. + * + * Relocations remain in place for the lifetime of the buffer object. + * + * \param reloc_buf Buffer to write the relocation into. + * \param flags BO flags to be used in validating the target buffer. + * Applicable flags include: + * - DRM_BO_FLAG_READ: The buffer will be read in the process of + * command execution. + * - DRM_BO_FLAG_WRITE: The buffer will be written in the process of + * command execution. + * - DRM_BO_FLAG_MEM_TT: The buffer should be validated in TT memory. + * - DRM_BO_FLAG_MEM_VRAM: The buffer should be validated in video + * memory. + * \param delta Constant value to be added to the relocation target's offset. + * \param offset Byte offset within batch_buf of the relocated pointer. + * \param target Buffer whose offset should be written into the relocation + * entry. + */ + int (*emit_reloc)(dri_bo *reloc_buf, uint64_t flags, uint32_t delta, + uint32_t offset, dri_bo *target); + + /** + * Processes the relocations, either in userland or by converting the list + * for use in batchbuffer submission. + * + * Kernel-based implementations will return a pointer to the arguments + * to be handed with batchbuffer submission to the kernel. The userland + * implementation performs the buffer validation and emits relocations + * into them the appopriate order. + * + * \param batch_buf buffer at the root of the tree of relocations + * \param count returns the number of buffers validated. + * \return relocation record for use in command submission. + * */ + void *(*process_relocs)(dri_bo *batch_buf, uint32_t *count); + + void (*post_submit)(dri_bo *batch_buf, dri_fence **fence); + + int (*check_aperture_space)(struct radeon_space_check *bos, int num_bo); + + int (*pin)(dri_bo *bo, int domain); + void (*unpin)(dri_bo *bo); + + uint32_t (*get_handle)(dri_bo *bo); + int debug; /**< Enables verbose debugging printouts */ +}; + +dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, + unsigned int alignment, uint64_t location_mask); +dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, + void *virtual, uint64_t location_mask); +void dri_bo_reference(dri_bo *bo); +void dri_bo_unreference(dri_bo *bo); +int dri_bo_map(dri_bo *buf, int write_enable); +int dri_bo_unmap(dri_bo *buf); +void dri_fence_wait(dri_fence *fence); +void dri_fence_reference(dri_fence *fence); +void dri_fence_unreference(dri_fence *fence); + +void dri_bo_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, const void *data); +void dri_bo_get_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, void *data); + +void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); +dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, + unsigned long size, + unsigned int (*fence_emit)(void *private), + int (*fence_wait)(void *private, + unsigned int cookie), + void *driver_priv); +void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug); +void dri_bo_fake_disable_backing_store(dri_bo *bo, + void (*invalidate_cb)(dri_bo *bo, + void *ptr), + void *ptr); +void dri_bufmgr_destroy(dri_bufmgr *bufmgr); + +int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, uint32_t delta, + uint32_t offset, dri_bo *target_buf); +void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count); +void dri_post_process_relocs(dri_bo *batch_buf); +void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence); +int dri_bufmgr_check_aperture_space(struct radeon_space_check *bos, int num_bo); + +int dri_bo_pin(dri_bo *bo, int domain); +void dri_bo_unpin(dri_bo *bo); + +uint32_t dri_bo_get_handle(dri_bo *bo); + +#ifndef TTM_API +/* reuse some TTM API */ + +#define DRM_BO_MEM_LOCAL 0 +#define DRM_BO_MEM_TT 1 +#define DRM_BO_MEM_VRAM 2 +#define DRM_BO_MEM_PRIV0 3 +#define DRM_BO_MEM_PRIV1 4 +#define DRM_BO_MEM_PRIV2 5 +#define DRM_BO_MEM_PRIV3 6 +#define DRM_BO_MEM_PRIV4 7 + +#define DRM_BO_FLAG_READ (1ULL << 0) +#define DRM_BO_FLAG_WRITE (1ULL << 1) +#define DRM_BO_FLAG_EXE (1ULL << 2) +#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) +#define DRM_BO_FLAG_NO_EVICT (1ULL << 4) + +#define DRM_BO_FLAG_MAPPABLE (1ULL << 5) +#define DRM_BO_FLAG_SHAREABLE (1ULL << 6) + +#define DRM_BO_FLAG_CACHED (1ULL << 7) + +#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) +#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19) +#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13) +#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) +#define DRM_BO_FLAG_TILE (1ULL << 15) + +#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) +#define DRM_BO_FLAG_MEM_TT (1ULL << 25) +#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) + +#define DRM_BO_MASK_MEM 0x00000000FF000000ULL + +#define DRM_FENCE_TYPE_EXE 0x00000001 +#endif + +#endif diff -up xf86-video-ati-6.12.2/src/radeon_dri.c.modeset xf86-video-ati-6.12.2/src/radeon_dri.c --- xf86-video-ati-6.12.2/src/radeon_dri.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_dri.c 2009-05-21 11:01:45.000000000 -0400 @@ -40,6 +40,8 @@ #include #include +#include +#include /* Driver data structures */ #include "radeon.h" @@ -53,6 +55,8 @@ #include "atipciids.h" +#include "radeon_drm.h" + /* X and server generic header files */ #include "xf86.h" #include "xf86PciInfo.h" @@ -70,16 +74,31 @@ static size_t radeon_drm_page_size; extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **configprivs); +#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 @@ -352,6 +371,81 @@ static void RADEONDestroyContext(ScreenP #endif } +/* 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, drm_radeon_sarea_t * sarea) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONDRIPtr pRADEONDRI; + + pRADEONDRI = (RADEONDRIPtr)info->dri->pDRIInfo->devPrivate; + info->dri->pDRIInfo->frameBufferPhysicalAddress = (char *) info->LinearAddr; + info->dri->pDRIInfo->frameBufferStride = pScrn->displayWidth * info->CurrentLayout.pixel_bytes; + info->dri->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes); +#if DRI_DRIVER_FRAMEBUFFER_MAP + info->dri->pDRIInfo->hFrameBuffer = info->fb_map_handle; +#endif +} + +static Bool +radeon_update_dri_mappings(ScrnInfoPtr pScrn, drm_radeon_sarea_t * 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->dri->drmFD, info->fb_map_handle); + info->fb_map_handle = 0; + } + + ret = drmAddMap(info->dri->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(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + Bool success; + drm_radeon_sarea_t *sarea; + + if (info->ChipFamily >= CHIP_FAMILY_R600) + return TRUE; + + if (!info->drm_mm) + return TRUE; + + if (info->dri2.enabled) + return TRUE; + + sarea = DRIGetSAREAPrivate(pScreen); + success = radeon_update_dri_mappings(pScrn, sarea); + + if (!success) + return FALSE; + + 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 @@ -701,25 +795,35 @@ static void RADEONDRIInitGARTValues(RADE info->dri->gartOffset = 0; - /* Initialize the CP ring buffer data */ - info->dri->ringStart = info->dri->gartOffset; - info->dri->ringMapSize = info->dri->ringSize*1024*1024 + radeon_drm_page_size; - info->dri->ringSizeLog2QW = RADEONMinBits(info->dri->ringSize*1024*1024/8)-1; - - info->dri->ringReadOffset = info->dri->ringStart + info->dri->ringMapSize; - info->dri->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->dri->bufStart = info->dri->ringReadOffset + info->dri->ringReadMapSize; - info->dri->bufMapSize = info->dri->bufSize*1024*1024; - - /* Reserve the rest for GART textures */ - info->dri->gartTexStart = info->dri->bufStart + info->dri->bufMapSize; - s = (info->dri->gartSize*1024*1024 - info->dri->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->dri->gartTexMapSize = (s >> l) << l; - info->dri->log2GARTTexGran = l; + if (!info->drm_mm) { + /* Initialize the CP ring buffer data */ + info->dri->ringStart = info->dri->gartOffset; + info->dri->ringMapSize = info->dri->ringSize*1024*1024 + radeon_drm_page_size; + info->dri->ringSizeLog2QW = RADEONMinBits(info->dri->ringSize*1024*1024/8)-1; + + info->dri->ringReadOffset = info->dri->ringStart + info->dri->ringMapSize; + info->dri->ringReadMapSize = radeon_drm_page_size; + + /* Reserve space for vertex/indirect buffers */ + info->dri->bufStart = info->dri->ringReadOffset + info->dri->ringReadMapSize; + info->dri->bufMapSize = info->dri->bufSize*1024*1024; + + /* Reserve the rest for GART textures */ + info->dri->gartTexStart = info->dri->bufStart + info->dri->bufMapSize; + s = (info->dri->gartSize*1024*1024 - info->dri->gartTexStart); + l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + info->dri->gartTexMapSize = (s >> l) << l; + info->dri->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->dri->gartTexMapSize = (s >> l) << l; + info->dri->log2GARTTexGran = l; + } + } /* AGP Mode Quirk List - Certain hostbridge/gfx-card combos don't work with @@ -992,6 +1096,8 @@ static Bool RADEONDRIAgpInit(RADEONInfoP "[agp] ring handle = 0x%08x\n", (unsigned int)info->dri->ringHandle); + +#if 0 if (drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize, &info->dri->ring) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n"); @@ -1000,9 +1106,10 @@ static Bool RADEONDRIAgpInit(RADEONInfoP xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] Ring mapped at 0x%08lx\n", (unsigned long)info->dri->ring); - +#endif if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize, DRM_AGP, DRM_READ_ONLY, &info->dri->ringReadPtrHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not add ring read ptr mapping\n"); return FALSE; @@ -1011,6 +1118,8 @@ static Bool RADEONDRIAgpInit(RADEONInfoP "[agp] ring read ptr handle = 0x%08x\n", (unsigned int)info->dri->ringReadPtrHandle); + +#if 0 if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize, &info->dri->ringReadPtr) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, @@ -1020,6 +1129,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoP xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] Ring read ptr mapped at 0x%08lx\n", (unsigned long)info->dri->ringReadPtr); +#endif if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize, DRM_AGP, 0, &info->dri->bufHandle) < 0) { @@ -1097,6 +1207,7 @@ static Bool RADEONDRIPciInit(RADEONInfoP "[pci] ring handle = 0x%08x\n", (unsigned int)info->dri->ringHandle); +#if 0 if (drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize, &info->dri->ring) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n"); @@ -1108,6 +1219,7 @@ static Bool RADEONDRIPciInit(RADEONInfoP xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Ring contents 0x%08lx\n", *(unsigned long *)(pointer)info->dri->ring); +#endif if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize, DRM_SCATTER_GATHER, flags, &info->dri->ringReadPtrHandle) < 0) { @@ -1119,8 +1231,10 @@ static Bool RADEONDRIPciInit(RADEONInfoP "[pci] ring read ptr handle = 0x%08x\n", (unsigned int)info->dri->ringReadPtrHandle); +#if 0 if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize, &info->dri->ringReadPtr) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring read ptr\n"); return FALSE; @@ -1131,6 +1245,7 @@ static Bool RADEONDRIPciInit(RADEONInfoP xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Ring read ptr contents 0x%08lx\n", *(unsigned long *)(pointer)info->dri->ringReadPtr); +#endif if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize, DRM_SCATTER_GATHER, 0, &info->dri->bufHandle) < 0) { @@ -1183,6 +1298,9 @@ static Bool RADEONDRIPciInit(RADEONInfoP */ static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen) { + + if (info->drm_mm) + return TRUE; /* Map registers */ info->dri->registerSize = info->MMIOSize; if (drmAddMap(info->dri->drmFD, info->MMIOAddr, info->dri->registerSize, @@ -1223,20 +1341,23 @@ static int RADEONDRIKernelInit(RADEONInf drmInfo.fb_bpp = info->CurrentLayout.pixel_code; drmInfo.depth_bpp = (info->dri->depthBits - 8) * 2; - drmInfo.front_offset = info->dri->frontOffset; - drmInfo.front_pitch = info->dri->frontPitch * cpp; - drmInfo.back_offset = info->dri->backOffset; - drmInfo.back_pitch = info->dri->backPitch * cpp; - drmInfo.depth_offset = info->dri->depthOffset; - drmInfo.depth_pitch = info->dri->depthPitch * drmInfo.depth_bpp / 8; - - drmInfo.fb_offset = info->dri->fbHandle; - drmInfo.mmio_offset = info->dri->registerHandle; - drmInfo.ring_offset = info->dri->ringHandle; - drmInfo.ring_rptr_offset = info->dri->ringReadPtrHandle; - drmInfo.buffers_offset = info->dri->bufHandle; - drmInfo.gart_textures_offset= info->dri->gartTexHandle; - + if (!info->drm_mm) { + drmInfo.front_offset = info->dri->frontOffset; + drmInfo.front_pitch = info->dri->frontPitch * cpp; + drmInfo.back_offset = info->dri->backOffset; + drmInfo.back_pitch = info->dri->backPitch * cpp; + drmInfo.depth_offset = info->dri->depthOffset; + drmInfo.depth_pitch = info->dri->depthPitch * drmInfo.depth_bpp / 8; + + drmInfo.fb_offset = info->dri->fbHandle; + drmInfo.mmio_offset = info->dri->registerHandle; + drmInfo.ring_offset = info->dri->ringHandle; + drmInfo.ring_rptr_offset = info->dri->ringReadPtrHandle; + drmInfo.buffers_offset = info->dri->bufHandle; + drmInfo.gart_textures_offset= info->dri->gartTexHandle; + } else { + } + if (drmCommandWrite(info->dri->drmFD, DRM_RADEON_CP_INIT, &drmInfo, sizeof(drm_radeon_init_t)) < 0) return FALSE; @@ -1245,8 +1366,9 @@ static int RADEONDRIKernelInit(RADEONInf * registers back to their default values, so we need to restore * those engine register here. */ - if (info->ChipFamily < CHIP_FAMILY_R600) - RADEONEngineRestore(pScrn); + if (!info->drm_mm) + if (info->ChipFamily < CHIP_FAMILY_R600) + RADEONEngineRestore(pScrn); return TRUE; } @@ -1444,12 +1566,11 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pSc /* Get DRM version & close DRM */ info->dri->pKernelDRMVersion = drmGetVersion(fd); - drmClose(fd); if (info->dri->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 */ @@ -1483,10 +1604,27 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pSc req_patch); drmFreeVersion(info->dri->pKernelDRMVersion); info->dri->pKernelDRMVersion = NULL; - return FALSE; + goto fail; + } + + if (info->dri->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_size = mminfo.vram_size; + info->mm.gart_size = mminfo.gart_size; + ErrorF("initing %llx %llx\n", + mminfo.gart_size, mminfo.vram_size); + } } + drmClose(fd); return TRUE; +fail: + drmClose(fd); + return FALSE; } Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on) @@ -1495,6 +1633,9 @@ Bool RADEONDRISetVBlankInterrupt(ScrnInf 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; @@ -1514,6 +1655,50 @@ Bool RADEONDRISetVBlankInterrupt(ScrnInf return TRUE; } +Bool RADEONDRIDoMappings(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + drm_radeon_sarea_t * pSAREAPriv = DRIGetSAREAPrivate(pScreen); + /* DRIScreenInit doesn't add all the + * common mappings. Add additional + * mappings here. + */ + + if (info->ChipFamily >= CHIP_FAMILY_R600) + return TRUE; + + if (info->dri2.enabled) + return TRUE; + + pSAREAPriv = DRIGetSAREAPrivate(pScreen); + 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; + + DRIGetDeviceInfo(pScreen, &info->dri->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 @@ -1578,10 +1763,22 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre pDRIInfo->ddxDriverMajorVersion = info->allowColorTiling ? 5 : 4; pDRIInfo->ddxDriverMinorVersion = 3; pDRIInfo->ddxDriverPatchVersion = 0; - pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr + info->dri->frontOffset; - pDRIInfo->frameBufferSize = info->FbMapSize - info->FbSecureSize; - pDRIInfo->frameBufferStride = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); + +#if DRI_DRIVER_FRAMEBUFFER_MAP + if (info->drm_mm) { + pDRIInfo->frameBufferPhysicalAddress = 0; + pDRIInfo->frameBufferSize = 0; + pDRIInfo->frameBufferStride = 0; + pDRIInfo->dontMapFrameBuffer = TRUE; + } else +#endif + { + pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr + info->dri->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 @@ -1634,9 +1831,7 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre 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 @@ -1668,57 +1863,60 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre 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->dri->fbHandle, - &scratch_int, &scratch_int, - &scratch_int, &scratch_int, - &scratch_ptr); - } - - /* FIXME: When are these mappings unmapped? */ + /* 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->dri->drmFD, fb_handle); - if (!RADEONInitVisualConfigs(pScreen)) { - RADEONDRICloseScreen(pScreen); - return FALSE; + 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; + } } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n"); return TRUE; } + static Bool RADEONDRIDoCloseScreen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -1760,17 +1958,21 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr 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); + } - /* Initialize kernel GART memory manager */ - RADEONDRIGartHeapInit(info, pScreen); /* Initialize and start the CP if required */ RADEONDRICPInit(pScrn); @@ -1779,6 +1981,10 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pSAREAPriv = (drm_radeon_sarea_t*)DRIGetSAREAPrivate(pScreen); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + if (info->drm_mm) { + /* init the handles into the sarea */ + + } pRADEONDRI = (RADEONDRIPtr)info->dri->pDRIInfo->devPrivate; pRADEONDRI->deviceID = info->Chipset; @@ -1936,6 +2142,8 @@ void RADEONDRICloseScreen(ScreenPtr pScr drmUnmap(info->dri->buf, info->dri->bufMapSize); info->dri->buf = NULL; } + +#if 0 if (info->dri->ringReadPtr) { drmUnmap(info->dri->ringReadPtr, info->dri->ringReadMapSize); info->dri->ringReadPtr = NULL; @@ -1944,6 +2152,7 @@ void RADEONDRICloseScreen(ScreenPtr pScr drmUnmap(info->dri->ring, info->dri->ringMapSize); info->dri->ring = NULL; } +#endif if (info->dri->agpMemHandle != DRM_AGP_NO_HANDLE) { drmAgpUnbind(info->dri->drmFD, info->dri->agpMemHandle); drmAgpFree(info->dri->drmFD, info->dri->agpMemHandle); @@ -2353,3 +2562,12 @@ int RADEONDRISetParam(ScrnInfoPtr pScrn, &radeonsetparam, sizeof(drm_radeon_setparam_t)); return ret; } + +static Bool radeon_dri_gart_init(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONDRIInitGARTValues(info); + return TRUE; +} diff -up xf86-video-ati-6.12.2/src/radeon_driver.c.modeset xf86-video-ati-6.12.2/src/radeon_driver.c --- xf86-video-ati-6.12.2/src/radeon_driver.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_driver.c 2009-05-21 11:20:20.000000000 -0400 @@ -67,7 +67,7 @@ #include #include - +#include /* Driver data structures */ #include "radeon.h" #include "radeon_reg.h" @@ -229,7 +229,10 @@ radeonShadowWindow(ScreenPtr screen, CAR stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; *size = stride; - return ((uint8_t *)info->FB + row * stride + offset); + if (info->drm_mm) + return ((uint8_t *)info->mm.front_buffer->virtual + row * stride + offset); + else + return ((uint8_t *)info->FB + row * stride + offset); } static Bool RADEONCreateScreenResources (ScreenPtr pScreen) @@ -250,6 +253,13 @@ RADEONCreateScreenResources (ScreenPtr p radeonShadowWindow, 0, NULL)) return FALSE; } + + if (info->dri2.enabled) { + if (info->mm.front_buffer) { + PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); + radeon_set_pixmap_bo(pPix, info->mm.front_buffer); + } + } return TRUE; } @@ -1695,6 +1705,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPt } pScrn->videoRam &= ~1023; + info->FbMapSize = pScrn->videoRam * 1024; /* if the card is PCI Express reserve the last 32k for the gart table */ @@ -1814,59 +1825,61 @@ static Bool RADEONPreInitChipType(ScrnIn break; } - from = X_PROBED; - info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffULL; - pScrn->memPhysBase = info->LinearAddr; - if (dev->MemBase) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Linear address override, using 0x%016lx instead of 0x%016llx\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%016llx\n", info->LinearAddr); + if (!info->drm_mode_setting) { + from = X_PROBED; + info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffULL; + pScrn->memPhysBase = info->LinearAddr; + if (dev->MemBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Linear address override, using 0x%016lx instead of 0x%016llx\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%016llx\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", - (unsigned long)dev->BiosBase, - (unsigned long)info->BIOSAddr); - info->BIOSAddr = dev->BiosBase; - from = X_CONFIG; - } - if (info->BIOSAddr) { - xf86DrvMsg(pScrn->scrnIndex, from, - "BIOS at 0x%08lx\n", (unsigned long)info->BIOSAddr); - } + /* 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", + (unsigned long)dev->BiosBase, + (unsigned long)info->BIOSAddr); + info->BIOSAddr = dev->BiosBase; + from = X_CONFIG; + } + if (info->BIOSAddr) { + xf86DrvMsg(pScrn->scrnIndex, from, + "BIOS at 0x%08lx\n", (unsigned long)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) - info->ChipErrata |= CHIP_ERRATA_R300_CG; + 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) - info->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS; + 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) - info->ChipErrata |= CHIP_ERRATA_PLL_DELAY; + 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 */ @@ -2041,6 +2054,15 @@ static Bool RADEONPreInitAccel(ScrnInfoP } info->accel_state->fifo_slots = 0; + if (info->drm_mode_setting && info->ChipFamily >= CHIP_FAMILY_R600) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using shadowfb for KMS on R600+\n"); + info->r600_shadow_fb = TRUE; + if (!xf86LoadSubModule(pScrn, "shadow")) + info->r600_shadow_fb = FALSE; + return TRUE; + } + if ((info->ChipFamily == CHIP_FAMILY_RS100) || (info->ChipFamily == CHIP_FAMILY_RS200) || (info->ChipFamily == CHIP_FAMILY_RS300) || @@ -2065,6 +2087,9 @@ static Bool RADEONPreInitAccel(ScrnInfoP 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) @@ -2075,12 +2100,17 @@ static Bool RADEONPreInitAccel(ScrnInfoP info->useEXA = TRUE; } else if (xf86NameCmp(optstr, "XAA") == 0) { from = X_CONFIG; + info->useEXA = FALSE; } } #else /* USE_XAA */ info->useEXA = TRUE; #endif /* !USE_XAA */ #endif /* USE_EXA */ + /* for drm_mm use EXA */ + if (info->drm_mm && !info->r600_shadow_fb) { + info->useEXA = TRUE; + } if (info->ChipFamily < CHIP_FAMILY_R600) xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", @@ -2179,15 +2209,9 @@ static Bool RADEONPreInitInt10(ScrnInfoP return TRUE; } -#ifdef XF86DRI -static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) +static Bool radeon_alloc_dri(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - MessageType from; - char *reason; - - info->directRenderingEnabled = FALSE; - info->directRenderingInited = FALSE; if (!(info->dri = xcalloc(1, sizeof(struct radeon_dri)))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n"); @@ -2198,6 +2222,22 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n"); return FALSE; } + return TRUE; +} + +#ifdef XF86DRI +static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + MessageType from; + char *reason; + + info->directRenderingEnabled = FALSE; + info->directRenderingInited = FALSE; + + if (!radeon_alloc_dri(pScrn)) + return FALSE; + info->cp->CPInUse = FALSE; info->cp->CPStarted = FALSE; info->cp->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT; @@ -2761,6 +2801,37 @@ static const xf86CrtcConfigFuncsRec RADE 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; @@ -2780,6 +2851,8 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in info = RADEONPTR(pScrn); info->MMIO = NULL; + info->drm_mode_setting = radeon_kernel_mode_enabled(pScrn); + info->IsSecondary = FALSE; info->IsPrimary = FALSE; @@ -2814,62 +2887,63 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in } 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) & ~0xffULL; - info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TOTO SAYS %016llx\n", - (unsigned long long)PCI_REGION_BASE(info->PciInfo, - 2, REGION_MEM)); - if (info->pEnt->device->IOBase) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "MMIO address override, using 0x%08lx instead of 0x%016llx\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%016llx: 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) & ~0xffULL; + 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%016llx\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%016llx: 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; @@ -2879,10 +2953,12 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in 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; @@ -2897,125 +2973,189 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); /* By default, don't do VGA IOs on ppc/sparc */ + if (!info->drm_mode_setting) { #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; + 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; + } - RADEONPostInt10Check(pScrn, int10_save); + if (!RADEONPreInitInt10(pScrn, &pInt10)) + goto fail; - if (!RADEONPreInitBIOS(pScrn, pInt10)) - goto fail; + RADEONPostInt10Check(pScrn, int10_save); + + if (!RADEONPreInitBIOS(pScrn, pInt10)) + goto fail; - /* Save BIOS scratch registers */ - RADEONSaveBIOSRegisters(pScrn, info->SavedReg); + /* Save BIOS scratch registers */ + RADEONSaveBIOSRegisters(pScrn, info->SavedReg); #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 (!info->directRenderingEnabled) { - if (info->ChipFamily >= CHIP_FAMILY_R600) { - info->r600_shadow_fb = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "using shadow framebuffer\n"); - if (!xf86LoadSubModule(pScrn, "shadow")) - info->r600_shadow_fb = FALSE; + if (!info->directRenderingEnabled) { + if (info->ChipFamily >= CHIP_FAMILY_R600) { + info->r600_shadow_fb = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "using shadow framebuffer\n"); + if (!xf86LoadSubModule(pScrn, "shadow")) + info->r600_shadow_fb = FALSE; + } } - } - if (!RADEONPreInitVRAM(pScrn)) - goto fail; + if (!RADEONPreInitVRAM(pScrn)) + goto fail; - RADEONPreInitColorTiling(pScrn); + RADEONPreInitColorTiling(pScrn); - if (IS_AVIVO_VARIANT) - xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192); - else - xf86CrtcSetSizeRange (pScrn, 320, 200, 4096, 4096); + if (IS_AVIVO_VARIANT) + xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192); + else + xf86CrtcSetSizeRange (pScrn, 320, 200, 4096, 4096); - RADEONPreInitDDC(pScrn); + RADEONPreInitDDC(pScrn); - if (!RADEONPreInitControllers(pScrn)) - goto fail; + if (!RADEONPreInitControllers(pScrn)) + goto fail; - ErrorF("before xf86InitialConfiguration\n"); + ErrorF("before xf86InitialConfiguration\n"); - if (!xf86InitialConfiguration (pScrn, FALSE)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - goto fail; - } + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + goto fail; + } - /* fix up cloning on rn50 cards - * since they only have one crtc sometimes the xserver doesn't assign - * a crtc to one of the outputs even though both outputs have common modes - * which results in only one monitor being enabled. Assign a crtc here so - * that both outputs light up. - */ - if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) { - int i; + /* fix up cloning on rn50 cards + * since they only have one crtc sometimes the xserver doesn't assign + * a crtc to one of the outputs even though both outputs have common modes + * which results in only one monitor being enabled. Assign a crtc here so + * that both outputs light up. + */ + if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) { + int i; - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; - /* XXX: double check crtc mode */ - if ((output->probed_modes != NULL) && (output->crtc == NULL)) - output->crtc = xf86_config->crtc[0]; + /* XXX: double check crtc mode */ + if ((output->probed_modes != NULL) && (output->crtc == NULL)) + output->crtc = xf86_config->crtc[0]; + } } - } - ErrorF("after xf86InitialConfiguration\n"); + ErrorF("after xf86InitialConfiguration\n"); + } else { +#ifdef XF86DRM_MODE + char *bus_id; + int zaphod_mask; + if (!radeon_alloc_dri(pScrn)) + return FALSE; + + zaphod_mask = 0xf; + if (info->IsPrimary) + zaphod_mask = 0xd; + if (info->IsSecondary) + zaphod_mask = 0x2; + + bus_id = DRICreatePCIBusID(info->PciInfo); + if (drmmode_pre_init(pScrn, &info->drmmode, bus_id, "radeon", pScrn->bitsPerPixel / 8, zaphod_mask) == FALSE) { + xfree(bus_id); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); + goto fail; + } + + info->dri->drmFD = info->drmmode.fd; + info->dri2.drm_fd = info->drmmode.fd; + info->dri2.enabled = FALSE; + xfree(bus_id); + + { + struct drm_radeon_gem_info mminfo; + + if (!drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) + { + info->mm.vram_size = mminfo.vram_visible; + info->mm.gart_size = mminfo.gart_size; + ErrorF("initing gart:%llx vram: s:%llx v:%llx\n", + mminfo.gart_size, mminfo.vram_size, mminfo.vram_visible); + } + { + struct drm_radeon_getparam gp; + int value; + + memset(&gp, 0, sizeof(gp)); + gp.param = RADEON_PARAM_FB_LOCATION; + gp.value = &value; + + if (drmCommandWriteRead(info->dri->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; + } + } + if (info->ChipFamily < CHIP_FAMILY_R600) { + info->useEXA = TRUE; + info->directRenderingEnabled = TRUE; + } + info->new_cs = TRUE; + info->drm_mm = 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; @@ -3030,10 +3170,12 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in 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) { @@ -3186,6 +3328,9 @@ static void RADEONBlockHandler(int i, po #ifdef USE_EXA info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; + if (info->new_cs) { + RADEONCPReleaseIndirect(pScrn); + } #endif } @@ -3274,7 +3419,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr int subPixelOrder = SubPixelUnknown; char* s; #endif - + void *front_ptr; info->accelOn = FALSE; #ifdef USE_XAA @@ -3294,58 +3439,61 @@ Bool RADEONScreenInit(int scrnIndex, Scr "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->dri->fbX = 0; - info->dri->fbY = 0; + info->dri->fbX = 0; + info->dri->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; + /* save the real front buffer size + * it changes with randr, rotation, etc. + */ + info->virtualX = pScrn->virtualX; + info->virtualY = pScrn->virtualY; - /* save the real front buffer size - * it changes with randr, rotation, etc. - */ - info->virtualX = pScrn->virtualX; - info->virtualY = pScrn->virtualY; + 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, @@ -3379,19 +3527,21 @@ Bool RADEONScreenInit(int scrnIndex, Scr 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 */ - if (info->ChipFamily < CHIP_FAMILY_R600) { - 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 */ + if (info->ChipFamily < CHIP_FAMILY_R600) { + 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); + } } } @@ -3428,7 +3578,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr #ifdef XF86DRI if (hasDRI) { info->accelDFS = xf86ReturnOptValBool(info->Options, OPTION_ACCEL_DFS, - info->cardType != CARD_AGP); + info->cardType != CARD_AGP); /* Reserve approx. half of offscreen memory for local textures by * default, can be overridden with Option "FBTexPercent". @@ -3454,7 +3604,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr #endif #if defined(XF86DRI) && defined(USE_XAA) - if (!info->useEXA && hasDRI) { + if (!info->useEXA && hasDRI && !info->drm_mm) { info->dri->textureSize = -1; if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT, &(info->dri->textureSize))) { @@ -3472,7 +3622,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr #endif #ifdef USE_XAA - if (!info->useEXA && !hasDRI && !RADEONSetupMemXAA(scrnIndex, pScreen)) + if (!info->useEXA && !hasDRI && !info->drm_mm && !RADEONSetupMemXAA(scrnIndex, pScreen)) return FALSE; #endif @@ -3493,7 +3643,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr 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, @@ -3503,19 +3653,52 @@ Bool RADEONScreenInit(int scrnIndex, Scr info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); info->directRenderingEnabled = FALSE; } else { - info->directRenderingEnabled = RADEONDRIScreenInit(pScreen); + info->directRenderingEnabled = FALSE; +#ifdef DRI2 + if (info->drm_mm) { + info->directRenderingEnabled = radeon_dri2_screen_init(pScreen); + } +#endif + if (!info->directRenderingEnabled) { + info->directRenderingEnabled = RADEONDRIScreenInit(pScreen); + } } } - /* Tell DRI about new memory map */ - if (info->directRenderingEnabled && info->dri->newMemoryMap) { - if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) { + front_ptr = info->FB; + if (info->drm_mm) { + if (info->directRenderingEnabled && info->dri->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->dri->drmFD); + drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr); + + radeon_bufmgr_gem_set_limit(info->bufmgr, RADEON_GEM_DOMAIN_GTT, info->mm.gart_size - info->dri->gartTexMapSize); + + radeon_setup_kernel_mem(pScreen); + front_ptr = info->mm.front_buffer->virtual; + info->accel_state->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64) << 22)); + } else { + + /* Tell DRI about new memory map */ + if (info->directRenderingEnabled && info->dri->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; + } } } + + if (info->directRenderingEnabled == TRUE && !info->dri2.enabled) + RADEONDRIDoMappings(pScreen); + #endif xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Initializing fb layer\n"); @@ -3539,7 +3722,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr 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)) @@ -3581,8 +3764,10 @@ Bool RADEONScreenInit(int scrnIndex, Scr /* restore the memory map here otherwise we may get a hang when * initializing the drm below */ - RADEONInitMemMapRegisters(pScrn, info->ModeReg, info); - RADEONRestoreMemMapRegisters(pScrn, info->ModeReg); + if (!info->drm_mode_setting) { + RADEONInitMemMapRegisters(pScrn, info->ModeReg, info); + RADEONRestoreMemMapRegisters(pScrn, info->ModeReg); + } /* Backing store setup */ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -3592,7 +3777,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr /* DRI finalisation */ #ifdef XF86DRI - if (info->directRenderingEnabled && info->cardType==CARD_PCIE && + if (!info->drm_mm && info->directRenderingEnabled && info->cardType==CARD_PCIE && info->dri->pKernelDRMVersion->version_minor >= 19) { if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_PCIGART_LOCATION, info->dri->pciGartOffset) < 0) @@ -3608,14 +3793,24 @@ Bool RADEONScreenInit(int scrnIndex, Scr if (info->directRenderingEnabled) { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "DRI Finishing init !\n"); + if (!info->dri2.enabled) { info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen); } + } if (info->directRenderingEnabled) { + + if (info->drm_mm) + if (!info->dri2.enabled) { + radeon_update_dri_buffers(pScreen); + } + /* 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); + } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); @@ -3717,8 +3912,14 @@ Bool RADEONScreenInit(int scrnIndex, Scr pScrn->virtualY * pScrn->displayWidth * info->CurrentLayout.pixel_bytes); /* set the modes with desired rotation, etc. */ - if (!xf86SetDesiredModes (pScrn)) + pScrn->pScreen = pScreen; + if (info->drm_mode_setting) { + if (!drmmode_set_desired_modes(pScrn, &info->drmmode)) + return FALSE; + } else { + if (!xf86SetDesiredModes (pScrn)) return FALSE; + } /* Provide SaveScreen & wrap BlockHandler and CloseScreen */ /* Wrap CloseScreen */ @@ -3738,18 +3939,24 @@ Bool RADEONScreenInit(int scrnIndex, Scr pScrn->PointerMoved = RADEONPointerMoved; /* Colormap setup */ - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "Initializing color map\n"); - if (!miCreateDefColormap(pScreen)) return FALSE; - /* all radeons support 10 bit CLUTs */ - if (!xf86HandleColormaps(pScreen, 256, 10, - RADEONLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR + if (!info->drm_mode_setting) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Initializing color map\n"); + if (!miCreateDefColormap(pScreen)) + return FALSE; + /* all radeons support 10 bit CLUTs */ + if (!xf86HandleColormaps(pScreen, 256, 10, + RADEONLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR #if 0 /* This option messes up text mode! (eich@suse.de) */ - | CMAP_LOAD_EVEN_IF_OFFSCREEN + | CMAP_LOAD_EVEN_IF_OFFSCREEN #endif - | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; - + | CMAP_RELOAD_ON_MODE_SWITCH)) + return FALSE; + } else { + if (!drmmode_setup_colormap(pScreen, pScrn)) + return FALSE; + } /* Note unused options */ if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -5288,7 +5495,7 @@ Bool RADEONSwitchMode(int scrnIndex, Dis #ifdef XF86DRI Bool CPStarted = info->cp->CPStarted; - if (CPStarted) { + if (CPStarted && !info->drm_mode_setting) { DRILock(pScrn->pScreen, 0); RADEONCP_STOP(pScrn, info); } @@ -5311,8 +5518,10 @@ Bool RADEONSwitchMode(int scrnIndex, Dis #endif } - if (info->accelOn) - RADEON_SYNC(info, pScrn); + if (!info->drm_mode_setting) { + if (info->accelOn) + RADEON_SYNC(info, pScrn); + } ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0); @@ -5324,16 +5533,19 @@ Bool RADEONSwitchMode(int scrnIndex, Dis /* xf86SetRootClip would do, but can't access that here */ } - if (info->accelOn) { - RADEON_SYNC(info, pScrn); - if (info->ChipFamily < CHIP_FAMILY_R600) - RADEONEngineRestore(pScrn); - } + if (!info->drm_mode_setting) + if (info->accelOn) { + RADEON_SYNC(info, pScrn); + if (info->ChipFamily < CHIP_FAMILY_R600) + RADEONEngineRestore(pScrn); + } #ifdef XF86DRI - if (CPStarted) { - RADEONCP_START(pScrn, info); - DRIUnlock(pScrn->pScreen); + if (!info->drm_mode_setting) { + if (CPStarted) { + RADEONCP_START(pScrn, info); + DRIUnlock(pScrn->pScreen); + } } #endif @@ -5531,6 +5743,11 @@ void RADEONAdjustFrame(int scrnIndex, in 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; + } + /* not handled */ if (IS_AVIVO_VARIANT) return; @@ -5570,80 +5787,104 @@ Bool RADEONEnterVT(int scrnIndex, int fl 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); + } else { + int ret; + ret = ioctl(info->dri->drmFD, DRM_IOCTL_SET_MASTER, NULL); + if (ret == -EINVAL) + ErrorF("Unable to retrieve master\n"); } - if (IS_R300_VARIANT || IS_RV100_VARIANT) - RADEONForceSomeClocks(pScrn); + if (info->drm_mm) { + info->accel_state->XInited3D = FALSE; + info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; + } - for (i = 0; i < config->num_crtc; i++) - radeon_crtc_modeset_ioctl(config->crtc[i], TRUE); + if (info->directRenderingEnabled) + radeon_update_dri_buffers(pScrn->pScreen); pScrn->vtSema = TRUE; - /* Clear the framebuffer */ - memset(info->FB + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * info->CurrentLayout.pixel_bytes); + if (!info->drm_mode_setting) { + for (i = 0; i < config->num_crtc; i++) + radeon_crtc_modeset_ioctl(config->crtc[i], TRUE); - if (!xf86SetDesiredModes(pScrn)) + /* Clear the framebuffer */ + memset(info->FB + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * info->CurrentLayout.pixel_bytes); + } + + if (info->drm_mode_setting) { + if (!drmmode_set_desired_modes(pScrn, &info->drmmode)) + return FALSE; + } else { + 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->dri->pKernelDRMVersion->version_minor >= 19 && - info->FbSecureSize) { + if (info->directRenderingEnabled) { + if (info->cardType == CARD_PCIE && + info->dri->pKernelDRMVersion->version_minor >= 19 && + info->FbSecureSize) { #if X_BYTE_ORDER == X_BIG_ENDIAN - unsigned char *RADEONMMIO = info->MMIO; - unsigned int sctrl = INREG(RADEON_SURFACE_CNTL); + unsigned char *RADEONMMIO = info->MMIO; + unsigned int sctrl = INREG(RADEON_SURFACE_CNTL); - /* we need to backup the PCIE GART TABLE from fb memory */ - OUTREG(RADEON_SURFACE_CNTL, 0); + /* we need to backup the PCIE GART TABLE from fb memory */ + OUTREG(RADEON_SURFACE_CNTL, 0); #endif - memcpy(info->FB + info->dri->pciGartOffset, info->dri->pciGartBackup, info->dri->pciGartSize); + memcpy(info->FB + info->dri->pciGartOffset, info->dri->pciGartBackup, info->dri->pciGartSize); #if X_BYTE_ORDER == X_BIG_ENDIAN - OUTREG(RADEON_SURFACE_CNTL, sctrl); + OUTREG(RADEON_SURFACE_CNTL, sctrl); #endif - } + } - /* get the DRI back into shape after resume */ - RADEONDRISetVBlankInterrupt (pScrn, TRUE); - RADEONDRIResume(pScrn->pScreen); - RADEONAdjustMemMapRegisters(pScrn, info->ModeReg); + /* 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 @@ -5658,7 +5899,7 @@ Bool RADEONEnterVT(int scrnIndex, int fl info->accel_state->XInited3D = FALSE; #ifdef XF86DRI - if (info->directRenderingEnabled) { + if (info->directRenderingEnabled && !info->drm_mode_setting) { if (info->ChipFamily >= CHIP_FAMILY_R600) R600LoadShaders(pScrn); RADEONCP_START(pScrn, info); @@ -5682,27 +5923,29 @@ void RADEONLeaveVT(int scrnIndex, int fl xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "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->dri->pKernelDRMVersion->version_minor >= 19 && - info->FbSecureSize) { + if (info->directRenderingInited || info->dri2.enabled) { + if (!info->drm_mode_setting) { + RADEONDRISetVBlankInterrupt (pScrn, FALSE); + DRILock(pScrn->pScreen, 0); + RADEONCP_STOP(pScrn, info); + + if (info->cardType == CARD_PCIE && + info->dri->pKernelDRMVersion->version_minor >= 19 && + info->FbSecureSize) { #if X_BYTE_ORDER == X_BIG_ENDIAN - unsigned char *RADEONMMIO = info->MMIO; - unsigned int sctrl = INREG(RADEON_SURFACE_CNTL); + unsigned char *RADEONMMIO = info->MMIO; + unsigned int sctrl = INREG(RADEON_SURFACE_CNTL); - /* we need to backup the PCIE GART TABLE from fb memory */ - OUTREG(RADEON_SURFACE_CNTL, 0); + /* we need to backup the PCIE GART TABLE from fb memory */ + OUTREG(RADEON_SURFACE_CNTL, 0); #endif - memcpy(info->dri->pciGartBackup, (info->FB + info->dri->pciGartOffset), info->dri->pciGartSize); + /* we need to backup the PCIE GART TABLE from fb memory */ + memcpy(info->dri->pciGartBackup, (info->FB + info->dri->pciGartOffset), info->dri->pciGartSize); #if X_BYTE_ORDER == X_BIG_ENDIAN - OUTREG(RADEON_SURFACE_CNTL, sctrl); + OUTREG(RADEON_SURFACE_CNTL, sctrl); #endif - } + } + } /* Make sure 3D clients will re-upload textures to video RAM */ if (info->dri->textureSize) { @@ -5718,6 +5961,11 @@ void RADEONLeaveVT(int scrnIndex, int fl i = list[i].next; } while (i != 0); } + + if (info->drm_mode_setting) + ioctl(info->dri->drmFD, DRM_IOCTL_DROP_MASTER, NULL); + + } #endif @@ -5744,10 +5992,17 @@ void RADEONLeaveVT(int scrnIndex, int fl xf86_hide_cursors (pScrn); - RADEONRestore(pScrn); + if (info->drm_mm) { + info->accel_state->XInited3D = FALSE; + info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; + } + + if (!info->drm_mode_setting) { + RADEONRestore(pScrn); - for (i = 0; i < config->num_crtc; i++) - radeon_crtc_modeset_ioctl(config->crtc[i], FALSE); + 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"); @@ -5801,7 +6056,8 @@ static Bool RADEONCloseScreen(int scrnIn #endif /* USE_XAA */ if (pScrn->vtSema) { - RADEONRestore(pScrn); + if (!info->drm_mode_setting) + RADEONRestore(pScrn); } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -5836,6 +6092,7 @@ static Bool RADEONCloseScreen(int scrnIn info->DGAModes = NULL; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "Unmapping memory\n"); + RADEONUnmapMem(pScrn); pScrn->vtSema = FALSE; diff -up xf86-video-ati-6.12.2/src/radeon_drm.h.modeset xf86-video-ati-6.12.2/src/radeon_drm.h --- xf86-video-ati-6.12.2/src/radeon_drm.h.modeset 2008-12-01 17:20:59.000000000 -0500 +++ xf86-video-ati-6.12.2/src/radeon_drm.h 2009-05-21 11:01:45.000000000 -0400 @@ -303,7 +303,8 @@ typedef union { #define RADEON_INDEX_PRIM_OFFSET 20 #define RADEON_SCRATCH_REG_OFFSET 32 -#define R600_SCRATCH_REG_OFFSET 256 + +#define R600_SCRATCH_REG_OFFSET 256 #define RADEON_NR_SAREA_CLIPRECTS 12 @@ -493,6 +494,16 @@ typedef struct { #define DRM_RADEON_SETPARAM 0x19 #define DRM_RADEON_SURF_ALLOC 0x1a #define DRM_RADEON_SURF_FREE 0x1b +/* KMS ioctl */ +#define DRM_RADEON_GEM_INFO 0x1c +#define DRM_RADEON_GEM_CREATE 0x1d +#define DRM_RADEON_GEM_MMAP 0x1e +#define DRM_RADEON_GEM_PREAD 0x21 +#define DRM_RADEON_GEM_PWRITE 0x22 +#define DRM_RADEON_GEM_SET_DOMAIN 0x23 +#define DRM_RADEON_GEM_WAIT_IDLE 0x24 +#define DRM_RADEON_CS 0x26 +#define DRM_RADEON_INFO 0x27 #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -521,6 +532,17 @@ typedef struct { #define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) #define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) +/* KMS */ +#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info) +#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create) +#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap) +#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) +#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) +#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) +#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) +#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) +#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) + typedef struct drm_radeon_init { enum { @@ -528,10 +550,10 @@ typedef struct drm_radeon_init { RADEON_CLEANUP_CP = 0x02, RADEON_INIT_R200_CP = 0x03, RADEON_INIT_R300_CP = 0x04, - RADEON_INIT_R600_CP = 0x05, + RADEON_INIT_R600_CP = 0x05 } func; unsigned long sarea_priv_offset; - int is_pci; /* for overriding only */ + int is_pci; int cp_mode; int gart_size; int ring_size; @@ -543,9 +565,8 @@ typedef struct drm_radeon_init { unsigned int depth_bpp; unsigned int depth_offset, depth_pitch; - /* DEPRECATED commented out below to allow for -Werror build */ - unsigned long fb_offset; /* deprecated, driver asks hardware */ - unsigned long mmio_offset; /* deprecated, driver asks hardware */ + unsigned long fb_offset; + unsigned long mmio_offset; unsigned long ring_offset; unsigned long ring_rptr_offset; unsigned long buffers_offset; @@ -581,7 +602,7 @@ typedef struct drm_radeon_clear { unsigned int clear_depth; unsigned int color_mask; unsigned int depth_mask; /* misnamed field: should be stencil */ - drm_radeon_clear_rect_t *depth_boxes; + drm_radeon_clear_rect_t *depth_boxes; } drm_radeon_clear_t; typedef struct drm_radeon_vertex { @@ -607,9 +628,9 @@ typedef struct drm_radeon_vertex2 { int idx; /* Index of vertex buffer */ int discard; /* Client finished with buffer? */ int nr_states; - drm_radeon_state_t *state; + drm_radeon_state_t *state; int nr_prims; - drm_radeon_prim_t *prim; + drm_radeon_prim_t *prim; } drm_radeon_vertex2_t; /* v1.3 - obsoletes drm_radeon_vertex2 @@ -624,15 +645,15 @@ typedef struct drm_radeon_vertex2 { */ typedef struct drm_radeon_cmd_buffer { int bufsz; - char *buf; + char *buf; int nbox; - struct drm_clip_rect *boxes; + struct drm_clip_rect *boxes; } drm_radeon_cmd_buffer_t; typedef struct drm_radeon_tex_image { unsigned int x, y; /* Blit coordinates */ unsigned int width, height; - const void *data; + const void *data; } drm_radeon_tex_image_t; typedef struct drm_radeon_texture { @@ -641,11 +662,11 @@ typedef struct drm_radeon_texture { int format; int width; /* Texture image coordinates */ int height; - drm_radeon_tex_image_t *image; + drm_radeon_tex_image_t *image; } drm_radeon_texture_t; typedef struct drm_radeon_stipple { - unsigned int *mask; + unsigned int *mask; } drm_radeon_stipple_t; typedef struct drm_radeon_indirect { @@ -655,9 +676,6 @@ typedef struct drm_radeon_indirect { int discard; } drm_radeon_indirect_t; -#define RADEON_INDIRECT_DISCARD (1 << 0) -#define RADEON_INDIRECT_NOFLUSH (1 << 1) - /* enum for card type parameters */ #define RADEON_CARD_PCI 0 #define RADEON_CARD_AGP 1 @@ -683,10 +701,11 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ +#define RADEON_PARAM_DEVICE_ID 16 typedef struct drm_radeon_getparam { int param; - void *value; + void *value; } drm_radeon_getparam_t; /* 1.6: Set up a memory manager for regions of shared memory: @@ -698,7 +717,7 @@ typedef struct drm_radeon_mem_alloc { int region; int alignment; int size; - int *region_offset; /* offset from start of fb or GART */ + int *region_offset; /* offset from start of fb or GART */ } drm_radeon_mem_alloc_t; typedef struct drm_radeon_mem_free { @@ -715,7 +734,7 @@ typedef struct drm_radeon_mem_init_heap /* 1.6: Userspace can request & wait on irq's: */ typedef struct drm_radeon_irq_emit { - int *irq_seq; + int *irq_seq; } drm_radeon_irq_emit_t; typedef struct drm_radeon_irq_wait { @@ -734,7 +753,6 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ - #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ @@ -753,4 +771,112 @@ typedef struct drm_radeon_surface_free { #define DRM_RADEON_VBLANK_CRTC1 1 #define DRM_RADEON_VBLANK_CRTC2 2 +/* + * Kernel modesetting world below. + */ +#define RADEON_GEM_DOMAIN_CPU 0x1 +#define RADEON_GEM_DOMAIN_GTT 0x2 +#define RADEON_GEM_DOMAIN_VRAM 0x4 + +struct drm_radeon_gem_info { + uint64_t gart_size; + uint64_t vram_size; + uint64_t vram_visible; +}; + +#define RADEON_GEM_NO_BACKING_STORE 1 + +struct drm_radeon_gem_create { + uint64_t size; + uint64_t alignment; + uint32_t handle; + uint32_t initial_domain; + uint32_t flags; +}; + +struct drm_radeon_gem_mmap { + uint32_t handle; + uint32_t pad; + uint64_t offset; + uint64_t size; + uint64_t addr_ptr; +}; + +struct drm_radeon_gem_set_domain { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; +}; + +struct drm_radeon_gem_wait_idle { + uint32_t handle; + uint32_t pad; +}; + +struct drm_radeon_gem_busy { + uint32_t handle; + uint32_t busy; +}; + +struct drm_radeon_gem_pread { + /** Handle for the object being read. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to read from */ + uint64_t offset; + /** Length of data to read */ + uint64_t size; + /** Pointer to write the data into. */ + /* void *, but pointers are not 32/64 compatible */ + uint64_t data_ptr; +}; + +struct drm_radeon_gem_pwrite { + /** Handle for the object being written to. */ + uint32_t handle; + uint32_t pad; + /** Offset into the object to write to */ + uint64_t offset; + /** Length of data to write */ + uint64_t size; + /** Pointer to read the data from. */ + /* void *, but pointers are not 32/64 compatible */ + uint64_t data_ptr; +}; + +#define RADEON_CHUNK_ID_RELOCS 0x01 +#define RADEON_CHUNK_ID_IB 0x02 + +struct drm_radeon_cs_chunk { + uint32_t chunk_id; + uint32_t length_dw; + uint64_t chunk_data; +}; + +struct drm_radeon_cs_reloc { + uint32_t handle; + uint32_t read_domains; + uint32_t write_domain; + uint32_t flags; +}; + +struct drm_radeon_cs { + uint32_t num_chunks; + uint32_t cs_id; + /* this points to uint64_t * which point to cs chunks */ + uint64_t chunks; + /* updates to the limits after this CS ioctl */ + uint64_t gart_limit; + uint64_t vram_limit; +}; + +#define RADEON_INFO_DEVICE_ID 0x00 +#define RADEON_INFO_NUM_GB_PIPES 0x01 + +struct drm_radeon_info { + uint32_t request; + uint32_t pad; + uint64_t value; +}; + #endif diff -up xf86-video-ati-6.12.2/src/radeon_exa.c.modeset xf86-video-ati-6.12.2/src/radeon_exa.c --- xf86-video-ati-6.12.2/src/radeon_exa.c.modeset 2009-02-27 11:25:10.000000000 -0500 +++ xf86-video-ati-6.12.2/src/radeon_exa.c 2009-05-21 11:01:45.000000000 -0400 @@ -44,7 +44,7 @@ #include "radeon_version.h" #include "xf86.h" - +#include "radeon_bufmgr_gem.h" /***********************************************************************/ #define RINFO_FROM_SCREEN(pScr) ScrnInfoPtr pScrn = xf86Screens[pScr->myNum]; \ @@ -182,12 +182,25 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPt RINFO_FROM_SCREEN(pPix->drawable.pScreen); uint32_t pitch, offset; int bpp; + struct radeon_exa_pixmap_priv *driver_priv; + + driver_priv = exaGetPixmapDriverPrivate(pPix); bpp = pPix->drawable.bitsPerPixel; if (bpp == 24) bpp = 8; - offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; + + /* 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); @@ -220,10 +233,27 @@ int RADEONBiggerCrtcArea(PixmapPtr pPix) return crtc_num; } +Bool RADEONGetPixmapOffsetCS(PixmapPtr pPix, uint32_t *pitch_offset) +{ + RINFO_FROM_SCREEN(pPix->drawable.pScreen); + uint32_t pitch, offset; + int bpp; + + bpp = pPix->drawable.bitsPerPixel; + if (bpp == 24) + bpp = 8; + + offset = exaGetPixmapOffset(pPix); + pitch = exaGetPixmapPitch(pPix); + return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); +} + #if X_BYTE_ORDER == X_BIG_ENDIAN static unsigned long swapper_surfaces[6]; +#endif + static Bool RADEONPrepareAccess(PixmapPtr pPix, int index) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); @@ -231,7 +261,31 @@ static Bool RADEONPrepareAccess(PixmapPt 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; + + if (radeon_bufmgr_gem_has_references(driver_priv->bo)) + 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; @@ -287,6 +341,7 @@ static Bool RADEONPrepareAccess(PixmapPt OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, offset); OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, offset + size - 1); swapper_surfaces[index] = offset; +#endif return TRUE; } @@ -296,7 +351,17 @@ static void RADEONFinishAccess(PixmapPtr 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; @@ -319,9 +384,92 @@ static void RADEONFinishAccess(PixmapPtr 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, 0); + 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); +} + +dri_bo *radeon_get_pixmap_bo(PixmapPtr pPix) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + +#ifdef XF86DRM_MODE + struct radeon_exa_pixmap_priv *driver_priv; + driver_priv = exaGetPixmapDriverPrivate(pPix); + if (driver_priv) + if (driver_priv->bo) + return driver_priv->bo; +#endif + return NULL; + +} + +void radeon_set_pixmap_bo(PixmapPtr pPix, dri_bo *bo) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); +#ifdef XF86DRM_MODE + struct radeon_exa_pixmap_priv *driver_priv; + + driver_priv = exaGetPixmapDriverPrivate(pPix); + if (driver_priv) { + if (driver_priv->bo) + dri_bo_unreference(driver_priv->bo); + + dri_bo_reference(bo); + driver_priv->bo = bo; + } +#endif + +} + +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 ENTER_DRAW(x) TRACE #define LEAVE_DRAW(x) TRACE @@ -332,6 +480,7 @@ static void RADEONFinishAccess(PixmapPtr #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 @@ -345,6 +494,7 @@ static void RADEONFinishAccess(PixmapPtr #undef OUT_ACCEL_REG #undef OUT_ACCEL_REG_F #undef FINISH_ACCEL +#undef OUT_RELOC #ifdef XF86DRI @@ -355,6 +505,7 @@ static void RADEONFinishAccess(PixmapPtr #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)) @@ -393,122 +544,126 @@ Bool RADEONSetupMemEXA (ScreenPtr pScree if (info->accel_state->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->accel_state->exa->memoryBase = info->FB; - info->accel_state->exa->memorySize = info->FbMapSize - info->FbSecureSize; - info->accel_state->exa->offScreenBase = screen_size; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocating from a screen of %ld kb\n", - info->accel_state->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->accel_state->exa->offScreenBase, align); - info->accel_state->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->dri->depthBits - 8) / 4, l, next, depth_size; - - info->dri->frontOffset = 0; - info->dri->frontPitch = pScrn->displayWidth; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will use %d kb for front buffer at offset 0x%08x\n", - screen_size / 1024, info->dri->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->dri->pciGartSize / 1024, - (int)info->dri->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. + + 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->dri->backPitch = pScrn->displayWidth; - next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN); - if (!info->dri->noBackBuffer && - next + screen_size <= info->accel_state->exa->memorySize) - { - info->dri->backOffset = next; - info->accel_state->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->dri->backOffset); + if (info->allowColorTiling) + screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * byteStride; + else + screen_size = pScrn->virtualY * byteStride; + + info->accel_state->exa->memoryBase = info->FB; + info->accel_state->exa->memorySize = info->FbMapSize - info->FbSecureSize; + info->accel_state->exa->offScreenBase = screen_size; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocating from a screen of %ld kb\n", + info->accel_state->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->accel_state->exa->offScreenBase, align); + info->accel_state->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); + } } - /* Reserve the static depth buffer, and adjust pitch and height to - * handle tiling. - */ - info->dri->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32); - depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->dri->depthPitch * depthCpp; - next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN); - if (next + depth_size <= info->accel_state->exa->memorySize) - { - info->dri->depthOffset = next; - info->accel_state->exa->offScreenBase = next + depth_size; +#if defined(XF86DRI) + if (info->directRenderingEnabled) { + int depthCpp = (info->dri->depthBits - 8) / 4, l, next, depth_size; + + info->dri->frontOffset = 0; + info->dri->frontPitch = pScrn->displayWidth; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will use %d kb for depth buffer at offset 0x%08x\n", - depth_size / 1024, info->dri->depthOffset); - } + "Will use %d kb for front buffer at offset 0x%08x\n", + screen_size / 1024, info->dri->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->dri->pciGartSize / 1024, + (int)info->dri->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->dri->backPitch = pScrn->displayWidth; + next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN); + if (!info->dri->noBackBuffer && + next + screen_size <= info->accel_state->exa->memorySize) + { + info->dri->backOffset = next; + info->accel_state->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->dri->backOffset); + } + + /* Reserve the static depth buffer, and adjust pitch and height to + * handle tiling. + */ + info->dri->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32); + depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->dri->depthPitch * depthCpp; + next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN); + if (next + depth_size <= info->accel_state->exa->memorySize) + { + info->dri->depthOffset = next; + info->accel_state->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->dri->depthOffset); + } - info->dri->textureSize *= (info->accel_state->exa->memorySize - - info->accel_state->exa->offScreenBase) / 100; + info->dri->textureSize *= (info->accel_state->exa->memorySize - + info->accel_state->exa->offScreenBase) / 100; - l = RADEONLog2(info->dri->textureSize / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) - l = RADEON_LOG_TEX_GRANULARITY; - info->dri->textureSize = (info->dri->textureSize >> l) << l; - if (info->dri->textureSize >= 512 * 1024) { - info->dri->textureOffset = info->accel_state->exa->offScreenBase; - info->accel_state->exa->offScreenBase += info->dri->textureSize; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Will use %d kb for textures at offset 0x%08x\n", - info->dri->textureSize / 1024, info->dri->textureOffset); - } else { - /* Minimum texture size is for 2 256x256x32bpp textures */ - info->dri->textureSize = 0; - } - } else + l = RADEONLog2(info->dri->textureSize / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) + l = RADEON_LOG_TEX_GRANULARITY; + info->dri->textureSize = (info->dri->textureSize >> l) << l; + if (info->dri->textureSize >= 512 * 1024) { + info->dri->textureOffset = info->accel_state->exa->offScreenBase; + info->accel_state->exa->offScreenBase += info->dri->textureSize; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Will use %d kb for textures at offset 0x%08x\n", + info->dri->textureSize / 1024, info->dri->textureOffset); + } else { + /* Minimum texture size is for 2 256x256x32bpp textures */ + info->dri->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->accel_state->exa->memorySize - info->accel_state->exa->offScreenBase) / 1024, info->accel_state->exa->offScreenBase); + } + return TRUE; } @@ -523,14 +678,23 @@ RADEONTexOffsetStart(PixmapPtr pPix) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); unsigned long long offset; - exaMoveInPixmap(pPix); - ExaOffscreenMarkUsed(pPix); + struct radeon_exa_pixmap_priv *driver_priv; - offset = exaGetPixmapOffset(pPix); + driver_priv = exaGetPixmapDriverPrivate(pPix); - if (offset > info->FbMapSize) - return ~0ULL; - else - return info->fbLocation + offset; + if (driver_priv) { + //offset = dri_bo_get_handle(driver_priv->bo); + offset = driver_priv->bo->offset; + } else { + exaMoveInPixmap(pPix); + offset = exaGetPixmapOffset(pPix); + if (offset > info->FbMapSize) + return ~0ULL; + else + offset += info->fbLocation; + ExaOffscreenMarkUsed(pPix); + } + + return offset; } #endif diff -up xf86-video-ati-6.12.2/src/radeon_exa_funcs.c.modeset xf86-video-ati-6.12.2/src/radeon_exa_funcs.c --- xf86-video-ati-6.12.2/src/radeon_exa_funcs.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_exa_funcs.c 2009-05-21 11:01:45.000000000 -0400 @@ -74,21 +74,73 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + if (info->new_cs) + return; + TRACE; if (info->accel_state->exaMarkerSynced != marker) { - FUNC_NAME(RADEONWaitForIdle)(pScrn); + FUNC_NAME(RADEONWaitForIdle)(pScrn); info->accel_state->exaMarkerSynced = marker; } RADEONPTR(pScrn)->accel_state->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 ? 10 : 9; + qwords += (has_src ? (info->new_cs ? 2 : 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; + int ret; + int retry_count = 0; + struct radeon_space_check bos[1]; + int i; ACCEL_PREAMBLE(); TRACE; @@ -97,25 +149,58 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr 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")); + + retry: + if (info->new_cs) { + + i = 0; + driver_priv = exaGetPixmapDriverPrivate(pPix); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) { + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) + RADEON_FALLBACK(("Not enough Video RAM for src\n")); + goto retry; + } + } 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; } @@ -146,6 +231,7 @@ FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPi TRACE; + info->state_2d.op = 0; BEGIN_ACCEL(2); OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, @@ -153,6 +239,7 @@ FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPi FINISH_ACCEL(); } + void FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset, uint32_t dst_pitch_offset, uint32_t datatype, int rop, @@ -163,23 +250,28 @@ FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoP 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->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | - (info->accel_state->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->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | + (info->accel_state->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 @@ -190,9 +282,46 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr p { RINFO_FROM_SCREEN(pDst->drawable.pScreen); uint32_t datatype, src_pitch_offset, dst_pitch_offset; - + struct radeon_exa_pixmap_priv *driver_priv; + int ret; + int retry_count = 0; + struct radeon_space_check bos[2]; + int i; TRACE; +retry: + if (info->new_cs) { + + i = 0; + driver_priv = exaGetPixmapDriverPrivate(pSrc); + info->state_2d.src_bo = driver_priv->bo; + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + + + driver_priv = exaGetPixmapDriverPrivate(pDst); + info->state_2d.dst_bo = driver_priv->bo; + bos[i].buf = driver_priv->bo; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) { + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) + RADEON_FALLBACK(("Not enough Video RAM for src\n")); + goto retry; + } + } + + info->accel_state->xdir = xdir; info->accel_state->ydir = ydir; @@ -200,10 +329,11 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr p 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")); FUNC_NAME(RADEONDoPrepareCopy)(pScrn, src_pitch_offset, dst_pitch_offset, datatype, rop, planemask); @@ -251,6 +381,7 @@ FUNC_NAME(RADEONDoneCopy)(PixmapPtr pDst TRACE; + info->state_2d.op = 0; BEGIN_ACCEL(2); OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, @@ -267,17 +398,27 @@ RADEONUploadToScreenCP(PixmapPtr pDst, i { RINFO_FROM_SCREEN(pDst->drawable.pScreen); unsigned int bpp = pDst->drawable.bitsPerPixel; + int ret; + struct radeon_exa_pixmap_priv *driver_priv; unsigned int hpass; uint32_t buf_pitch, dst_pitch_off; TRACE; + if (info->new_cs) + return FALSE; + if (bpp < 8) return FALSE; - if (info->directRenderingEnabled && - RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off)) { - uint8_t *buf; + if (!info->directRenderingEnabled && !info->drm_mode_setting) + goto fallback; + + if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off)) + goto fallback; + + { + uint8_t *buf; int cpp = bpp / 8; ACCEL_PREAMBLE(); @@ -297,20 +438,26 @@ RADEONUploadToScreenCP(PixmapPtr pDst, i exaMarkSync(pDst->drawable.pScreen); return TRUE; } - +fallback: return FALSE; } /* Emit blit with arbitrary source and destination offsets and pitches */ static void -RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset, +RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, dri_bo *src_bo, dri_bo *dst_bo, + uint32_t src_pitch_offset, uint32_t dst_pitch_offset, int srcX, int srcY, int dstX, int dstY, int w, int h) { RADEONInfoPtr info = RADEONPTR(pScrn); + uint32_t qwords; ACCEL_PREAMBLE(); - BEGIN_ACCEL(6); + qwords = 6; + if (src_bo && dst_bo) + qwords += 2; + + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_SRC_PITCH_OFFSET_CNTL | @@ -321,8 +468,14 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, uint3 RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); + OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset); + if (src_bo) + OUT_RELOC(src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); + if (dst_bo) + OUT_RELOC(dst_bo, 0, RADEON_GEM_DOMAIN_GTT); + OUT_ACCEL_REG(RADEON_SRC_Y_X, (srcY << 16) | srcX); OUT_ACCEL_REG(RADEON_DST_Y_X, (dstY << 16) | dstX); OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); @@ -334,6 +487,174 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, uint3 FINISH_ACCEL(); } +static Bool +RADEON_DFS_CS2(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + RINFO_FROM_SCREEN(pSrc->drawable.pScreen); + struct radeon_exa_pixmap_priv *driver_priv; + int src_pitch = exaGetPixmapPitch(pSrc); + int bpp = pSrc->drawable.bitsPerPixel; + uint32_t src_offset; + /* force into GTT? */ + + if (!info->accelDFS) + return FALSE; + + driver_priv = exaGetPixmapDriverPrivate(pSrc); + + radeon_bufmgr_gem_force_gtt(driver_priv->bo); + radeon_bufmgr_gem_wait_rendering(driver_priv->bo); + + dri_bo_map(driver_priv->bo, 0); + + src_offset = (x * bpp / 8) + (y * src_pitch); + w *= bpp / 8; + + while (h--) { + memcpy(dst, driver_priv->bo->virtual + src_offset, w); + src_offset += src_pitch; + dst += dst_pitch; + } + dri_bo_unmap(driver_priv->bo); + return TRUE; +} + +static Bool +RADEON_DFS_CS(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + RINFO_FROM_SCREEN(pSrc->drawable.pScreen); + struct radeon_exa_pixmap_priv *driver_priv; + dri_bo *scratch_bo[2]; + int i, ret; + uint32_t scratch_size = RADEON_BUFFER_SIZE / 2; + int bpp = pSrc->drawable.bitsPerPixel; + uint32_t scratch_pitch = (w * bpp/8 + 63) & ~63, scratch_off = 0; + uint32_t datatype; + int src_pitch = exaGetPixmapPitch(pSrc); + dri_bo *cur_scratch; + uint32_t src_pitch_offset; + struct radeon_space_check bos[3]; + int retry_count; + + if (!info->accelDFS) + return FALSE; + + driver_priv = exaGetPixmapDriverPrivate(pSrc); + + if (radeon_bufmgr_gem_has_references(driver_priv->bo)) + RADEONCPFlushIndirect(pScrn, 0); + + /* if we haven't put this buffer in VRAM then just force gtt and memcpy from it */ + if (!radeon_bufmgr_gem_in_vram(driver_priv->bo)) { + return RADEON_DFS_CS2(pSrc, x, y, w, h, dst, dst_pitch); + } + RADEONGetDatatypeBpp(bpp, &datatype); + scratch_bo[0] = scratch_bo[1] = NULL; + for (i = 0; i < 2; i++) { + scratch_bo[i] = dri_bo_alloc(info->bufmgr, "DFS scratch", scratch_size, 0, 0); + if (!scratch_bo[i]) + goto fail; + } + +retry: + i = 0; + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + bos[i].buf = scratch_bo[0]; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_GTT; + i++; + bos[i].buf = scratch_bo[1]; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_GTT; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) + goto fail; + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) + goto fail; + goto retry; + } + + /* we want to blit from the BO to the scratch and memcpy out of the scratch */ + { + int wpass = wpass = w * bpp / 8; + int hpass = min(h, scratch_size / scratch_pitch); + uint32_t pitch_offset = scratch_pitch << 16; + + RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset); + + ACCEL_PREAMBLE(); + RADEON_SWITCH_TO_2D(); + + cur_scratch = scratch_bo[0]; + RADEONBlitChunk(pScrn, datatype, driver_priv->bo, cur_scratch, src_pitch_offset, + pitch_offset, + x, y, 0, 0, w, hpass); + + FLUSH_RING(); + + while (h) { + int swap = RADEON_HOST_DATA_SWAP_NONE; + int oldhpass = hpass, i = 0; + dri_bo *old_scratch; + uint8_t *src; + + old_scratch = cur_scratch; + y += oldhpass; + h -= oldhpass; + hpass = min(h, scratch_size / scratch_pitch); + if (hpass) { + if (cur_scratch == scratch_bo[0]) + cur_scratch = scratch_bo[1]; + else + cur_scratch = scratch_bo[0]; + + RADEONBlitChunk(pScrn, datatype, driver_priv->bo, cur_scratch, src_pitch_offset, + pitch_offset, + x, y, 0, 0, w, hpass); + } + + radeon_bufmgr_gem_wait_rendering(old_scratch); + ret = dri_bo_map(old_scratch, 0); + + if (hpass) + FLUSH_RING(); + + src = old_scratch->virtual; + + if (wpass == scratch_pitch && wpass == dst_pitch) { + RADEONCopySwap((uint8_t*)dst, src, wpass * oldhpass, swap); + dst += dst_pitch * oldhpass; + } else while (oldhpass--) { + RADEONCopySwap((uint8_t*)dst, src, wpass, swap); + src += scratch_pitch; + dst += dst_pitch; + } + dri_bo_unmap(old_scratch); + } + + dri_bo_unreference(scratch_bo[0]); + dri_bo_unreference(scratch_bo[1]); + return TRUE; + } + + + fail: + if (scratch_bo[0]) + dri_bo_unreference(scratch_bo[0]); + if (scratch_bo[1]) + dri_bo_unreference(scratch_bo[1]); + return FALSE; +} static Bool RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h, @@ -347,12 +668,17 @@ RADEONDownloadFromScreenCP(PixmapPtr pSr TRACE; + if (info->new_cs) { + return RADEON_DFS_CS(pSrc, x, y, w, h, dst, dst_pitch); + } + /* * 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 (bpp != 24 && RADEONGetDatatypeBpp(bpp, &datatype) && + if (!info->drm_mm && info->accelDFS && bpp != 24 && + RADEONGetDatatypeBpp(bpp, &datatype) && RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset) && (scratch = RADEONCPGetBuffer(pScrn))) { @@ -367,7 +693,8 @@ RADEONDownloadFromScreenCP(PixmapPtr pSr RADEON_SWITCH_TO_2D(); /* Kick the first blit as early as possible */ - RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset, + RADEONBlitChunk(pScrn, datatype, NULL, NULL, + src_pitch_offset, scratch_pitch_offset, x, y, 0, 0, w, hpass); FLUSH_RING(); @@ -394,7 +721,8 @@ RADEONDownloadFromScreenCP(PixmapPtr pSr /* Prepare next blit if anything's left */ if (hpass) { scratch_off = scratch->total/2 - scratch_off; - RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10), + RADEONBlitChunk(pScrn, datatype, NULL, NULL, + src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10), x, y, 0, 0, w, hpass); } @@ -473,10 +801,8 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr info->accel_state->exa->DownloadFromScreen = RADEONDownloadFromScreenCP; #endif -#if X_BYTE_ORDER == X_BIG_ENDIAN info->accel_state->exa->PrepareAccess = RADEONPrepareAccess; info->accel_state->exa->FinishAccess = RADEONFinishAccess; -#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS; #ifdef EXA_SUPPORTS_PREPARE_AUX @@ -485,6 +811,11 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1; info->accel_state->exa->pixmapPitchAlign = 64; + if (info->drm_mm) { + info->accel_state->exa->flags |= EXA_HANDLES_PIXMAPS; + } else { + } + #ifdef RENDER if (info->RenderAccel) { if (info->ChipFamily >= CHIP_FAMILY_R600) @@ -493,7 +824,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr 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 " @@ -528,6 +859,15 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr } #endif +#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 4) + if (info->drm_mm) { + info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap; + info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap; + info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen; + } +#endif + + #if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n"); diff -up xf86-video-ati-6.12.2/src/radeon_exa_render.c.modeset xf86-video-ati-6.12.2/src/radeon_exa_render.c --- xf86-video-ati-6.12.2/src/radeon_exa_render.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_exa_render.c 2009-05-21 11:01:45.000000000 -0400 @@ -54,6 +54,10 @@ #define ONLY_ONCE #endif +#define VTX_COUNT_MASK 6 +#define VTX_COUNT 4 + + /* Only include the following (generic) bits once. */ #ifdef ONLY_ONCE @@ -365,12 +369,14 @@ static Bool FUNC_NAME(R100TextureSetup)( Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad && !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y)); int i; + struct radeon_exa_pixmap_priv *driver_priv; + int qwords; ACCEL_PREAMBLE(); txpitch = exaGetPixmapPitch(pPix); - txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset; + txoffset = exaGetPixmapOffset(pPix); - if ((txoffset & 0x1f) != 0) + if (!info->new_cs && ((txoffset & 0x1f) != 0)) RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); if ((txpitch & 0x1f) != 0) RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); @@ -426,23 +432,43 @@ static Bool FUNC_NAME(R100TextureSetup)( } } - BEGIN_ACCEL(5); + qwords = info->new_cs ? 6 : 5; + BEGIN_ACCEL(qwords); 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); + + if (info->new_cs) { + driver_priv = exaGetPixmapDriverPrivate(pPix); + OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, 0); + OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + } else { + txoffset += info->fbLocation + pScrn->fbOffset; + 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); + if (info->new_cs) { + driver_priv = exaGetPixmapDriverPrivate(pPix); + OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, 0); + OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + } else { + txoffset += info->fbLocation + pScrn->fbOffset; + OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset); + } + + /* emit a texture relocation */ } FINISH_ACCEL(); @@ -551,10 +577,52 @@ static Bool FUNC_NAME(R100PrepareComposi uint32_t dst_format, dst_offset, dst_pitch, colorpitch; uint32_t pp_cntl, blendcntl, cblend, ablend; int pixel_shift; + struct radeon_exa_pixmap_priv *driver_priv; + int qwords; + int retry_count = 0; + struct radeon_space_check bos[3]; + int i, ret; ACCEL_PREAMBLE(); TRACE; + retry: + if (info->new_cs) { + + i = 0; + driver_priv = exaGetPixmapDriverPrivate(pSrc); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + + if (pMask) { + driver_priv = exaGetPixmapDriverPrivate(pMask); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + } + + driver_priv = exaGetPixmapDriverPrivate(pDst); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) { + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) + RADEON_FALLBACK(("Not enough Video RAM for src\n")); + goto retry; + } + } + if (!RADEONGetDestFormat(pDstPicture, &dst_format)) return FALSE; @@ -568,19 +636,18 @@ static Bool FUNC_NAME(R100PrepareComposi 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; if (RADEONPixmapIsColortiled(pDst)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset; - dst_pitch = exaGetPixmapPitch(pDst); - if ((dst_offset & 0x0f) != 0) + if (!info->new_cs && (dst_offset & 0x0f) != 0) RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); + if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) return FALSE; @@ -598,10 +665,18 @@ static Bool FUNC_NAME(R100PrepareComposi info->accel_state->is_transform[1] = FALSE; } - BEGIN_ACCEL(8); + qwords = info->new_cs ? 9 : 8; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + if (info->new_cs) { + driver_priv = exaGetPixmapDriverPrivate(pDst); + OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, 0); + OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } else { + dst_offset += info->fbLocation + pScrn->fbOffset; + OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + } OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); /* IN operator: Multiply src by mask components or mask alpha. @@ -701,13 +776,17 @@ static Bool FUNC_NAME(R200TextureSetup)( Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad && !(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y)); int i; + struct radeon_exa_pixmap_priv *driver_priv; + int qwords; ACCEL_PREAMBLE(); 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)); + if (!info->new_cs) { + if ((txoffset & 0x1f) != 0) + RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); + } if ((txpitch & 0x1f) != 0) RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); @@ -764,7 +843,8 @@ static Bool FUNC_NAME(R200TextureSetup)( } } - BEGIN_ACCEL(6); + qwords = info->new_cs ? 7 : 6; + BEGIN_ACCEL(qwords); if (unit == 0) { OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat); @@ -772,7 +852,15 @@ static Bool FUNC_NAME(R200TextureSetup)( OUT_ACCEL_REG(R200_PP_TXSIZE_0, (pPix->drawable.width - 1) | ((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); + if (info->new_cs) { + driver_priv = exaGetPixmapDriverPrivate(pPix); + + OUT_ACCEL_REG(R200_PP_TXOFFSET_0, 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(R200_PP_TXOFFSET_0, txoffset); + } } else { OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat); @@ -780,7 +868,17 @@ static Bool FUNC_NAME(R200TextureSetup)( OUT_ACCEL_REG(R200_PP_TXSIZE_1, (pPix->drawable.width - 1) | ((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); + if (info->new_cs) { + uint32_t handle = 0; + driver_priv = exaGetPixmapDriverPrivate(pPix); + + OUT_ACCEL_REG(R200_PP_TXOFFSET_1, 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(R200_PP_TXOFFSET_1, txoffset); + } + /* emit a texture relocation */ } FINISH_ACCEL(); @@ -873,10 +971,52 @@ static Bool FUNC_NAME(R200PrepareComposi uint32_t dst_format, dst_offset, dst_pitch; uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch; int pixel_shift; + struct radeon_exa_pixmap_priv *driver_priv; + int qwords; + int retry_count = 0; + struct radeon_space_check bos[3]; + int i, ret; ACCEL_PREAMBLE(); TRACE; + retry: + if (info->new_cs) { + + i = 0; + driver_priv = exaGetPixmapDriverPrivate(pSrc); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + + if (pMask) { + driver_priv = exaGetPixmapDriverPrivate(pMask); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + } + + driver_priv = exaGetPixmapDriverPrivate(pDst); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) { + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) + RADEON_FALLBACK(("Not enough Video RAM for src\n")); + goto retry; + } + } + if (!RADEONGetDestFormat(pDstPicture, &dst_format)) return FALSE; @@ -890,13 +1030,13 @@ static Bool FUNC_NAME(R200PrepareComposi 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; if (RADEONPixmapIsColortiled(pDst)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - if ((dst_offset & 0x0f) != 0) + if (!info->new_cs && (dst_offset & 0x0f) != 0) RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); @@ -918,11 +1058,22 @@ static Bool FUNC_NAME(R200PrepareComposi info->accel_state->is_transform[1] = FALSE; } - BEGIN_ACCEL(11); + qwords = info->new_cs ? 12 : 11; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + + if (info->new_cs) { + driver_priv = exaGetPixmapDriverPrivate(pDst); + assert(driver_priv); + + OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, 0); + OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } else { + dst_offset += info->fbLocation + pScrn->fbOffset; + OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + } OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY); if (pMask) @@ -991,6 +1142,10 @@ static Bool R300CheckCompositeTexture(Pi int unit, Bool is_r500) { + ScreenPtr pScreen = pDstPict->pDrawable->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; int i; @@ -1016,8 +1171,17 @@ static Bool R300CheckCompositeTexture(Pi RADEON_FALLBACK(("Unsupported picture format 0x%x\n", (int)pPict->format)); - if (!RADEONCheckTexturePOT(pPict, unit == 0)) + if (!RADEONCheckTexturePOT(pPict, unit == 0)) { + if (info->new_cs) { + struct radeon_exa_pixmap_priv *driver_priv; + PixmapPtr pPix; + + pPix = RADEONGetDrawablePixmap(pPict->pDrawable); + driver_priv = exaGetPixmapDriverPrivate(pPix); + radeon_bufmgr_gem_force_gtt(driver_priv->bo); + } return FALSE; + } if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) @@ -1049,15 +1213,19 @@ static Bool FUNC_NAME(R300TextureSetup)( 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)); + if (!info->new_cs) { + if ((txoffset & 0x1f) != 0) + RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset)); + } if ((txpitch & 0x1f) != 0) RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch)); @@ -1139,13 +1307,26 @@ static Bool FUNC_NAME(R300TextureSetup)( RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); } - BEGIN_ACCEL(pPict->repeat ? 6 : 7); + qwords = pPict->repeat ? 6 : 7; + qwords += info->new_cs ? 1 : 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); + + if (info->new_cs) { + uint32_t handle = 0; + driver_priv = exaGetPixmapDriverPrivate(pPix); + + 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(); @@ -1244,6 +1425,7 @@ static Bool R300CheckComposite(int op, P return TRUE; } + #endif /* ONLY_ONCE */ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, @@ -1255,10 +1437,51 @@ static Bool FUNC_NAME(R300PrepareComposi uint32_t txenable, colorpitch; uint32_t blendcntl; int pixel_shift; + int qwords, ret; + int retry_count = 0; + struct radeon_exa_pixmap_priv *driver_priv; + struct radeon_space_check bos[3]; + int i; ACCEL_PREAMBLE(); - TRACE; + retry: + if (info->new_cs) { + + i = 0; + driver_priv = exaGetPixmapDriverPrivate(pSrc); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + + if (pMask) { + driver_priv = exaGetPixmapDriverPrivate(pMask); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + } + + driver_priv = exaGetPixmapDriverPrivate(pDst); + bos[i].buf = driver_priv->bo; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) { + RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n")); + } + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) + RADEON_FALLBACK(("Not enough Video RAM - this really shouldn't happen\nm")); + goto retry; + } + } + if (!R300GetDestFormat(pDstPicture, &dst_format)) return FALSE; @@ -1269,7 +1492,7 @@ static Bool FUNC_NAME(R300PrepareComposi 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; @@ -1278,7 +1501,7 @@ static Bool FUNC_NAME(R300PrepareComposi colorpitch |= dst_format; - if ((dst_offset & 0x0f) != 0) + if (!info->new_cs && ((dst_offset & 0x0f) != 0)) RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset)); if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); @@ -1287,6 +1510,9 @@ static Bool FUNC_NAME(R300PrepareComposi return FALSE; RADEON_SWITCH_TO_3D(); + BEGIN_ACCEL(1); + OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0); + FINISH_ACCEL(); if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0)) return FALSE; @@ -1943,9 +2169,18 @@ static Bool FUNC_NAME(R300PrepareComposi (8191 << R300_SCISSOR_Y_SHIFT))); FINISH_ACCEL(); - BEGIN_ACCEL(3); + qwords = info->new_cs ? 4 : 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); @@ -1963,7 +2198,6 @@ static Bool FUNC_NAME(R300PrepareComposi return TRUE; } - #ifdef ACCEL_CP #define VTX_OUT_MASK(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \ @@ -2249,14 +2483,23 @@ static void FUNC_NAME(RadeonDoneComposit if (IS_R300_3D || IS_R500_3D) { BEGIN_ACCEL(3); - OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA); OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL); + OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xaaaa); } else BEGIN_ACCEL(1); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); FINISH_ACCEL(); LEAVE_DRAW(0); + +#if 0 + /* workaround hang on RS4xx and RS6xx chips */ + if(info->ChipFamily == CHIP_FAMILY_RS400 || + info->ChipFamily == CHIP_FAMILY_RS480 || + info->ChipFamily == CHIP_FAMILY_RS600 || + info->ChipFamily == CHIP_FAMILY_RS690) + RADEONCPFlushIndirect(pScrn, 1); +#endif } #undef ONLY_ONCE diff -up xf86-video-ati-6.12.2/src/radeon.h.modeset xf86-video-ati-6.12.2/src/radeon.h --- xf86-video-ati-6.12.2/src/radeon.h.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon.h 2009-05-21 11:01:45.000000000 -0400 @@ -46,6 +46,8 @@ #include "compiler.h" #include "xf86fbman.h" +#include "drmmode_display.h" + /* PCI support */ #include "xf86Pci.h" @@ -75,6 +77,7 @@ #include "dri.h" #include "GL/glxint.h" #include "xf86drm.h" +#include "radeon_dri2.h" #ifdef DAMAGE #include "damage.h" @@ -85,6 +88,7 @@ #include "xf86Crtc.h" #include "X11/Xatom.h" +#include "radeon_bufmgr.h" /* Render support */ #ifdef RENDER #include "picturestr.h" @@ -413,6 +417,11 @@ typedef enum { typedef struct _atomBiosHandle *atomBiosHandlePtr; +struct radeon_exa_pixmap_priv { + dri_bo *bo; + int flags; +}; + typedef struct { uint32_t pci_device_id; RADEONChipFamily chip_family; @@ -423,7 +432,27 @@ 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; +}; + #ifdef XF86DRI + struct radeon_cp { Bool CPRuns; /* CP is running */ Bool CPInUse; /* CP has been used by X server */ @@ -437,6 +466,10 @@ struct radeon_cp { drmBufPtr indirectBuffer; int indirectStart; + drmBuf ib_gem_fake; + void *ib_ptr; + + struct radeon_relocs_info relocs; /* Debugging info for BEGIN_RING/ADVANCE_RING pairs. */ int dma_begin_count; char *dma_debug_func; @@ -503,13 +536,13 @@ struct radeon_dri { 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 */ @@ -528,7 +561,6 @@ struct radeon_dri { drmAddress gartTex; /* Map */ int log2GARTTexGran; - /* DRI screen private data */ int fbX; int fbY; int backX; @@ -788,6 +820,7 @@ typedef struct { RADEONCardType cardType; /* Current card is a PCI card */ struct radeon_cp *cp; struct radeon_dri *dri; + struct radeon_dri2 dri2; #ifdef USE_EXA Bool accelDFS; #endif @@ -891,6 +924,27 @@ typedef struct { Bool r4xx_atom; + 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_size; + uint64_t gart_size; + + dri_bo *front_buffer; + dri_bo *cursor[2]; + } mm; + + drm_handle_t fb_map_handle; + Bool drm_mode_setting; +#ifdef XF86DRM_MODE + drmmode_rec drmmode; +#endif + + int can_resize; + dri_bufmgr *bufmgr; } RADEONInfoRec, *RADEONInfoPtr; #define RADEONWaitForFifo(pScrn, entries) \ @@ -1146,6 +1200,13 @@ extern void radeon_legacy_free_memory(ScrnInfoPtr pScrn, void *mem_struct); +/* radeon_memory.c */ +Bool radeon_setup_kernel_mem(ScreenPtr pScreen); +Bool RADEONDRIDoMappings(ScreenPtr pScreen); +Bool radeon_update_dri_buffers(ScreenPtr pScreen); + +dri_bo *radeon_get_pixmap_bo(PixmapPtr pPix); +void radeon_set_pixmap_bo(PixmapPtr pPix, dri_bo *bo); #ifdef XF86DRI # ifdef USE_XAA /* radeon_accelfuncs.c */ @@ -1164,7 +1225,9 @@ do { \ #define RADEONCP_RELEASE(pScrn, info) \ do { \ - if (info->cp->CPInUse) { \ + if (info->new_cs) { \ + RADEONCPReleaseIndirect(pScrn); \ + } else if (info->cp->CPInUse) { \ RADEON_PURGE_CACHE(); \ RADEON_WAIT_UNTIL_IDLE(); \ RADEONCPReleaseIndirect(pScrn); \ @@ -1199,7 +1262,7 @@ do { \ #define RADEONCP_REFRESH(pScrn, info) \ do { \ - if (!info->cp->CPInUse) { \ + if (!info->cp->CPInUse && !info->new_cs) { \ if (info->cp->needCacheFlush) { \ RADEON_PURGE_CACHE(); \ RADEON_PURGE_ZCACHE(); \ @@ -1226,6 +1289,13 @@ do { \ #define RING_LOCALS uint32_t *__head = NULL; int __expected; int __count = 0 #define BEGIN_RING(n) do { \ + if (!info->cp->indirectBuffer) { \ + info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn); \ + info->cp->indirectStart = 0; \ + } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \ + info->cp->indirectBuffer->total) { \ + RADEONCPFlushIndirect(pScrn, 1); \ + } \ if (RADEON_VERBOSE) { \ xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\ @@ -1238,13 +1308,6 @@ do { \ } \ info->cp->dma_debug_func = __FILE__; \ info->cp->dma_debug_lineno = __LINE__; \ - if (!info->cp->indirectBuffer) { \ - info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn); \ - info->cp->indirectStart = 0; \ - } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) > \ - info->cp->indirectBuffer->total) { \ - RADEONCPFlushIndirect(pScrn, 1); \ - } \ __expected = n; \ __head = (pointer)((char *)info->cp->indirectBuffer->address + \ info->cp->indirectBuffer->used); \ @@ -1287,6 +1350,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, &info->cp->relocs, __head, &__count, read_domains, write_domains); \ + } while(0) + + #define FLUSH_RING() \ do { \ if (RADEON_VERBOSE) \ diff -up xf86-video-ati-6.12.2/src/radeon_legacy_memory.c.modeset xf86-video-ati-6.12.2/src/radeon_legacy_memory.c --- xf86-video-ati-6.12.2/src/radeon_legacy_memory.c.modeset 2009-02-24 09:45:07.000000000 -0500 +++ xf86-video-ati-6.12.2/src/radeon_legacy_memory.c 2009-05-21 11:01:45.000000000 -0400 @@ -21,6 +21,19 @@ radeon_legacy_allocate_memory(ScrnInfoPt RADEONInfoPtr info = RADEONPTR(pScrn); uint32_t offset = 0; + if (info->new_cs) { + dri_bo *video_bo; + + video_bo = dri_bo_alloc(info->bufmgr, "xv pixmap", size, 4096, 0); + + *mem_struct = video_bo; + + if (!video_bo) + return 0; + + return (uint32_t)-1; + + } #ifdef USE_EXA if (info->useEXA) { ExaOffscreenArea *area = *mem_struct; @@ -94,6 +107,12 @@ radeon_legacy_free_memory(ScrnInfoPtr pS void *mem_struct) { RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->new_cs) { + dri_bo *bo = mem_struct; + dri_bo_unreference(bo); + return; + } #ifdef USE_EXA ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; diff -up /dev/null xf86-video-ati-6.12.2/src/radeon_memory.c --- /dev/null 2009-05-05 09:44:49.704001696 -0400 +++ xf86-video-ati-6.12.2/src/radeon_memory.c 2009-05-21 11:01:45.000000000 -0400 @@ -0,0 +1,71 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "radeon.h" +#include "radeon_drm.h" +#include "radeon_bufmgr_gem.h" + +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 = 0, remain_size_bytes; + int pagesize = 4096; + + screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * stride; + { + int cursor_size = 64 * 4 * 64; + int c; + + cursor_size = RADEON_ALIGN(cursor_size, pagesize); + for (c = 0; c < xf86_config->num_crtc; c++) { + /* cursor objects */ + info->mm.cursor[c] = dri_bo_alloc(info->bufmgr, "front", cursor_size, + 0, RADEON_GEM_DOMAIN_VRAM); + if (!info->mm.cursor[c]) { + return FALSE; + } + + if (dri_bo_map(info->mm.cursor[c], 1)) { + ErrorF("Failed to map cursor buffer memory\n"); + } + + drmmode_set_cursor(pScrn, &info->drmmode, c, info->mm.cursor[c]); + total_size_bytes += cursor_size; + } + } + + screen_size = RADEON_ALIGN(screen_size, pagesize); + /* keep area front front buffer - but don't allocate it yet */ + total_size_bytes += screen_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->dri->textureSize = 0; + + info->mm.front_buffer = dri_bo_alloc(info->bufmgr, "front", screen_size, + 0, RADEON_GEM_DOMAIN_VRAM); + + // drmmode_set_fb(pScrn, &info->drmmode, pScrn->virtualX, RADEON_ALIGN(pScrn->virtualY, 16), stride, info->mm.front_buffer); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->mm.front_buffer->size/1024); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Remaining VRAM size (used for pixmaps): %dK\n", remain_size_bytes/1024); + + /* set the emit limit at 90% of VRAM */ + remain_size_bytes = (remain_size_bytes / 10) * 9; + + radeon_bufmgr_gem_set_limit(info->bufmgr, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes); + return TRUE; +} + + diff -up xf86-video-ati-6.12.2/src/radeon_probe.h.modeset xf86-video-ati-6.12.2/src/radeon_probe.h --- xf86-video-ati-6.12.2/src/radeon_probe.h.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_probe.h 2009-05-21 11:01:45.000000000 -0400 @@ -50,6 +50,7 @@ #include "xaa.h" #endif +#include "radeon_dri_bufmgr.h" extern DriverRec RADEON; #define RADEON_MAX_CRTC 2 @@ -159,6 +160,7 @@ typedef struct _RADEONCrtcPrivateRec { int can_tile; Bool enabled; Bool initialized; + } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr; typedef struct _radeon_encoder { @@ -612,6 +614,7 @@ typedef struct RADEONSaveRec SavedReg; /* Original (text) mode */ void *MMIO; /* Map of MMIO region */ + int fd; } RADEONEntRec, *RADEONEntPtr; /* radeon_probe.c */ diff -up xf86-video-ati-6.12.2/src/radeon_textured_video.c.modeset xf86-video-ati-6.12.2/src/radeon_textured_video.c --- xf86-video-ati-6.12.2/src/radeon_textured_video.c.modeset 2009-03-27 01:13:04.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_textured_video.c 2009-05-21 11:01:45.000000000 -0400 @@ -40,6 +40,7 @@ #include "radeon_macros.h" #include "radeon_probe.h" #include "radeon_video.h" +#include "radeon_drm.h" #include #include "fourcc.h" @@ -133,6 +134,7 @@ static __inline__ uint32_t float4touint( #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() #include "radeon_textured_videofuncs.c" @@ -142,6 +144,7 @@ static __inline__ uint32_t float4touint( #undef BEGIN_ACCEL #undef OUT_ACCEL_REG #undef OUT_ACCEL_REG_F +#undef OUT_RELOC #undef FINISH_ACCEL #ifdef XF86DRI @@ -155,6 +158,7 @@ static __inline__ uint32_t float4touint( #define OUT_ACCEL_REG_F(reg, val) OUT_ACCEL_REG(reg, F_TO_DW(val)) #define FINISH_ACCEL() ADVANCE_RING() #define OUT_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" @@ -412,6 +416,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn size * 2, 64); if (pPriv->video_offset == 0) return BadAlloc; + + if (info->new_cs) + pPriv->src_bo = pPriv->video_memory; } /* Bicubic filter loading */ @@ -422,6 +429,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn pPriv->bicubic_src_offset = pPriv->bicubic_offset + info->fbLocation + pScrn->fbOffset; if (pPriv->bicubic_offset == 0) pPriv->bicubic_enabled = FALSE; + + if (info->new_cs) + pPriv->bicubic_bo = pPriv->bicubic_memory; } if (pDraw->type == DRAWABLE_WINDOW) @@ -451,11 +461,21 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn left = (x1 >> 16) & ~1; npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; - pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset; - if (info->ChipFamily >= CHIP_FAMILY_R600) - pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset); - else - pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch)); + pPriv->src_offset = pPriv->video_offset; + if (info->new_cs) { + int ret; + radeon_bufmgr_gem_wait_rendering(pPriv->src_bo); + ret = dri_bo_map(pPriv->src_bo, 1); + if (ret) + return BadAlloc; + + pPriv->src_addr = pPriv->src_bo->virtual; + } else { + if (info->ChipFamily >= CHIP_FAMILY_R600) + pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset); + else + pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch)); + } pPriv->src_pitch = dstPitch; pPriv->planeu_offset = dstPitch * dst_height; pPriv->planev_offset = pPriv->planeu_offset + dstPitch2 * ((dst_height + 1) >> 1); @@ -481,12 +501,12 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn if (info->DMAForXv) { if (id == FOURCC_YV12) R600CopyPlanarHW(pScrn, buf, buf + s3offset, buf + s2offset, - pPriv->src_offset, + pPriv->src_offset + info->fbLocation + pScrn->fbOffset, srcPitch, srcPitch2, pPriv->src_pitch, width, height); else R600CopyPlanarHW(pScrn, buf, buf + s2offset, buf + s3offset, - pPriv->src_offset, + pPriv->src_offset + info->fbLocation + pScrn->fbOffset, srcPitch, srcPitch2, pPriv->src_pitch, width, height); } else { @@ -548,7 +568,7 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn default: if (info->ChipFamily >= CHIP_FAMILY_R600) { if (info->DMAForXv) - R600CopyPackedHW(pScrn, buf, pPriv->src_offset, + R600CopyPackedHW(pScrn, buf, pPriv->src_offset + info->fbLocation + pScrn->fbOffset, 2 * width, pPriv->src_pitch, width, height); else @@ -566,9 +586,25 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn /* Upload bicubic filter tex */ if (pPriv->bicubic_enabled) { - if (info->ChipFamily < CHIP_FAMILY_R600) - RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, - (uint8_t *)(info->FB + pPriv->bicubic_offset), 1024, 1024, 1, 512, 2); + if (info->ChipFamily < CHIP_FAMILY_R600) { + uint8_t *bicubic_addr; + int ret; + + if (info->new_cs) { + radeon_bufmgr_gem_wait_rendering(pPriv->bicubic_bo); + ret = dri_bo_map(pPriv->bicubic_bo, 1); + if (ret) + return BadAlloc; + + bicubic_addr = pPriv->bicubic_bo->virtual; + } else + bicubic_addr = (uint8_t *)(info->FB + pPriv->bicubic_offset); + + RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, bicubic_addr, 1024, 1024, 1, 512, 2); + + if (info->new_cs) + dri_bo_unmap(pPriv->bicubic_bo); + } } /* update cliplist */ @@ -586,10 +622,12 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn pPriv->w = width; pPriv->h = height; + if (info->new_cs) + dri_bo_unmap(pPriv->src_bo); #ifdef XF86DRI if (IS_R600_3D) R600DisplayTexturedVideo(pScrn, pPriv); - else if (info->directRenderingEnabled) + else if (info->directRenderingEnabled || info->drm_mode_setting) RADEONDisplayTexturedVideoCP(pScrn, pPriv); else #endif diff -up xf86-video-ati-6.12.2/src/radeon_textured_videofuncs.c.modeset xf86-video-ati-6.12.2/src/radeon_textured_videofuncs.c --- xf86-video-ati-6.12.2/src/radeon_textured_videofuncs.c.modeset 2009-05-21 11:01:45.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_textured_videofuncs.c 2009-05-21 11:01:45.000000000 -0400 @@ -87,11 +87,25 @@ do { \ #endif /* !ACCEL_CP */ +#define OUT_TEXTURE_REG(reg, offset, bo) do { \ + if (info->new_cs) { \ + OUT_ACCEL_REG((reg), (offset)); \ + OUT_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \ + } else { \ + OUT_ACCEL_REG((reg), (offset) + info->fbLocation + pScrn->fbOffset);} \ + } while(0) + + static void FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) { RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pPixmap = pPriv->pPixmap; + struct radeon_exa_pixmap_priv *driver_priv; + struct radeon_space_check bos[2]; + int i, ret; + int retry_count = 0; + dri_bo *dst_bo; uint32_t txformat; uint32_t txfilter, txformat0, txformat1, txoffset, txpitch; uint32_t dst_offset, dst_pitch, dst_format; @@ -101,19 +115,57 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc int dstxoff, dstyoff, pixel_shift, vtx_count; BoxPtr pBox = REGION_RECTS(&pPriv->clip); int nBox = REGION_NUM_RECTS(&pPriv->clip); + int qwords; ACCEL_PREAMBLE(); + retry: + if (info->new_cs) { + + i = 0; + bos[i].buf = pPriv->src_bo; + bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + bos[i].write_domain = 0; + i++; + + driver_priv = exaGetPixmapDriverPrivate(pPixmap); + dst_bo = driver_priv->bo; + bos[i].buf = driver_priv->bo; + bos[i].read_domains = 0; + bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;; + i++; + + ret = dri_bufmgr_check_aperture_space(bos, i); + if (ret == BUFMGR_SPACE_OP_TO_BIG) { + ErrorF("Not enough RAM to hw accel composite operation\n"); + return; + } + if (ret == BUFMGR_SPACE_FLUSH) { + RADEONCPFlushIndirect(pScrn, 1); + retry_count++; + if (retry_count == 2) { + ErrorF("Not enough RAM to hw accel composite operation\n"); + return; + } + goto retry; + } + } + pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; #ifdef USE_EXA if (info->useEXA) { - dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; + if (info->new_cs) { + driver_priv = exaGetPixmapDriverPrivate(pPixmap); + if (driver_priv) + dst_bo = driver_priv->bo; + } else { + 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; } @@ -144,7 +196,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc RADEON_WAIT_DMA_GUI_IDLE); FINISH_ACCEL(); - if (!info->accel_state->XInited3D) + if (!info->accel_state->XInited3D && !info->drm_mm) RADEONInit3DEngine(pScrn); } @@ -222,15 +274,19 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc if (IS_R500_3D && ((pPriv->h - 1) & 0x800)) txpitch |= R500_TXHEIGHT_11; - txoffset = pPriv->src_offset; + if (info->new_cs) + txoffset = 0; + else + txoffset = pPriv->src_offset; - BEGIN_ACCEL(6); + qwords = info->new_cs ? 7 : 6; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_0, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset); + OUT_TEXTURE_REG(R300_TX_OFFSET_0, txoffset, pPriv->src_bo); FINISH_ACCEL(); txenable = R300_TEX_0_ENABLE; @@ -246,19 +302,22 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc R300_TX_MIN_FILTER_LINEAR | R300_TX_MAG_FILTER_LINEAR); - BEGIN_ACCEL(12); + qwords = info->new_cs ? 14 : 12; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter | (1 << R300_TX_ID_SHIFT)); OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_1, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_2); OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset); + OUT_TEXTURE_REG(R300_TX_OFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo); + OUT_ACCEL_REG(R300_TX_FILTER0_2, txfilter | (2 << R300_TX_ID_SHIFT)); OUT_ACCEL_REG(R300_TX_FILTER1_2, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_2, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_2, R300_TX_FORMAT_X8 | R300_TX_FORMAT_CACHE_FOURTH_REGION_3); OUT_ACCEL_REG(R300_TX_FORMAT2_2, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset); + OUT_TEXTURE_REG(R300_TX_OFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo); + FINISH_ACCEL(); txenable |= R300_TEX_1_ENABLE | R300_TEX_2_ENABLE; } @@ -279,13 +338,19 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc R300_TX_MAG_FILTER_NEAREST | (1 << R300_TX_ID_SHIFT)); - BEGIN_ACCEL(6); + qwords = info->new_cs ? 7 : 6; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter); OUT_ACCEL_REG(R300_TX_FILTER1_1, 0); OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0); OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1); OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch); - OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset); + if (info->new_cs) { + OUT_ACCEL_REG(R300_TX_OFFSET_1, 0); + OUT_RELOC(pPriv->bicubic_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + } else { + OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset); + } FINISH_ACCEL(); /* Enable tex 1 */ @@ -1536,11 +1601,18 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc } } - BEGIN_ACCEL(6); + qwords = info->new_cs ? 8 : 6; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(R300_TX_INVALTAGS, 0); OUT_ACCEL_REG(R300_TX_ENABLE, txenable); - OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset); + if (info->new_cs) { + OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, 0); + OUT_RELOC(dst_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 = RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO; @@ -1587,11 +1659,19 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc if (RADEONTilingEnabled(pScrn, pPixmap)) colorpitch |= RADEON_COLOR_TILE_ENABLE; - BEGIN_ACCEL(4); + qwords = info->new_cs ? 5 : 4; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format /*| RADEON_ALPHA_BLEND_ENABLE*/); - OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + + if (info->new_cs) { + OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, 0); + OUT_RELOC(dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + } else { + dst_offset += info->fbLocation + pScrn->fbOffset; + OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset); + } OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch); @@ -1630,7 +1710,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc R200_CLAMP_S_CLAMP_LAST | R200_CLAMP_T_CLAMP_LAST; - BEGIN_ACCEL(36); + qwords = info->new_cs ? 39 : 36; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_1_ENABLE | RADEON_TEX_2_ENABLE | @@ -1649,21 +1730,22 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc (pPriv->w - 1) | ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo); OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat | R200_TXFORMAT_ST_ROUTE_STQ1); OUT_ACCEL_REG(R200_PP_TXFORMAT_X_1, 0); OUT_ACCEL_REG(R200_PP_TXSIZE_1, txformat0); OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch); - OUT_ACCEL_REG(R200_PP_TXOFFSET_1, pPriv->src_offset + pPriv->planeu_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_1, txoffset + pPriv->planeu_offset, pPriv->src_bo); OUT_ACCEL_REG(R200_PP_TXFILTER_2, txfilter); OUT_ACCEL_REG(R200_PP_TXFORMAT_2, txformat | R200_TXFORMAT_ST_ROUTE_STQ1); OUT_ACCEL_REG(R200_PP_TXFORMAT_X_2, 0); OUT_ACCEL_REG(R200_PP_TXSIZE_2, txformat0); OUT_ACCEL_REG(R200_PP_TXPITCH_2, txpitch); - OUT_ACCEL_REG(R200_PP_TXOFFSET_2, pPriv->src_offset + pPriv->planev_offset); + + OUT_TEXTURE_REG(R200_PP_TXOFFSET_2, txoffset + pPriv->planev_offset, pPriv->src_bo); /* similar to r300 code. Note the big problem is that hardware constants * are 8 bits only, representing 0.0-1.0. We can get that up (using bias @@ -1799,7 +1881,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc R200_CLAMP_S_CLAMP_LAST | R200_CLAMP_T_CLAMP_LAST; - BEGIN_ACCEL(24); + qwords = info->new_cs ? 25 : 24; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | @@ -1817,7 +1900,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc (pPriv->w - 1) | ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo); /* MAD temp1 / 2, const0.a * 2, temp0.ggg, -const0.rgb */ OUT_ACCEL_REG(R200_PP_TXCBLEND_0, @@ -1901,7 +1984,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc FINISH_ACCEL(); } else { - BEGIN_ACCEL(13); + qwords = info->new_cs ? 14 : 13; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); @@ -1922,7 +2006,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); - OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(R200_PP_TXOFFSET_0, txoffset, pPriv->src_bo); OUT_ACCEL_REG(R200_PP_TXCBLEND_0, R200_TXC_ARG_A_ZERO | @@ -1945,7 +2029,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc info->accel_state->texW[0] = 1; info->accel_state->texH[0] = 1; - BEGIN_ACCEL(9); + qwords = info->new_cs ? 10 : 9; + BEGIN_ACCEL(qwords); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); @@ -1959,8 +2044,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(Sc RADEON_CLAMP_S_CLAMP_LAST | RADEON_CLAMP_T_CLAMP_LAST | RADEON_YUV_TO_RGB); + OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat); - OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset); + OUT_TEXTURE_REG(RADEON_PP_TXOFFSET_0, txoffset, pPriv->src_bo); OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | diff -up xf86-video-ati-6.12.2/src/radeon_video.c.modeset xf86-video-ati-6.12.2/src/radeon_video.c --- xf86-video-ati-6.12.2/src/radeon_video.c.modeset 2009-04-07 11:31:32.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_video.c 2009-05-21 11:01:45.000000000 -0400 @@ -284,7 +284,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; @@ -294,9 +294,12 @@ void RADEONInitVideo(ScreenPtr pScreen) RADEONInitOffscreenImages(pScreen); } - if ((info->ChipFamily < CHIP_FAMILY_RS400) + if (info->ChipFamily >= CHIP_FAMILY_R600 && info->drm_mode_setting) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Disabling textured video for KMS On R600+\n"); + } else if ((info->ChipFamily < CHIP_FAMILY_RS400) #ifdef XF86DRI - || (info->directRenderingEnabled) + || (info->directRenderingEnabled || info->drm_mode_setting) #endif ) { texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen); @@ -2197,7 +2200,7 @@ RADEONCopyData( #ifdef XF86DRI - if ( info->directRenderingEnabled && info->DMAForXv ) + if ( info->directRenderingEnabled && info->DMAForXv && !info->new_cs ) { uint8_t *buf; uint32_t bufPitch, dstPitchOff; diff -up xf86-video-ati-6.12.2/src/radeon_video.h.modeset xf86-video-ati-6.12.2/src/radeon_video.h --- xf86-video-ati-6.12.2/src/radeon_video.h.modeset 2009-04-07 11:31:53.000000000 -0400 +++ xf86-video-ati-6.12.2/src/radeon_video.h 2009-05-21 11:01:45.000000000 -0400 @@ -121,6 +121,9 @@ typedef struct { int w, h; int drw_x, drw_y; int vsync; + + dri_bo *src_bo; + dri_bo *bicubic_bo; } RADEONPortPrivRec, *RADEONPortPrivPtr; xf86CrtcPtr