diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2010-03-01 14:26:51 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2010-03-02 08:19:08 -0800 |
commit | 7b01fc8f4ba1182370980f54a34bdb959e291e02 (patch) | |
tree | 3bf49f2f8f0648e76b2b5b0eaac508795ade0406 /src | |
parent | e6f4c9c6379b20b9fee50489d6afd05867c35967 (diff) |
Bug #26612: Separate LUTs per output.
Wire up the RandR 1.2 gamma_set hook. Call it from G80SetPalette like the Intel
driver does.
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Andy Ritger <aritger@nvidia.com>
Reviewed-by: Christian Zander <chzander@nvidia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/g80_display.c | 101 | ||||
-rw-r--r-- | src/g80_display.h | 1 | ||||
-rw-r--r-- | src/g80_driver.c | 56 |
3 files changed, 104 insertions, 54 deletions
diff --git a/src/g80_display.c b/src/g80_display.c index 0cb9860..8c8e5bd 100644 --- a/src/g80_display.c +++ b/src/g80_display.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 NVIDIA, Corporation + * Copyright (c) 2007,2010 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -42,6 +42,8 @@ typedef struct G80CrtcPrivRec { Bool cursorVisible; Bool skipModeFixup; Bool dither; + /* Look-up table values to be set when the CRTC is enabled */ + uint16_t lut_r[256], lut_g[256], lut_b[256]; } G80CrtcPrivRec, *G80CrtcPrivPtr; static void G80CrtcShowHideCursor(xf86CrtcPtr crtc, Bool show, Bool update); @@ -488,7 +490,7 @@ G80CrtcBlankScreen(xf86CrtcPtr crtc, Bool blank) if(pPriv->cursorVisible) G80CrtcShowHideCursor(crtc, TRUE, FALSE); C(0x00000840 + headOff, pScrn->depth == 8 ? 0x80000000 : 0xc0000000); - C(0x00000844 + headOff, (pNv->videoRam * 1024 - 0x5000) >> 8); + C(0x00000844 + headOff, (pNv->videoRam * 1024 - 0x5000 - 0x1000 * pPriv->head) >> 8); if(pNv->architecture != 0x50) C(0x0000085C + headOff, 1); C(0x00000874 + headOff, 1); @@ -646,9 +648,98 @@ G80CrtcCommit(xf86CrtcPtr crtc) } static void -G80DispGammaSet(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, - int size) +G80CrtcGammaSet(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, + int size) { + ScrnInfoPtr pScrn = crtc->scrn; + G80Ptr pNv = G80PTR(pScrn); + G80CrtcPrivPtr pPriv = crtc->driver_private; + int i; + volatile struct { + uint16_t red, green, blue, unused; + } *lut = (void*)&pNv->mem[pNv->videoRam * 1024 - 0x5000 - 0x1000 * pPriv->head]; + + assert(size == 256); + + for(i = 0; i < size; i++) { + pPriv->lut_r[i] = lut[i].red = red[i] >> 2; + pPriv->lut_g[i] = lut[i].green = green[i] >> 2; + pPriv->lut_b[i] = lut[i].blue = blue[i] >> 2; + } + + lut[256] = lut[255]; +} + +void +G80LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, + VisualPtr pVisual) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i, j, index; + int p; + uint16_t lut_r[256], lut_g[256], lut_b[256]; + + for(p = 0; p < xf86_config->num_crtc; p++) { + xf86CrtcPtr crtc = xf86_config->crtc[p]; + G80CrtcPrivPtr pPriv = crtc->driver_private; + + /* Initialize to the old lookup table values. */ + for(i = 0; i < 256; i++) { + lut_r[i] = pPriv->lut_r[i] << 2; + lut_g[i] = pPriv->lut_g[i] << 2; + lut_b[i] = pPriv->lut_b[i] << 2; + } + + switch(pScrn->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 << 8; + lut_g[index * 8 + j] = + colors[index].green << 8; + lut_b[index * 8 + j] = + colors[index].blue << 8; + } + } + break; + case 16: + for(i = 0; i < numColors; i++) { + index = indices[i]; + + if(index <= 31) { + for(j = 0; j < 8; j++) { + lut_r[index * 8 + j] = + colors[index].red << 8; + lut_b[index * 8 + j] = + colors[index].blue << 8; + } + } + + for(j = 0; j < 4; j++) { + lut_g[index * 4 + j] = + colors[index].green << 8; + } + } + break; + default: + for(i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 8; + lut_g[index] = colors[index].green << 8; + lut_b[index] = colors[index].blue << 8; + } + break; + } + + /* Make the change through RandR */ +#ifdef RANDR_12_INTERFACE + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); +#else + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); +#endif + } } static const xf86CrtcFuncsRec g80_crtc_funcs = { @@ -660,7 +751,7 @@ static const xf86CrtcFuncsRec g80_crtc_funcs = { .mode_fixup = G80CrtcModeFixup, .prepare = G80CrtcPrepare, .mode_set = G80CrtcModeSet, - .gamma_set = G80DispGammaSet, + .gamma_set = G80CrtcGammaSet, .commit = G80CrtcCommit, .shadow_create = NULL, .shadow_destroy = NULL, diff --git a/src/g80_display.h b/src/g80_display.h index 2031fed..43c6e12 100644 --- a/src/g80_display.h +++ b/src/g80_display.h @@ -22,5 +22,6 @@ void G80CrtcSetCursorPosition(xf86CrtcPtr, int x, int y); void G80CrtcSkipModeFixup(xf86CrtcPtr); void G80CrtcSetDither(xf86CrtcPtr, Bool dither, Bool update); void G80CrtcSetScale(xf86CrtcPtr, DisplayModePtr, enum G80ScaleMode); +void G80LoadPalette(ScrnInfoPtr, int numColors, int *indices, LOCO *, VisualPtr); void G80DispCreateCrtcs(ScrnInfoPtr pScrn); diff --git a/src/g80_driver.c b/src/g80_driver.c index 13e417a..8ea45af 100644 --- a/src/g80_driver.c +++ b/src/g80_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 NVIDIA, Corporation + * Copyright (c) 2007,2010 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -57,7 +57,7 @@ #include "g80_xaa.h" #define G80_REG_SIZE (1024 * 1024 * 16) -#define G80_RESERVED_VIDMEM 0xd000 +#define G80_RESERVED_VIDMEM 0xe000 typedef enum { OPTION_HW_CURSOR, @@ -630,7 +630,7 @@ G80InitHW(ScrnInfoPtr pScrn) pNv->reg[0x00003224/4] = 0x000f0078; pNv->reg[0x0000322c/4] = 0x00000644; - pNv->reg[0x00003234/4] = G80_RESERVED_VIDMEM - 0x5001; + pNv->reg[0x00003234/4] = G80_RESERVED_VIDMEM - 0x6001; pNv->reg[0x00003254/4] = 0x00000001; pNv->reg[0x00002210/4] = 0x1c001000; @@ -655,7 +655,7 @@ G80InitHW(ScrnInfoPtr pScrn) pNv->dmaPut = 0; pNv->dmaCurrent = SKIPS; - pNv->dmaMax = (G80_RESERVED_VIDMEM - 0x5000) / 4 - 2; + pNv->dmaMax = (G80_RESERVED_VIDMEM - 0x6000) / 4 - 2; pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; G80DmaStart(pNv, 0, 1); @@ -726,48 +726,6 @@ G80InitHW(ScrnInfoPtr pScrn) pNv->currentRop = ~0; /* Set to something invalid */ } -#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) -#define COLOR(c) (unsigned int)(0x3fff * ((c)/255.0)) -static void -G80LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, - VisualPtr pVisual) -{ - G80Ptr pNv = G80PTR(pScrn); - int i, index; - volatile struct { - unsigned short red, green, blue, unused; - } *lut = (void*)&pNv->mem[pNv->videoRam * 1024 - 0x5000]; - - switch(pScrn->depth) { - case 15: - for(i = 0; i < numColors; i++) { - index = indices[i]; - lut[DEPTH_SHIFT(index, 5)].red = COLOR(colors[index].red); - lut[DEPTH_SHIFT(index, 5)].green = COLOR(colors[index].green); - lut[DEPTH_SHIFT(index, 5)].blue = COLOR(colors[index].blue); - } - break; - case 16: - for(i = 0; i < numColors; i++) { - index = indices[i]; - lut[DEPTH_SHIFT(index, 6)].green = COLOR(colors[index].green); - if(index < 32) { - lut[DEPTH_SHIFT(index, 5)].red = COLOR(colors[index].red); - lut[DEPTH_SHIFT(index, 5)].blue = COLOR(colors[index].blue); - } - } - break; - default: - for(i = 0; i < numColors; i++) { - index = indices[i]; - lut[index].red = COLOR(colors[index].red); - lut[index].green = COLOR(colors[index].green); - lut[index].blue = COLOR(colors[index].blue); - } - break; - } -} - static Bool G80ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -866,6 +824,9 @@ G80ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) Must precede creation of the default colormap */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + if(!xf86CrtcScreenInit(pScreen)) + return FALSE; + /* Initialize default colormap */ if(!miCreateDefColormap(pScreen)) return FALSE; @@ -909,9 +870,6 @@ G80ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pNv->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = G80BlockHandler; - if(!xf86CrtcScreenInit(pScreen)) - return FALSE; - return TRUE; } |