diff -Nru xserver-xorg-video-ati-6.8.0/src/radeon_video.c xserver-xorg-video-ati-6.8.0.fixed_gamma/src/radeon_video.c --- xserver-xorg-video-ati-6.8.0/src/radeon_video.c 2008-02-19 02:10:46.000000000 +0100 +++ xserver-xorg-video-ati-6.8.0.fixed_gamma/src/radeon_video.c 2008-05-16 23:42:00.000000000 +0200 @@ -850,19 +850,42 @@ /* Set gamma */ RADEONWaitForIdleMMIO(pScrn); ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL) & ~RADEON_SCALER_GAMMA_SEL_MASK; - OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 0x00000005)); + if (info->ChipFamily <= CHIP_FAMILY_R200) { + /* this breaks my r300 (pink picture) + * for gamma != 1.0 (gamma != 0). + * I suspect this is really for much older Radeons (r100?) which + * didn't have the RADEON_OV0_GAMMA_* registers */ + OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl | (gamma << 0x00000005)); + } else { + OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl); + } /* Load gamma curve adjustments */ if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREG(RADEON_OV0_GAMMA_000_00F, - (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) | - (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010)); - OUTREG(RADEON_OV0_GAMMA_010_01F, - (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | - (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010)); - OUTREG(RADEON_OV0_GAMMA_020_03F, - (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | - (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010)); + if (info->ChipFamily >= CHIP_FAMILY_R300) { + /* It looks like the slope values have to be shifted by + * additional 2bits/1bit to yield the expected result + * on my two r300 cards */ + OUTREG(RADEON_OV0_GAMMA_000_00F, + (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) | + (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000012)); + OUTREG(RADEON_OV0_GAMMA_010_01F, + (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | + (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000012)); + OUTREG(RADEON_OV0_GAMMA_020_03F, + (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | + (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000011)); + } else { + OUTREG(RADEON_OV0_GAMMA_000_00F, + (gamma_curve_r200[gamma].GAMMA_0_F_OFFSET << 0x00000000) | + (gamma_curve_r200[gamma].GAMMA_0_F_SLOPE << 0x00000010)); + OUTREG(RADEON_OV0_GAMMA_010_01F, + (gamma_curve_r200[gamma].GAMMA_10_1F_OFFSET << 0x00000000) | + (gamma_curve_r200[gamma].GAMMA_10_1F_SLOPE << 0x00000010)); + OUTREG(RADEON_OV0_GAMMA_020_03F, + (gamma_curve_r200[gamma].GAMMA_20_3F_OFFSET << 0x00000000) | + (gamma_curve_r200[gamma].GAMMA_20_3F_SLOPE << 0x00000010)); + } OUTREG(RADEON_OV0_GAMMA_040_07F, (gamma_curve_r200[gamma].GAMMA_40_7F_OFFSET << 0x00000000) | (gamma_curve_r200[gamma].GAMMA_40_7F_SLOPE << 0x00000010));