From 1768af38c737f4c14d32f587b51a8ec3d3d6ed5f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 13 Dec 2007 15:06:18 -0500 Subject: [PATCH] Add infrastructure for validating modes by memory bandwidth. --- hw/xfree86/common/xf86Mode.c | 2 ++ hw/xfree86/common/xf86str.h | 1 + hw/xfree86/modes/xf86Modes.c | 37 ++++++++++++++++++++++++++++++++++++ hw/xfree86/modes/xf86Modes.h | 5 +++++ 4 files changed, 45 insertions(+) diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index 544276bdf..782f08b8d 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -183,6 +183,8 @@ xf86ModeStatusToString(ModeStatus status) return "all modes must have the same resolution"; case MODE_NO_REDUCED: return "monitor doesn't support reduced blanking"; + case MODE_BANDWIDTH: + return "mode requires too much memory bandwidth"; case MODE_BAD: return "unknown reason"; case MODE_ERROR: diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index af98b4fd5..2e0213597 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -125,6 +125,7 @@ typedef enum { MODE_ONE_HEIGHT, /* only one height is supported */ MODE_ONE_SIZE, /* only one resolution is supported */ MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */ + MODE_BANDWIDTH, /* mode requires too much memory bandwidth */ MODE_BAD = -2, /* unspecified reason */ MODE_ERROR = -1 /* error condition */ } ModeStatus; diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index 12ee6e05b..3febd3759 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -118,6 +118,24 @@ xf86ModeHeight (DisplayModePtr mode, Rotation rotation) } } +/** Calculates the memory bandwidth (in MiB/sec) of a mode. */ +_X_EXPORT unsigned int +xf86ModeBandwidth(DisplayModePtr mode, int depth) +{ + float a_active, a_total, active_percent, pixels_per_second; + int bytes_per_pixel = (depth + 7) / 8; + + if (!mode->HTotal || !mode->VTotal || !mode->Clock) + return 0; + + a_active = mode->HDisplay * mode->VDisplay; + a_total = mode->HTotal * mode->VTotal; + active_percent = a_active / a_total; + pixels_per_second = active_percent * mode->Clock * 1000.0; + + return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024)); +} + /** Sets a default mode name of x on a mode. */ _X_EXPORT void xf86SetModeDefaultName(DisplayModePtr mode) @@ -485,6 +503,25 @@ xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) } +/** + * Marks as bad any modes exceeding the given bandwidth. + * + * \param modeList doubly-linked or circular list of modes. + * \param bandwidth bandwidth in MHz. + * \param depth color depth. + */ +_X_EXPORT void +xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList, + unsigned int bandwidth, int depth) +{ + DisplayModePtr mode; + + for (mode = modeList; mode != NULL; mode = mode->next) { + if (xf86ModeBandwidth(mode, depth) > bandwidth) + mode->status = MODE_BANDWIDTH; + } +} + /** * Frees any modes from the list with a status other than MODE_OK. * diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h index 3722d25a0..9ad5ee653 100644 --- a/hw/xfree86/modes/xf86Modes.h +++ b/hw/xfree86/modes/xf86Modes.h @@ -42,6 +42,7 @@ double xf86ModeHSync(DisplayModePtr mode); double xf86ModeVRefresh(DisplayModePtr mode); +unsigned int xf86ModeBandwidth(DisplayModePtr mode, int depth); int xf86ModeWidth (DisplayModePtr mode, Rotation rotation); @@ -78,6 +79,10 @@ void xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, MonPtr mon); +void +xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList, + unsigned int bandwidth, int depth); + void xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, Bool verbose);