Enable framebuffer compression (use Option "FrameBufferCompression"
"true" in your xorg.conf). Should save ~0.5W during typical 2D usage.
This commit is contained in:
parent
1e2e301348
commit
b384c60897
|
|
@ -77,6 +77,13 @@ driver attempts to allocate space for at 3 screenfuls of pixmaps plus an
|
|||
HD-sized XV video. The default used for a specific configuration can be found
|
||||
by examining the __xservername__ log file.
|
||||
.TP
|
||||
.BI "Option \*qFrameBufferCompression\*q \*q" boolean \*q
|
||||
This option controls whether the framebuffer compression feature is enabled.
|
||||
If possible, the front buffer will be allocated in a tiled format and compressed
|
||||
periodically to save memory bandwidth and power.
|
||||
.TP
|
||||
This option is only available on mobile chipsets.
|
||||
.TP
|
||||
.BI "Option \*qDRI\*q \*q" boolean \*q
|
||||
Disable or enable DRI support.
|
||||
Default: DRI is enabled for configurations where it is supported.
|
||||
|
|
|
|||
|
|
@ -287,6 +287,8 @@ typedef struct _I830Rec {
|
|||
|
||||
i830_memory *front_buffer;
|
||||
i830_memory *front_buffer_2;
|
||||
i830_memory *compressed_front_buffer;
|
||||
i830_memory *compressed_ll_buffer;
|
||||
/* One big buffer for all cursors for kernels that support this */
|
||||
i830_memory *cursor_mem;
|
||||
/* separate small buffers for kernels that support this */
|
||||
|
|
@ -342,6 +344,7 @@ typedef struct _I830Rec {
|
|||
Bool allowPageFlip;
|
||||
Bool TripleBuffer;
|
||||
Bool disableTiling;
|
||||
Bool fb_compression;
|
||||
|
||||
int backPitch;
|
||||
|
||||
|
|
|
|||
|
|
@ -653,15 +653,110 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
|
|||
#endif
|
||||
}
|
||||
|
||||
#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
|
||||
#define FBC_LL_BASE 0x03204 /* 4k page aligned */
|
||||
#define FBC_CONTROL 0x03208
|
||||
#define FBC_CTL_EN (1<<31)
|
||||
#define FBC_CTL_PERIODIC (1<<30)
|
||||
#define FBC_CTL_INTERVAL_SHIFT (16)
|
||||
#define FBC_CTL_STRIDE_SHIFT (5)
|
||||
#define FBC_CTL_FENCENO (1<<0)
|
||||
#define FBC_COMMAND 0x0320c
|
||||
#define FBC_CMD_COMPRESS (1<<0)
|
||||
#define FBC_STATUS 0x03210
|
||||
#define FBC_STAT_COMPRESSING (1<<31)
|
||||
#define FBC_STAT_COMPRESSED (1<<30)
|
||||
#define FBC_STAT_MODIFIED (1<<29)
|
||||
#define FBC_STAT_CURRENT_LINE (1<<0)
|
||||
#define FBC_CONTROL2 0x03214
|
||||
#define FBC_CTL_CPU_FENCE (1<<1)
|
||||
#define FBC_CTL_PIPEA (0<<0)
|
||||
#define FBC_CTL_PIPEB (1<<0)
|
||||
|
||||
#define FBC_COMPRESSED_LINES (1536+32)
|
||||
|
||||
/*
|
||||
* Several restrictions:
|
||||
* - DSP[AB]CNTR - no line duplication && no pixel multiplier
|
||||
* - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
|
||||
* - no alpha buffer discard
|
||||
* - no dual wide display
|
||||
* - progressive mode only (DSP[AB]CNTR)
|
||||
*
|
||||
* FIXME: verify above conditions are true
|
||||
*/
|
||||
static void
|
||||
i830_enable_fb_compression(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
uint32_t fbc_ctl;
|
||||
unsigned long compressed_stride;
|
||||
int pipe = intel_crtc->pipe;
|
||||
int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
|
||||
unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
|
||||
unsigned long interval = 1000;
|
||||
|
||||
compressed_stride = pI830->compressed_front_buffer->size /
|
||||
FBC_COMPRESSED_LINES;
|
||||
|
||||
if (uncompressed_stride < compressed_stride)
|
||||
compressed_stride = uncompressed_stride;
|
||||
|
||||
/* FBC_CTL wants 64B units */
|
||||
compressed_stride = (compressed_stride / 64) - 1;
|
||||
|
||||
/* Set it up... */
|
||||
OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
|
||||
OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr);
|
||||
OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
|
||||
|
||||
/* enable it... */
|
||||
fbc_ctl = INREG(FBC_CONTROL);
|
||||
fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
|
||||
fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
|
||||
fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
|
||||
OUTREG(FBC_CONTROL, fbc_ctl);
|
||||
|
||||
/* and request immediate compression */
|
||||
OUTREG(FBC_COMMAND, FBC_CMD_COMPRESS);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_disable_fb_compression(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
uint32_t fbc_ctl;
|
||||
|
||||
/* Disable compression */
|
||||
fbc_ctl = INREG(FBC_CONTROL);
|
||||
fbc_ctl &= ~FBC_CTL_EN;
|
||||
OUTREG(FBC_CONTROL, fbc_ctl);
|
||||
|
||||
/* Wait for compressing bit to clear */
|
||||
while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
|
||||
; /* nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
i830_crtc_prepare (xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
crtc->funcs->dpms (crtc, DPMSModeOff);
|
||||
|
||||
/* Temporarily turn off FB compression during modeset */
|
||||
if (pI830->fb_compression)
|
||||
i830_disable_fb_compression(crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_crtc_commit (xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
Bool deactivate = FALSE;
|
||||
|
||||
|
|
@ -675,6 +770,10 @@ i830_crtc_commit (xf86CrtcPtr crtc)
|
|||
xf86_reload_cursors (crtc->scrn->pScreen);
|
||||
if (deactivate)
|
||||
i830_pipe_a_require_deactivate (crtc->scrn);
|
||||
|
||||
/* Reenable FB compression if possible */
|
||||
if (pI830->fb_compression)
|
||||
i830_enable_fb_compression(crtc);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ typedef enum {
|
|||
OPTION_COLOR_KEY,
|
||||
OPTION_CHECKDEVICES,
|
||||
OPTION_MODEDEBUG,
|
||||
OPTION_FBC,
|
||||
#ifdef XF86DRI_MM
|
||||
OPTION_INTELTEXPOOL,
|
||||
OPTION_INTELMMSIZE,
|
||||
|
|
@ -306,6 +307,7 @@ static OptionInfoRec I830Options[] = {
|
|||
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE},
|
||||
{OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_FBC, "FrameBufferCompression", OPTV_BOOLEAN, {0}, FALSE},
|
||||
#ifdef XF86DRI_MM
|
||||
{OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE},
|
||||
|
|
@ -2305,6 +2307,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
pI830->CacheLines = -1;
|
||||
}
|
||||
|
||||
if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
|
||||
pI830->fb_compression = TRUE;
|
||||
else
|
||||
pI830->fb_compression = FALSE;
|
||||
|
||||
pI830->disableTiling = FALSE;
|
||||
|
||||
if (I830IsPrimary(pScrn)) {
|
||||
|
|
|
|||
|
|
@ -902,8 +902,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
|
|||
name = secondary ? "secondary front buffer" : "front buffer";
|
||||
|
||||
/* Attempt to allocate it tiled first if we have page flipping on. */
|
||||
if (!pI830->disableTiling && pI830->allowPageFlip &&
|
||||
IsTileable(pScrn, pitch))
|
||||
if ((!pI830->disableTiling && pI830->allowPageFlip &&
|
||||
IsTileable(pScrn, pitch)) || pI830->fb_compression)
|
||||
{
|
||||
/* XXX: probably not the case on 965 */
|
||||
if (IS_I9XX(pI830))
|
||||
|
|
@ -1022,6 +1022,56 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
/* Only mobile chips since 845 support this feature */
|
||||
if (!IS_MOBILE(pI830)) {
|
||||
pI830->fb_compression = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compressed framebuffer limitations:
|
||||
* - contiguous, physical, uncached memory
|
||||
* - ideally as large as the front buffer(s), smaller sizes cache less
|
||||
* - uncompressed buffer must be tiled w/pitch 2k-16k
|
||||
* - uncompressed fb is <= 2048 in width, 0 mod 8
|
||||
* - uncompressed fb is <= 1536 in height, 0 mod 2
|
||||
* - compressed fb stride is <= uncompressed stride
|
||||
* - SR display watermarks must be equal between 16bpp and 32bpp?
|
||||
* - both compressed and line buffers must be in stolen memory
|
||||
*/
|
||||
pI830->compressed_front_buffer =
|
||||
i830_allocate_memory(pScrn, "compressed frame buffer",
|
||||
MB(6), KB(4),
|
||||
NEED_PHYSICAL_ADDR);
|
||||
|
||||
if (!pI830->compressed_front_buffer) {
|
||||
pI830->fb_compression = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pI830->compressed_ll_buffer =
|
||||
i830_allocate_memory(pScrn, "compressed ll buffer",
|
||||
1568, KB(4), NEED_PHYSICAL_ADDR);
|
||||
if (!pI830->compressed_ll_buffer) {
|
||||
i830_free_memory(pScrn, pI830->compressed_front_buffer);
|
||||
pI830->fb_compression = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (pI830->fb_compression)
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression "
|
||||
"enabled\n");
|
||||
else
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer"
|
||||
" compression disabled\n");
|
||||
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Allocate memory for 2D operation. This includes the (front) framebuffer,
|
||||
* ring buffer, scratch memory, HW cursor.
|
||||
|
|
@ -1046,6 +1096,9 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
|
|||
/* Allocate the ring buffer first, so it ends up in stolen mem. */
|
||||
i830_allocate_ringbuffer(pScrn);
|
||||
|
||||
if (pI830->fb_compression)
|
||||
i830_setup_fb_compression(pScrn);
|
||||
|
||||
/* Next, allocate other fixed-size allocations we have. */
|
||||
if (!pI830->SWCursor && !i830_allocate_cursor_buffers(pScrn)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
|
|
|
|||
Loading…
Reference in New Issue