diff options
author | Eric Anholt <eric@anholt.net> | 2007-08-16 11:30:16 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-08-16 11:30:16 -0700 |
commit | 0c9e4aeea84e20a18e3b76d8cf8e802af004df57 (patch) | |
tree | ed4e5daf4bf77bbc89bf2936ca33d554f23ad7b1 | |
parent | 79d9a309b19e22561e000a47b732c67479c2e6d4 (diff) | |
parent | 2231cdcd8f1ee81b3e59cc5e3a325c22ee0f40e4 (diff) |
Merge branch 'master' into buffer-objects
Conflicts:
src/i830_dri.c
src/i830_memory.c
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | man/intel.man | 4 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/bios_reader/bios_dumper.c | 3 | ||||
-rw-r--r-- | src/i810.h | 4 | ||||
-rw-r--r-- | src/i810_reg.h | 12 | ||||
-rw-r--r-- | src/i830.h | 38 | ||||
-rw-r--r-- | src/i830_bios.h | 3 | ||||
-rw-r--r-- | src/i830_debug.c | 32 | ||||
-rw-r--r-- | src/i830_display.c | 256 | ||||
-rw-r--r-- | src/i830_dri.c | 14 | ||||
-rw-r--r-- | src/i830_driver.c | 24 | ||||
-rw-r--r-- | src/i830_exa.c | 114 | ||||
-rw-r--r-- | src/i830_lvds.c | 117 | ||||
-rw-r--r-- | src/i830_memory.c | 129 | ||||
-rw-r--r-- | src/i830_quirks.c | 84 | ||||
-rw-r--r-- | src/i830_reg.h | 7 | ||||
-rw-r--r-- | src/i830_tv.c | 9 | ||||
-rw-r--r-- | src/i830_xaa.c | 114 | ||||
-rw-r--r-- | src/i915_render.c | 25 | ||||
-rw-r--r-- | src/i915_video.c | 16 | ||||
-rw-r--r-- | src/i965_render.c | 42 | ||||
-rw-r--r-- | src/i965_video.c | 3 |
23 files changed, 650 insertions, 411 deletions
diff --git a/configure.ac b/configure.ac index 9b76b652..8c2b5ec6 100644 --- a/configure.ac +++ b/configure.ac @@ -26,16 +26,6 @@ AC_INIT([xf86-video-intel], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) -AC_DEFINE_UNQUOTED([INTEL_VERSION_MAJOR], - [$(echo $PACKAGE_VERSION | sed -e 's/^\([[0-9]]*\)\.[[0-9]]*\.[[0-9]]*/\1/')], - [Major version]) -AC_DEFINE_UNQUOTED([INTEL_VERSION_MINOR], - [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]*\.\([[0-9]]*\)\.[[0-9]]*/\1/')], - [Minor version]) -AC_DEFINE_UNQUOTED([INTEL_VERSION_PATCH], - [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)/\1/')], - [Patch version]) - AC_CONFIG_SRCDIR([Makefile.am]) AM_CONFIG_HEADER([config.h]) AC_CONFIG_AUX_DIR(.) diff --git a/man/intel.man b/man/intel.man index c682d550..efe34d7e 100644 --- a/man/intel.man +++ b/man/intel.man @@ -85,7 +85,7 @@ Default: enabled on supported configurations. .BI "Option \*qTiling\*q \*q" boolean \*q This option controls whether memory buffers are allocated in tiled mode. In many cases (especially for complex rendering), tiling can improve performance. -Default: enabled on supported configurations. +Default: enabled. .TP .BI "Option \*qDRI\*q \*q" boolean \*q Disable or enable DRI support. @@ -140,7 +140,7 @@ and that is used with the 3D driver in Mesa from version 6.5.2 and upwards. If the size is set too high to make room for pre-allocated VideoRam, the driver will try to reduce it automatically. If you use only older Mesa or DRM versions, you may set this value to zero, and -atctivate the legacy texture pool (see +activate the legacy texture pool (see .B "Option \*qLegacy3D\*q" ). If you run 3D programs with large texture memory requirements, you might gain some performance by increasing this value. diff --git a/src/Makefile.am b/src/Makefile.am index 858ffd17..50e913ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,6 +90,7 @@ intel_drv_la_SOURCES = \ i830_debug.h \ i830_display.c \ i830_display.h \ + i830_quirks.c \ i830_driver.c \ i830_dvo.c \ i830.h \ diff --git a/src/bios_reader/bios_dumper.c b/src/bios_reader/bios_dumper.c index c0dbdcf8..6f163d56 100644 --- a/src/bios_reader/bios_dumper.c +++ b/src/bios_reader/bios_dumper.c @@ -29,6 +29,7 @@ #include <stdlib.h> #include <string.h> #include <stdarg.h> +#include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <pciaccess.h> @@ -80,7 +81,7 @@ int main(int argc, char **argv) exit(1); } - fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC); + fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE); if (fd < 0) { fprintf(stderr, "Couldn't open output: %s\n", strerror(errno)); exit(1); @@ -66,6 +66,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I810_DRIVER_NAME "intel" #define I810_LEGACY_DRIVER_NAME "i810" +#define INTEL_VERSION_MAJOR PACKAGE_VERSION_MAJOR +#define INTEL_VERSION_MINOR PACKAGE_VERSION_MINOR +#define INTEL_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL + /* HWMC Surfaces */ #define I810_MAX_SURFACES 7 #define I810_MAX_SUBPICTURES 2 diff --git a/src/i810_reg.h b/src/i810_reg.h index 248df049..03e10d64 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -822,6 +822,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define PP_SEQUENCE_MASK 0x30000000 #define PP_CONTROL 0x61204 +# define POWER_DOWN_ON_RESET (1 << 1) # define POWER_TARGET_ON (1 << 0) #define LVDSPP_ON 0x61208 @@ -1066,6 +1067,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define BLC_PWM_CTL 0x61254 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +#define BACKLIGHT_MODULATION_FREQ_SHIFT2 (16) /** * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control. @@ -1073,7 +1075,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * The actual value is this field multiplied by two. */ #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BACKLIGHT_MODULATION_FREQ_MASK2 (0xffff << 16) #define BLM_LEGACY_MODE (1 << 16) + /** * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. @@ -1084,6 +1088,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) +/* On 965+ backlight control is in another register */ +#define BLC_PWM_CTL2 0x61250 +#define BLM_LEGACY_MODE2 (1 << 30) + #define BLM_CTL 0x61260 #define BLM_THRESHOLD_0 0x61270 #define BLM_THRESHOLD_1 0x61274 @@ -2021,6 +2029,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DSPBCNTR 0x71180 #define DISPLAY_PLANE_ENABLE (1<<31) #define DISPLAY_PLANE_DISABLE 0 +#define DISPLAY_PLANE_TILED (1<<10) #define DISPPLANE_GAMMA_ENABLE (1<<30) #define DISPPLANE_GAMMA_DISABLE 0 #define DISPPLANE_PIXFORMAT_MASK (0xf<<26) @@ -2160,12 +2169,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4)) #define XY_COLOR_BLT_WRITE_ALPHA (1<<21) #define XY_COLOR_BLT_WRITE_RGB (1<<20) +#define XY_COLOR_BLT_TILED (1<<11) #define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1) #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) +#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) +#define XY_SRC_COPY_BLT_DST_TILED (1<<11) #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4) #define SRC_COPY_BLT_WRITE_ALPHA (1<<21) @@ -117,6 +117,12 @@ typedef CARD8(*I830ReadIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr, typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value); typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr); +enum tile_format { + TILE_NONE, + TILE_XMAJOR, + TILE_YMAJOR +}; + /** Record of a linear allocation in the aperture. */ typedef struct _i830_memory i830_memory; struct _i830_memory { @@ -148,6 +154,8 @@ struct _i830_memory { */ unsigned long agp_offset; + enum tile_format tiling; + /** Description of the allocation, for logging */ char *name; @@ -326,8 +334,6 @@ typedef struct _I830Rec { i830_memory *logical_context; - unsigned int front_tiled; - #ifdef XF86DRI i830_memory *back_buffer; i830_memory *third_buffer; @@ -340,10 +346,6 @@ typedef struct _I830Rec { int drmMinor; Bool allocate_classic_textures; - unsigned int back_tiled; - unsigned int third_tiled; - unsigned int depth_tiled; - Bool want_vblank_interrupts; #ifdef DAMAGE DamagePtr pDamage; @@ -414,9 +416,8 @@ typedef struct _I830Rec { CloseScreenProcPtr CloseScreen; #ifdef I830_USE_EXA - unsigned int copy_src_pitch; - unsigned int copy_src_off; ExaDriverPtr EXADriverPtr; + PixmapPtr pSrcPixmap; #endif I830WriteIndexedByteFunc writeControl; @@ -507,6 +508,7 @@ typedef struct _I830Rec { CARD32 saveDSPAPOS; CARD32 saveDSPABASE; CARD32 saveDSPASURF; + CARD32 saveDSPATILEOFF; CARD32 saveFPB0; CARD32 saveFPB1; CARD32 saveDPLL_B; @@ -523,6 +525,7 @@ typedef struct _I830Rec { CARD32 saveDSPBPOS; CARD32 saveDSPBBASE; CARD32 saveDSPBSURF; + CARD32 saveDSPBTILEOFF; CARD32 saveVCLK_DIVISOR_VGA0; CARD32 saveVCLK_DIVISOR_VGA1; CARD32 saveVCLK_POST_DIV; @@ -541,6 +544,7 @@ typedef struct _I830Rec { CARD32 savePaletteB[256]; CARD32 saveSWF[17]; CARD32 saveBLC_PWM_CTL; + CARD32 saveBLC_PWM_CTL2; CARD32 saveFBC_CFB_BASE; CARD32 saveFBC_LL_BASE; CARD32 saveFBC_CONTROL2; @@ -550,6 +554,7 @@ typedef struct _I830Rec { /** Enables logging of debug output related to mode switching. */ Bool debug_modes; + unsigned int quirk_flag; } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) @@ -730,17 +735,8 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, void i830_enter_render(ScrnInfoPtr); -static inline int i830_tiling_supported(I830Ptr pI830) -{ - if (IS_I965G(pI830)) - return FALSE; - return TRUE; -} - static inline int i830_fb_compression_supported(I830Ptr pI830) { - if (!i830_tiling_supported(pI830)) - return FALSE; if (!IS_MOBILE(pI830)) return FALSE; if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830)) @@ -748,6 +744,8 @@ static inline int i830_fb_compression_supported(I830Ptr pI830) return TRUE; } +Bool i830_pixmap_tiled(PixmapPtr p); + extern const int I830PatternROP[16]; extern const int I830CopyROP[16]; @@ -763,4 +761,10 @@ extern const int I830CopyROP[16]; #define _845_DRAM_RW_CONTROL 0x90 #define DRAM_WRITE 0x33330000 +/* quirk flag definition */ +#define QUIRK_IGNORE_TV 0x00000001 +#define QUIRK_IGNORE_LVDS 0x00000002 +#define QUIRK_IGNORE_MACMINI_LVDS 0x00000004 +extern void i830_fixup_devices(ScrnInfoPtr); + #endif /* _I830_H_ */ diff --git a/src/i830_bios.h b/src/i830_bios.h index cb7666e3..9e8356a1 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -130,9 +130,6 @@ struct aimdb_block { CARD16 aimdb_size; } __attribute__((packed)); -struct vch_bdb_20 { -} __attribute__((packed)); - struct vch_panel_data { CARD16 fp_timing_offset; CARD8 fp_timing_size; diff --git a/src/i830_debug.c b/src/i830_debug.c index 055ca932..8b4b76f4 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -334,6 +334,19 @@ DEBUGSTRING(i830_debug_sdvo) enable, pipe, stall, detected, sdvoextra, gang); } +#if 0 +DEBUGSTRING(i810_debug_fence_new) +{ + char *enable = (val & FENCE_VALID) ? "enabled" : "disabled"; + char format = (val & I965_FENCE_Y_MAJOR) ? 'Y' : 'X'; + int pitch = ((val & 0xffc) >> 2) * 128; + unsigned int offset = val & 0xfffff000; + + return XNFprintf("%s, %c tile walk, %d pitch, 0x%08x offset", + enable, format, pitch, offset); +} +#endif + #define DEFINEREG(reg) \ { reg, #reg, NULL, 0 } #define DEFINEREG2(reg, func) \ @@ -465,6 +478,25 @@ static struct i830SnapshotRec { DEFINEREG(TV_H_LUMA_59), DEFINEREG(TV_H_CHROMA_0), DEFINEREG(TV_H_CHROMA_59), + +#if 0 + DEFINEREG2(FENCE_NEW + 0, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 8, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 16, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 24, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 32, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 40, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 48, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 56, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 64, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 72, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 80, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 88, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 96, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 104, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 112, i810_debug_fence_new), + DEFINEREG2(FENCE_NEW + 120, i810_debug_fence_new), +#endif }; #undef DEFINEREG #define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0])) diff --git a/src/i830_display.c b/src/i830_display.c index 26873fef..706b9ba8 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -375,6 +375,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) unsigned long Start, Offset; int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF); Offset = ((y * pScrn->displayWidth + x) * pI830->cpp); if (pI830->front_buffer == NULL) { @@ -399,6 +400,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) POSTING_READ(dspbase); OUTREG(dspsurf, Start); POSTING_READ(dspsurf); + OUTREG(dsptileoff, (y << 16) | x); } else { OUTREG(dspbase, Start + Offset); POSTING_READ(dspbase); @@ -498,6 +500,143 @@ i830_pipe_a_require_deactivate (ScrnInfoPtr scrn) return; } +/* FIXME: use pixmap private instead if possible */ +static Bool +i830_display_tiled(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + + /* Rotated data is currently linear, allocated either via XAA or EXA */ + if (crtc->rotatedData) + return FALSE; + + if (pI830->front_buffer && pI830->front_buffer->tiling != TILE_NONE) + return TRUE; + + return FALSE; +} + +static Bool +i830_use_fb_compression(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int pipe = intel_crtc->pipe; + int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); + + if (!pI830->fb_compression) + return FALSE; + + if (!i830_display_tiled(crtc)) + return FALSE; + + /* Pre-965 only supports plane A */ + if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) + return FALSE; + + /* Need 15, 16, or 32 (w/alpha) pixel format */ + if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ + pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ + return FALSE; + + /* + * No checks for pixel multiply, incl. horizontal, or interlaced modes + * since they're currently unused. + */ + return TRUE; +} + +/* + * 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) + * - uncompressed fb is <= 2048 in width, 0 mod 8 + * - uncompressed fb is <= 1536 in height, 0 mod 2 + * - SR display watermarks must be equal between 16bpp and 32bpp? + * + * 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 = 0; + unsigned long compressed_stride; + int pipe = intel_crtc->pipe; + /* FIXME: plane & pipe might not always be equal */ + int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); + unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp; + unsigned long interval = 1000; + + if (INREG(FBC_CONTROL) & FBC_CTL_EN) { + char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a'; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on " + "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' : + 'a'); + return; + } + + compressed_stride = pI830->compressed_front_buffer->size / + FBC_LL_SIZE; + + if (uncompressed_stride < compressed_stride) + compressed_stride = uncompressed_stride; + + /* FBC_CTL wants 64B units */ + compressed_stride = (compressed_stride / 64) - 1; + + /* Set it up... */ + /* Wait for compressing bit to clear */ + while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING) + ; /* nothing */ + i830WaitForVblank(pScrn); + OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr); + OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6); + OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL | + FBC_CTL_CPU_FENCE | plane); + + /* Zero buffers */ + memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, + pI830->compressed_front_buffer->size); + memset(pI830->FbBase + pI830->compressed_ll_buffer->offset, 0, + pI830->compressed_ll_buffer->size); + + /* enable it... */ + 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; + fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE; + OUTREG(FBC_CONTROL, fbc_ctl); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", pipe ? + 'b' : 'a'); +} + +static void +i830_disable_fb_compression(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + uint32_t fbc_ctl; + char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a'; + + /* 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 */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe); +} /** * Sets the power management mode of the pipe and plane. @@ -561,8 +700,16 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Give the overlay scaler a chance to enable if it's on this pipe */ i830_crtc_dpms_video(crtc, TRUE); + + /* Reenable compression if needed */ + if (i830_use_fb_compression(crtc)) + i830_enable_fb_compression(crtc); break; case DPMSModeOff: + /* Shut off compression if in use */ + if (i830_use_fb_compression(crtc)) + i830_disable_fb_compression(crtc); + /* Give the overlay scaler a chance to disable if it's on this pipe */ i830_crtc_dpms_video(crtc, FALSE); @@ -656,112 +803,6 @@ i830_crtc_unlock (xf86CrtcPtr crtc) #endif } -static Bool -i830_use_fb_compression(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); - - if (!pI830->fb_compression) - return FALSE; - - /* Pre-965 only supports plane A */ - if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) - return FALSE; - - /* Need 15, 16, or 32 (w/alpha) pixel format */ - if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ - pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ - return FALSE; - - /* - * No checks for pixel multiply, incl. horizontal, or interlaced modes - * since they're currently unused. - */ - return TRUE; -} - -/* - * 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) - * - uncompressed fb is <= 2048 in width, 0 mod 8 - * - uncompressed fb is <= 1536 in height, 0 mod 2 - * - SR display watermarks must be equal between 16bpp and 32bpp? - * - * 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_PLANEA : FBC_CTL_PLANEB); - unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp; - unsigned long interval = 1000; - - if (INREG(FBC_CONTROL) & FBC_CTL_EN) { - char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a'; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on " - "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' : - 'a'); - return; - } - - compressed_stride = pI830->compressed_front_buffer->size / - FBC_LL_SIZE; - - 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 + FBC_LL_PAD); - 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); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ? - 'b' : 'a'); -} - -static void -i830_disable_fb_compression(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t fbc_ctl; - char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a'; - - /* 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 */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe); -} - static void i830_crtc_prepare (xf86CrtcPtr crtc) { @@ -1059,6 +1100,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, else dspcntr |= DISPPLANE_SEL_PIPE_B; + if (IS_I965G(pI830) && i830_display_tiled(crtc)) + dspcntr |= DISPLAY_PLANE_TILED; + pipeconf = INREG(pipeconf_reg); if (pipe == 0 && !IS_I965G(pI830)) { diff --git a/src/i830_dri.c b/src/i830_dri.c index f97edd77..c25a0843 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -593,7 +593,8 @@ I830DRIScreenInit(ScreenPtr pScreen) #if DRIINFO_MAJOR_VERSION > 5 || \ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3) - pDRIInfo->texOffsetStart = I830TexOffsetStart; + if (pI830->useEXA) + pDRIInfo->texOffsetStart = I830TexOffsetStart; #endif #if DRI_SUPPORTS_CLIP_NOTIFY @@ -1636,10 +1637,13 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) I830DRIUnmapScreenRegions(pScrn, sarea); - sarea->front_tiled = pI830->front_tiled; - sarea->back_tiled = pI830->back_tiled; - sarea->third_tiled = pI830->third_tiled; - sarea->depth_tiled = pI830->depth_tiled; + sarea->front_tiled = (pI830->front_buffer->tiling != TILE_NONE); + sarea->back_tiled = (pI830->back_buffer->tiling != TILE_NONE); + if (pI830->third_buffer != NULL) + sarea->third_tiled = (pI830->third_buffer->tiling != TILE_NONE); + else + sarea->third_tiled = FALSE; + sarea->depth_tiled = (pI830->depth_buffer->tiling != TILE_NONE); sarea->rotated_tiled = FALSE; sarea->front_offset = pI830->front_buffer->offset; diff --git a/src/i830_driver.c b/src/i830_driver.c index c86840a1..1fbf9d56 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1239,6 +1239,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", (unsigned long)pI830->MMIOAddr); + /* check quirks */ + i830_fixup_devices(pScrn); + /* Allocate an xf86CrtcConfig */ xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -1832,6 +1835,8 @@ SaveHWState(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { pI830->saveDSPASURF = INREG(DSPASURF); pI830->saveDSPBSURF = INREG(DSPBSURF); + pI830->saveDSPATILEOFF = INREG(DSPATILEOFF); + pI830->saveDSPBTILEOFF = INREG(DSPBTILEOFF); } pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0); @@ -1926,7 +1931,10 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(PIPEASRC, pI830->savePIPEASRC); OUTREG(DSPABASE, pI830->saveDSPABASE); if (IS_I965G(pI830)) + { OUTREG(DSPASURF, pI830->saveDSPASURF); + OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF); + } OUTREG(PIPEACONF, pI830->savePIPEACONF); i830WaitForVblank(pScrn); OUTREG(DSPACNTR, pI830->saveDSPACNTR); @@ -1963,7 +1971,10 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(PIPEBSRC, pI830->savePIPEBSRC); OUTREG(DSPBBASE, pI830->saveDSPBBASE); if (IS_I965G(pI830)) + { OUTREG(DSPBSURF, pI830->saveDSPBSURF); + OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF); + } OUTREG(PIPEBCONF, pI830->savePIPEBCONF); i830WaitForVblank(pScrn); OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); @@ -2277,11 +2288,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->CacheLines = -1; } - /* Enable tiling by default where supported */ - if (i830_tiling_supported(pI830)) - pI830->tiling = TRUE; - else - pI830->tiling = FALSE; + /* Enable tiling by default */ + pI830->tiling = TRUE; /* Allow user override if they set a value */ if (xf86IsOptionSet(pI830->Options, OPTION_TILING)) { @@ -2305,12 +2313,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->fb_compression = FALSE; } - if (pI830->fb_compression) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, " - "forcing tiling on.\n"); - pI830->tiling = TRUE; - } - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", pI830->fb_compression ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? diff --git a/src/i830_exa.c b/src/i830_exa.c index e801d50d..353ab8f2 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -54,7 +54,7 @@ do { \ #define I830FALLBACK(s, arg...) \ do { \ return FALSE; \ -} while(0) +} while(0) #endif const int I830CopyROP[16] = @@ -98,6 +98,33 @@ const int I830PatternROP[16] = }; /** + * Returns whether a given pixmap is tiled or not. + * + * Currently, we only have one pixmap that might be tiled, which is the front + * buffer. At the point where we are tiling some pixmaps managed by the + * general allocator, we should move this to using pixmap privates. + */ +Bool +i830_pixmap_tiled(PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long offset; + + /* Don't use exaGetPixmapOffset becuase we might be called from XAA code. */ + offset = (long)pPixmap->devPrivate.ptr - + (long)pI830->FbBase; + if (offset == pI830->front_buffer->offset && + pI830->front_buffer->tiling != TILE_NONE) + { + return TRUE; + } + + return FALSE; +} + +/** * I830EXASync - wait for a command to finish * @pScreen: current screen * @marker: marker command to wait for @@ -133,12 +160,12 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) offset = exaGetPixmapOffset(pPixmap); pitch = exaGetPixmapPitch(pPixmap); - if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0) + if (offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0) I830FALLBACK("pixmap offset not aligned"); - if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0) + if (pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0) I830FALLBACK("pixmap pitch not aligned"); - pI830->BR[13] = (pitch & 0xffff); + pI830->BR[13] = (I830PatternROP[alu] & 0xff) << 16 ; switch (pPixmap->drawable.bitsPerPixel) { case 8: break; @@ -151,7 +178,6 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) pI830->BR[13] |= ((1 << 24) | (1 << 25)); break; } - pI830->BR[13] |= (I830PatternROP[alu] & 0xff) << 16 ; pI830->BR[16] = fg; return TRUE; } @@ -161,19 +187,29 @@ I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) { ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - unsigned long offset; + unsigned long offset, pitch; + uint32_t cmd; + + offset = exaGetPixmapOffset(pPixmap); + pitch = exaGetPixmapPitch(pPixmap); - offset = exaGetPixmapOffset(pPixmap); - { BEGIN_LP_RING(6); + + cmd = XY_COLOR_BLT_CMD; + if (pPixmap->drawable.bitsPerPixel == 32) - OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA - | XY_COLOR_BLT_WRITE_RGB); - else - OUT_RING(XY_COLOR_BLT_CMD); + cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; + + if (IS_I965G(pI830) && i830_pixmap_tiled(pPixmap)) { + assert((pitch % 512) == 0); + pitch >>= 2; + cmd |= XY_COLOR_BLT_TILED; + } + + OUT_RING(cmd); - OUT_RING(pI830->BR[13]); + OUT_RING(pI830->BR[13] | pitch); OUT_RING((y1 << 16) | (x1 & 0xffff)); OUT_RING((y2 << 16) | (x2 & 0xffff)); OUT_RING(offset); @@ -206,11 +242,9 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask)) I830FALLBACK("planemask is not solid"); - pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap); - pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap); + pI830->pSrcPixmap = pSrcPixmap; - pI830->BR[13] = exaGetPixmapPitch(pDstPixmap); - pI830->BR[13] |= I830CopyROP[alu] << 16; + pI830->BR[13] = I830CopyROP[alu] << 16; switch (pSrcPixmap->drawable.bitsPerPixel) { case 8: @@ -231,30 +265,49 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1, { ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); + uint32_t cmd; int dst_x2, dst_y2; - unsigned int dst_off; + unsigned int dst_off, dst_pitch, src_off, src_pitch; dst_x2 = dst_x1 + w; dst_y2 = dst_y1 + h; dst_off = exaGetPixmapOffset(pDstPixmap); + dst_pitch = exaGetPixmapPitch(pDstPixmap); + src_off = exaGetPixmapOffset(pI830->pSrcPixmap); + src_pitch = exaGetPixmapPitch(pI830->pSrcPixmap); { BEGIN_LP_RING(8); + cmd = XY_SRC_COPY_BLT_CMD; + if (pDstPixmap->drawable.bitsPerPixel == 32) - OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - else - OUT_RING(XY_SRC_COPY_BLT_CMD); + cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; + + if (IS_I965G(pI830)) { + if (i830_pixmap_tiled(pDstPixmap)) { + assert((dst_pitch % 512) == 0); + dst_pitch >>= 2; + cmd |= XY_SRC_COPY_BLT_DST_TILED; + } + + if (i830_pixmap_tiled(pI830->pSrcPixmap)) { + assert((src_pitch % 512) == 0); + src_pitch >>= 2; + cmd |= XY_SRC_COPY_BLT_SRC_TILED; + } + } + + OUT_RING(cmd); - OUT_RING(pI830->BR[13]); + OUT_RING(pI830->BR[13] | dst_pitch); OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff)); OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff)); OUT_RING(dst_off); OUT_RING((src_y1 << 16) | (src_x1 & 0xffff)); - OUT_RING(pI830->copy_src_pitch); - OUT_RING(pI830->copy_src_off); + OUT_RING(src_pitch); + OUT_RING(src_off); ADVANCE_LP_RING(); } @@ -415,11 +468,12 @@ I830EXAInit(ScreenPtr pScreen) } pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; - DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n", - pI830->EXADriverPtr->memoryBase, - pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize, - pI830->EXADriverPtr->offScreenBase, - pI830->EXADriverPtr->memorySize); + DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, " + "memorySize 0x%x\n", + pI830->EXADriverPtr->memoryBase, + pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize, + pI830->EXADriverPtr->offScreenBase, + pI830->EXADriverPtr->memorySize); /* Limits are described in the BLT engine chapter under Graphics Data Size diff --git a/src/i830_lvds.c b/src/i830_lvds.c index e2c6e3ce..18e5c2b3 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -46,6 +46,30 @@ struct i830_lvds_priv { int backlight_duty_cycle; }; +/** + * Use legacy backlight controls? + * + * \param pI830 device in question + * + * Returns TRUE if legacy backlight should be used, false otherwise. + */ +static int +i830_lvds_backlight_legacy(I830Ptr pI830) +{ + CARD32 blc_pwm_ctl, blc_pwm_ctl2; + + /* 965GM+ change the location of the legacy control bit */ + if (IS_I965GM(pI830)) { + blc_pwm_ctl2 = INREG(BLC_PWM_CTL2); + if (blc_pwm_ctl2 & BLM_LEGACY_MODE2) + return TRUE; + } else { + blc_pwm_ctl = INREG(BLC_PWM_CTL); + if (blc_pwm_ctl & BLM_LEGACY_MODE) + return TRUE; + } + return FALSE; +} /** * Sets the backlight level. @@ -59,18 +83,12 @@ i830_lvds_set_backlight(xf86OutputPtr output, int level) I830Ptr pI830 = I830PTR(pScrn); CARD32 blc_pwm_ctl; + if (i830_lvds_backlight_legacy(pI830)) + pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe); + blc_pwm_ctl = INREG(BLC_PWM_CTL); - if (blc_pwm_ctl & BLM_LEGACY_MODE) - { - pciWriteByte (pI830->PciTag, - LEGACY_BACKLIGHT_BRIGHTNESS, - level & 0xff); - } - else - { - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); - } + blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; + OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); } /** @@ -82,12 +100,24 @@ i830_lvds_get_max_backlight(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); CARD32 pwm_ctl = INREG(BLC_PWM_CTL); + CARD32 val; + + if (IS_I965GM(pI830)) { + val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >> + BACKLIGHT_MODULATION_FREQ_SHIFT2); + } else { + val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + } - if (pwm_ctl & BLM_LEGACY_MODE) - return 0xff; - else - return ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + /* + * In legacy control mode, backlight value is calculated: + * if (LBB[7:0] != 0xff) + * backlight = BLC_PWM_CTL[15:0] * BPC[7:0] + * else + * backlight = BLC_PWM_CTL[15:0] + */ + return val; } /** @@ -138,21 +168,15 @@ i830_lvds_save (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); + if (IS_I965GM(pI830)) + pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); pI830->savePP_ON = INREG(LVDSPP_ON); pI830->savePP_OFF = INREG(LVDSPP_OFF); pI830->savePP_CONTROL = INREG(PP_CONTROL); pI830->savePP_CYCLE = INREG(PP_CYCLE); pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL); - if (pI830->saveBLC_PWM_CTL & BLM_LEGACY_MODE) - { - dev_priv->backlight_duty_cycle = pciReadByte (pI830->PciTag, - LEGACY_BACKLIGHT_BRIGHTNESS); - } - else - { - dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - } + dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); /* * If the light is off at server startup, just make it full brightness @@ -167,6 +191,8 @@ i830_lvds_restore(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); + if (IS_I965GM(pI830)) + OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2); OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL); OUTREG(LVDSPP_ON, pI830->savePP_ON); OUTREG(LVDSPP_OFF, pI830->savePP_OFF); @@ -462,6 +488,9 @@ i830_lvds_init(ScrnInfoPtr pScrn) DisplayModePtr modes, scan, bios_mode; struct i830_lvds_priv *dev_priv; + if (pI830->quirk_flag & QUIRK_IGNORE_LVDS) + return; + output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS"); if (!output) return; @@ -575,29 +604,23 @@ i830_lvds_init(ScrnInfoPtr pScrn) /* Blacklist machines with BIOSes that list an LVDS panel without actually * having one. */ - if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) { - if (pI830->PciInfo->subsysVendor == 0xa0a0) /* aopen mini pc */ - goto disable_exit; - - if ((pI830->PciInfo->subsysVendor == 0x8086) && - (pI830->PciInfo->subsysCard == 0x7270)) { - /* It's a Mac Mini or Macbook Pro. - * - * Apple hardware is out to get us. The macbook pro has a real - * LVDS panel, but the mac mini does not, and they have the same - * device IDs. We'll distinguish by panel size, on the assumption - * that Apple isn't about to make any machines with an 800x600 - * display. - */ - - if (dev_priv->panel_fixed_mode != NULL && + if (pI830->quirk_flag & QUIRK_IGNORE_MACMINI_LVDS) { + /* It's a Mac Mini or Macbook Pro. + * + * Apple hardware is out to get us. The macbook pro has a real + * LVDS panel, but the mac mini does not, and they have the same + * device IDs. We'll distinguish by panel size, on the assumption + * that Apple isn't about to make any machines with an 800x600 + * display. + */ + + if (dev_priv->panel_fixed_mode != NULL && dev_priv->panel_fixed_mode->HDisplay == 800 && dev_priv->panel_fixed_mode->VDisplay == 600) - { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Suspected Mac Mini, ignoring the LVDS\n"); - goto disable_exit; - } + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Suspected Mac Mini, ignoring the LVDS\n"); + goto disable_exit; } } diff --git a/src/i830_memory.c b/src/i830_memory.c index 96a4d67f..23288588 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -111,15 +111,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Our hardware status area is just a single page */ #define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE -enum tile_format { - TILING_NONE, - TILING_XMAJOR, - TILING_YMAJOR -}; - static i830_memory * i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, long size, unsigned long alignment, int flags); + static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, unsigned int pitch, unsigned int size, enum tile_format tile_format); @@ -765,6 +760,8 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, } } + mem->tiling = TILE_NONE; + return mem; } @@ -789,7 +786,7 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, i830_memory *mem; int fence_divide, i; - if (tile_format == TILING_NONE) + if (tile_format == TILE_NONE) return i830_allocate_memory(pScrn, name, size, alignment, flags); /* XXX: for now, refuse to tile with movable buffer object allocations, @@ -866,19 +863,11 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, } mem->size = size; + mem->tiling = tile_format; return mem; } -static void -i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix, - i830_memory *mem, unsigned int tiling_mode) -{ - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s%s is %stiled\n", prefix, mem->name, - (tiling_mode == FENCE_LINEAR) ? "not " : ""); -} - void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) { @@ -901,6 +890,8 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) "%sFixed memory allocation layout:\n", prefix); for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { + char phys_suffix[32] = ""; + char *tile_suffix = ""; if (mem->offset >= pI830->stolen_size && mem->prev->offset < pI830->stolen_size) @@ -910,19 +901,18 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) prefix, pI830->stolen_size); } - if (mem->bus_addr == 0) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, - mem->offset, mem->end - 1, mem->name, - mem->size / 1024); - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s " - "(%ld kB, 0x%016llx physical)\n", - prefix, - mem->offset, mem->end - 1, mem->name, - mem->size / 1024, mem->bus_addr); - } + if (mem->bus_addr != 0) + snprintf(phys_suffix, sizeof(phys_suffix), + ", 0x%016llx physical\n", mem->bus_addr); + if (mem->tiling == TILE_XMAJOR) + tile_suffix = " X tiled"; + else if (mem->tiling == TILE_YMAJOR) + tile_suffix = " Y tiled"; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB%s)%s\n", prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024, phys_suffix, tile_suffix); } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%s0x%08lx: end of aperture\n", @@ -952,25 +942,6 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) prefix, pI830->memory_manager->end); } #endif /* XF86DRI_MM */ - - if (pI830->front_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer, - pI830->front_tiled); - } -#ifdef XF86DRI - if (pI830->back_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer, - pI830->back_tiled); - } - if (pI830->third_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->third_buffer, - pI830->third_tiled); - } - if (pI830->depth_buffer != NULL) { - i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer, - pI830->depth_tiled); - } -#endif } static Bool @@ -1098,6 +1069,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, char *name; int flags; i830_memory *front_buffer = NULL; + Bool tiling; /* The front buffer is currently marked as NEED_LIFETIME_FIXED because * DRIDoMappings is the only caller of the rm/add map functions, @@ -1172,24 +1144,30 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, name = secondary ? "secondary front buffer" : "front buffer"; - /* Attempt to allocate it tiled first if possible. */ - if (pI830->tiling && IsTileable(pScrn, pitch)) { + /* Front buffer tiling has to be disabled with G965 XAA because some of the + * acceleration operations (non-XY COLOR_BLT) can't be done to tiled + * buffers. + */ + if (!pI830->useEXA && IS_I965G(pI830)) + tiling = FALSE; + else + tiling = pI830->tiling; + + /* Attempt to allocate it tiled first if we have page flipping on. */ + if (tiling && IsTileable(pScrn, pitch)) { /* XXX: probably not the case on 965 */ if (IS_I9XX(pI830)) align = MB(1); else align = KB(512); front_buffer = i830_allocate_memory_tiled(pScrn, name, size, - pitch, align, - flags, - TILING_XMAJOR); - pI830->front_tiled = FENCE_XMAJOR; + pitch, align, flags, + TILE_XMAJOR); } /* If not, attempt it linear */ if (front_buffer == NULL) { front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags); - pI830->front_tiled = FENCE_LINEAR; } if (front_buffer == NULL) { @@ -1343,10 +1321,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn) } out: - if (pI830->fb_compression) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression " - "enabled\n"); - else + if (!pI830->fb_compression) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer" " compression disabled\n"); @@ -1522,7 +1497,7 @@ myLog2(unsigned int n) static Bool i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, - unsigned int *tiled, const char *name) + const char *name) { I830Ptr pI830 = I830PTR(pScrn); unsigned int pitch = pScrn->displayWidth * pI830->cpp; @@ -1543,8 +1518,7 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED | ALLOW_SHARING, - TILING_XMAJOR); - *tiled = FENCE_XMAJOR; + TILE_XMAJOR); } /* Otherwise, just allocate it linear. The offset must stay constant @@ -1556,7 +1530,6 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED | ALLOW_SHARING); - *tiled = FENCE_LINEAR; } if (*buffer == NULL) { @@ -1592,7 +1565,7 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) /* The 965 requires that the depth buffer be in Y Major format, while * the rest appear to fail when handed that format. */ - tile_format = IS_I965G(pI830) ? TILING_YMAJOR: TILING_XMAJOR; + tile_format = IS_I965G(pI830) ? TILE_YMAJOR: TILE_XMAJOR; pI830->depth_buffer = i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, @@ -1601,8 +1574,6 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) NEED_LIFETIME_FIXED | ALLOW_SHARING, tile_format); - pI830->depth_tiled = (tile_format == TILING_YMAJOR) ? FENCE_YMAJOR : - FENCE_XMAJOR; } /* Otherwise, allocate it linear. The offset must stay constant @@ -1613,7 +1584,6 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) pI830->depth_buffer = i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE, ALLOW_SHARING | NEED_LIFETIME_FIXED); - pI830->depth_tiled = FENCE_LINEAR; } if (pI830->depth_buffer == NULL) { @@ -1697,13 +1667,11 @@ i830_allocate_3d_memory(ScrnInfoPtr pScrn) return FALSE; } - if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer, - &pI830->back_tiled, "back buffer")) + if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer, "back buffer")) return FALSE; if (pI830->TripleBuffer && !i830_allocate_backbuffer(pScrn, &pI830->third_buffer, - &pI830->third_tiled, "third buffer")) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate third buffer, triple buffering " @@ -1739,14 +1707,9 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n", nr, offset, pitch, size / 1024); - assert(tile_format != TILING_NONE); + assert(tile_format != TILE_NONE); if (IS_I965G(pI830)) { - if (tile_format == TILING_XMAJOR) - pitch = 512; - else - pitch = 128; - if (nr < 0 || nr >= FENCE_NEW_NR) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "i830_set_fence(): fence %d out of range\n",nr); @@ -1754,18 +1717,18 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, } switch (tile_format) { - case TILING_XMAJOR: + case TILE_XMAJOR: pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; pI830->fence[nr] |= I965_FENCE_X_MAJOR; break; - case TILING_YMAJOR: + case TILE_YMAJOR: /* YMajor can be 128B aligned but the current code dictates * otherwise. This isn't a problem apart from memory waste. * FIXME */ pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; pI830->fence[nr] |= I965_FENCE_Y_MAJOR; break; - case TILING_NONE: + case TILE_NONE: break; } @@ -1813,13 +1776,13 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, val = offset | FENCE_VALID; switch (tile_format) { - case TILING_XMAJOR: + case TILE_XMAJOR: val |= FENCE_X_MAJOR; break; - case TILING_YMAJOR: + case TILE_YMAJOR: val |= FENCE_Y_MAJOR; break; - case TILING_NONE: + case TILE_NONE: break; } @@ -1887,7 +1850,7 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, } if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) - && tile_format == TILING_YMAJOR) + && tile_format == TILE_YMAJOR) fence_pitch = pitch / 128; else if (IS_I9XX(pI830)) fence_pitch = pitch / 512; diff --git a/src/i830_quirks.c b/src/i830_quirks.c new file mode 100644 index 00000000..b75baefd --- /dev/null +++ b/src/i830_quirks.c @@ -0,0 +1,84 @@ +/* + * 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: + * Zhenyu Wang <zhenyu.z.wang@intel.com> + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "i830.h" + +#define SUBSYS_ANY (~0) + +typedef struct { + int chipType; + int subsysVendor; + int subsysCard; + void (*hook)(I830Ptr); +} i830_quirk, *i830_quirk_ptr; + +static void quirk_ignore_tv (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_IGNORE_TV; +} + +static void quirk_ignore_lvds (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_IGNORE_LVDS; +} + +static void quirk_mac_mini (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_IGNORE_MACMINI_LVDS; +} + +static i830_quirk i830_quirk_list[] = { + /* Lenovo T61 has no TV output */ + { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv }, + /* Panasonic Toughbook CF-Y4 has no TV output */ + { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv }, + /* Lenovo 3000 v200 */ + { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv }, + /* Aopen mini pc */ + { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, + /* Mac mini has no lvds, but macbook pro does */ + { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini }, + { 0, 0, 0, NULL }, +}; + +void i830_fixup_devices(ScrnInfoPtr scrn) +{ + I830Ptr pI830 = I830PTR(scrn); + i830_quirk_ptr p = i830_quirk_list; + + while (p && p->chipType != 0) { + if (pI830->PciInfo->chipType == p->chipType && + pI830->PciInfo->subsysVendor == p->subsysVendor && + (pI830->PciInfo->subsysCard == p->subsysCard || + p->subsysCard == SUBSYS_ANY)) + p->hook(pI830); + ++p; + } +} diff --git a/src/i830_reg.h b/src/i830_reg.h index 8a2a98ac..df22ed41 100644 --- a/src/i830_reg.h +++ b/src/i830_reg.h @@ -36,6 +36,7 @@ #define FBC_CTL_EN (1<<31) #define FBC_CTL_PERIODIC (1<<30) #define FBC_CTL_INTERVAL_SHIFT (16) +#define FBC_CTL_UNCOMPRESSIBLE (1<<14) #define FBC_CTL_STRIDE_SHIFT (5) #define FBC_CTL_FENCENO (1<<0) #define FBC_COMMAND 0x0320c @@ -46,9 +47,15 @@ #define FBC_STAT_MODIFIED (1<<29) #define FBC_STAT_CURRENT_LINE (1<<0) #define FBC_CONTROL2 0x03214 +#define FBC_CTL_FENCE_DBL (0<<4) +#define FBC_CTL_IDLE_IMM (0<<2) +#define FBC_CTL_IDLE_FULL (1<<2) +#define FBC_CTL_IDLE_LINE (2<<2) +#define FBC_CTL_IDLE_DEBUG (3<<2) #define FBC_CTL_CPU_FENCE (1<<1) #define FBC_CTL_PLANEA (0<<0) #define FBC_CTL_PLANEB (1<<0) +#define FBC_FENCE_OFF 0x0321b #define FBC_LL_SIZE (1536) #define FBC_LL_PAD (32) diff --git a/src/i830_tv.c b/src/i830_tv.c index 8337d864..e3aeaf9c 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -1415,10 +1415,8 @@ i830_tv_get_modes(xf86OutputPtr output) continue; mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec)); - mode_ptr->name = xnfalloc(strlen(tv_mode->name) + - strlen(input->name) + 4); - sprintf(mode_ptr->name, "%s", input->name); - + mode_ptr->name = xnfalloc(strlen(input->name) + 1); + strcpy (mode_ptr->name, input->name); mode_ptr->HDisplay = hactive_s; mode_ptr->HSyncStart = hactive_s + 1; @@ -1625,6 +1623,9 @@ i830_tv_init(ScrnInfoPtr pScrn) struct i830_tv_priv *dev_priv; CARD32 tv_dac_on, tv_dac_off, save_tv_dac; + if (pI830->quirk_flag & QUIRK_IGNORE_TV) + return; + if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) return; diff --git a/src/i830_xaa.c b/src/i830_xaa.c index ec8a8794..fabac20e 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -126,7 +126,6 @@ I830XAAInit(ScreenPtr pScreen) if (!infoPtr) return FALSE; - pI830->bufferOffset = 0; infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; /* Use the same sync function as the I830. @@ -235,6 +234,7 @@ I830XAAInit(ScreenPtr pScreen) infoPtr->RestoreAccelState = I830RestoreAccelState; } + /* Set up pI830->bufferOffset */ I830SelectBuffer(pScrn, I830_SELECT_FRONT); if (!XAAInit(pScreen, infoPtr)) @@ -269,40 +269,39 @@ I830XAAInit(ScreenPtr pScreen) return TRUE; } -#ifdef XF86DRI static unsigned int -CheckTiling(ScrnInfoPtr pScrn) +I830CheckTiling(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - unsigned int tiled = 0; - - /* Check tiling */ - if (IS_I965G(pI830)) { - if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR) - tiled = 1; - if (pI830->back_buffer != NULL && - pI830->bufferOffset == pI830->back_buffer->offset && - pI830->back_tiled == FENCE_XMAJOR) { - tiled = 1; - } - if (pI830->third_buffer != NULL && - pI830->bufferOffset == pI830->third_buffer->offset && - pI830->third_tiled == FENCE_XMAJOR) { - tiled = 1; - } - /* not really supported as it's always YMajor tiled */ - if (pI830->depth_buffer != NULL && - pI830->bufferOffset == pI830->depth_buffer->offset && - pI830->depth_tiled == FENCE_XMAJOR) { - tiled = 1; - } + + if (pI830->bufferOffset == pI830->front_buffer->offset && + pI830->front_buffer->tiling != TILE_NONE) + { + return TRUE; + } +#ifdef XF86DRI + if (pI830->back_buffer != NULL && + pI830->bufferOffset == pI830->back_buffer->offset && + pI830->back_buffer->tiling != TILE_NONE) + { + return TRUE; + } + if (pI830->depth_buffer != NULL && + pI830->bufferOffset == pI830->depth_buffer->offset && + pI830->depth_buffer->tiling != TILE_NONE) + { + return TRUE; + } + if (pI830->third_buffer != NULL && + pI830->bufferOffset == pI830->third_buffer->offset && + pI830->third_buffer->tiling != TILE_NONE) + { + return TRUE; } +#endif - return tiled; + return FALSE; } -#else -#define CheckTiling(pScrn) 0 -#endif void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, @@ -314,16 +313,20 @@ I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n", color, rop, planemask); + if (IS_I965G(pI830) && I830CheckTiling(pScrn)) { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4; + } else { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + } + #ifdef I830_USE_EXA /* This function gets used by I830DRIInitBuffers(), and we might not have * XAAGetPatternROP() available. So just use the ROPs from our EXA code * if available. */ - pI830->BR[13] = ((I830PatternROP[rop] << 16) | - (pScrn->displayWidth * pI830->cpp)); + pI830->BR[13] |= (I830PatternROP[rop] << 16); #else - pI830->BR[13] = ((XAAGetPatternROP(rop) << 16) | - (pScrn->displayWidth * pI830->cpp)); + pI830->BR[13] |= ((XAAGetPatternROP(rop) << 16); #endif pI830->BR[16] = color; @@ -381,7 +384,12 @@ I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, ErrorF("I830SetupForScreenToScreenCopy %d %d %x %x %d\n", xdir, ydir, rop, planemask, transparency_color); - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + if (IS_I965G(pI830) && I830CheckTiling(pScrn)) { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4; + } else { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + } + #ifdef I830_USE_EXA /* This function gets used by I830DRIInitBuffers(), and we might not have * XAAGetCopyROP() available. So just use the ROPs from our EXA code @@ -411,7 +419,7 @@ I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1, { I830Ptr pI830 = I830PTR(pScrn); int dst_x2, dst_y2; - unsigned int tiled = CheckTiling(pScrn); + unsigned int tiled = I830CheckTiling(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I830SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n", @@ -420,10 +428,6 @@ I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int src_x1, int src_y1, dst_x2 = dst_x1 + w; dst_y2 = dst_y1 + h; - if (tiled) - pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | - (pI830->BR[13] & 0xFFFF0000); - { BEGIN_LP_RING(8); @@ -463,7 +467,11 @@ I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty, pI830->BR[18] = bg; pI830->BR[19] = fg; - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); /* In bytes */ + if (IS_I965G(pI830) && I830CheckTiling(pScrn)) { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4; + } else { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + } pI830->BR[13] |= XAAGetPatternROP(rop) << 16; if (bg == -1) pI830->BR[13] |= (1 << 28); @@ -487,7 +495,7 @@ I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty, { I830Ptr pI830 = I830PTR(pScrn); int x1, x2, y1, y2; - unsigned int tiled = CheckTiling(pScrn); + unsigned int tiled = I830CheckTiling(pScrn); x1 = x; x2 = x + w; @@ -497,10 +505,6 @@ I830SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty, if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I830SubsequentMono8x8PatternFillRect\n"); - if (tiled) - pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | - (pI830->BR[13] & 0xFFFF0000); - { BEGIN_LP_RING(10); @@ -560,7 +564,11 @@ I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, fg, bg, rop, planemask); /* Fill out register values */ - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + if (IS_I965G(pI830) && I830CheckTiling(pScrn)) { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4; + } else { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + } pI830->BR[13] |= XAAGetCopyROP(rop) << 16; if (bg == -1) pI830->BR[13] |= (1 << 29); @@ -603,7 +611,7 @@ static void I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) { I830Ptr pI830 = I830PTR(pScrn); - unsigned int tiled = CheckTiling(pScrn); + unsigned int tiled = I830CheckTiling(pScrn); if (pI830->init == 0) { pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - @@ -621,10 +629,6 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n", bufno, pI830->BR[12]); - if (tiled) - pI830->BR[13] = ((pI830->BR[13] & 0xFFFF) >> 2) | - (pI830->BR[13] & 0xFFFF0000); - { BEGIN_LP_RING(8); @@ -666,7 +670,11 @@ I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, ErrorF("I830SetupForScanlineImageWrite %x %x\n", rop, planemask); /* Fill out register values */ - pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + if (IS_I965G(pI830) && I830CheckTiling(pScrn)) { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp) >> 4; + } else { + pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); + } pI830->BR[13] |= XAAGetCopyROP(rop) << 16; switch (pScrn->bitsPerPixel) { @@ -703,7 +711,7 @@ static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) { I830Ptr pI830 = I830PTR(pScrn); - unsigned int tiled = CheckTiling(pScrn); + unsigned int tiled = I830CheckTiling(pScrn); if (pI830->init == 0) { pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - diff --git a/src/i915_render.c b/src/i915_render.c index 9c937f23..7546dfd7 100644 --- a/src/i915_render.c +++ b/src/i915_render.c @@ -155,16 +155,9 @@ static Bool i915_get_dest_format(PicturePtr pDstPicture, CARD32 *dst_format) case PICT_x1r5g5b5: *dst_format = COLR_BUF_ARGB1555; break; - /* COLR_BUF_8BIT is special for YUV surfaces. While we may end up being - * able to use it depending on how the hardware implements it, disable it - * for now while we don't know what exactly it does (what channel does it - * read from? - */ - /* case PICT_a8: *dst_format = COLR_BUF_8BIT; break; - */ case PICT_a4r4g4b4: case PICT_x4r4g4b4: *dst_format = COLR_BUF_ARGB4444; @@ -285,10 +278,9 @@ i915_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) pI830->mapstate[unit * 3 + 0] = offset; pI830->mapstate[unit * 3 + 1] = format | + MS3_USE_FENCE_REGS | ((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) | ((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT); - if (pI830->tiling) - pI830->mapstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS; pI830->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT; pI830->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << @@ -314,6 +306,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, I830Ptr pI830 = I830PTR(pScrn); CARD32 dst_format, dst_offset, dst_pitch; CARD32 blendctl; + int out_reg = FS_OC; IntelEmitInvarientState(pScrn); *pI830->last_3d = LAST_3D_RENDER; @@ -413,6 +406,9 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, ADVANCE_LP_RING(); } + if (dst_format == COLR_BUF_8BIT) + out_reg = FS_U0; + FS_BEGIN(); /* Declare the registers necessary for our program. I don't think the @@ -433,7 +429,7 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, if (!pMask) { /* No mask, so move to output color */ - i915_fs_mov(FS_OC, i915_fs_operand_reg(FS_R0)); + i915_fs_mov(out_reg, i915_fs_operand_reg(FS_R0)); } else { /* Load the pMaskPicture texel */ i915_fs_texld(FS_R1, FS_S1, FS_T1); @@ -454,17 +450,20 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture, PICT_FORMAT_RGB(pMaskPicture->format)) { if (i915_blend_op[op].src_alpha) { - i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W), + i915_fs_mul(out_reg, i915_fs_operand(FS_R0, W, W, W, W), i915_fs_operand_reg(FS_R1)); } else { - i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0), + i915_fs_mul(out_reg, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_R1)); } } else { - i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0), + i915_fs_mul(out_reg, i915_fs_operand_reg(FS_R0), i915_fs_operand(FS_R1, W, W, W, W)); } } + if (dst_format == COLR_BUF_8BIT) + i915_fs_mov(FS_OC, i915_fs_operand(out_reg, W, W, W, W)); + FS_END(); return TRUE; diff --git a/src/i915_video.c b/src/i915_video.c index e116fe23..a6447b1c 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -149,7 +149,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_RING(_3DSTATE_MAP_STATE | 3); OUT_RING(0x00000001); /* texture map #1 */ OUT_RING(pPriv->YBuf0offset); - ms3 = MAPSURF_422; + ms3 = MAPSURF_422 | MS3_USE_FENCE_REGS; switch (id) { case FOURCC_YUY2: ms3 |= MT_422_YCRCB_NORMAL; @@ -160,8 +160,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, } ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; - if (pI830->tiling) - ms3 |= MS3_USE_FENCE_REGS; OUT_RING(ms3); OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); ADVANCE_LP_RING(); @@ -248,29 +246,23 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, OUT_RING(0x00000007); OUT_RING(pPriv->YBuf0offset); - ms3 = MAPSURF_8BIT | MT_8BIT_I8; + ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; - if (pI830->tiling) - ms3 |= MS3_USE_FENCE_REGS; OUT_RING(ms3); OUT_RING(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); OUT_RING(pPriv->UBuf0offset); - ms3 = MAPSURF_8BIT | MT_8BIT_I8; + ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT; - if (pI830->tiling) - ms3 |= MS3_USE_FENCE_REGS; OUT_RING(ms3); OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); OUT_RING(pPriv->VBuf0offset); - ms3 = MAPSURF_8BIT | MT_8BIT_I8; + ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT; - if (pI830->tiling) - ms3 |= MS3_USE_FENCE_REGS; OUT_RING(ms3); OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); ADVANCE_LP_RING(); diff --git a/src/i965_render.c b/src/i965_render.c index 744501ae..ad3b53ef 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -161,16 +161,9 @@ static Bool i965_get_dest_format(PicturePtr pDstPicture, CARD32 *dst_format) case PICT_x1r5g5b5: *dst_format = BRW_SURFACEFORMAT_B5G5R5X1_UNORM; break; - /* COLR_BUF_8BIT is special for YUV surfaces. While we may end up being - * able to use it depending on how the hardware implements it, disable it - * for now while we don't know what exactly it does (what channel does it - * read from? - */ - /* case PICT_a8: - *dst_format = COLR_BUF_8BIT; + *dst_format = BRW_SURFACEFORMAT_A8_UNORM; break; - */ case PICT_a4r4g4b4: case PICT_x4r4g4b4: *dst_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM; @@ -292,7 +285,7 @@ static int next_offset, total_state_size; static char *state_base; static int state_base_offset; static float *vb; -static int vb_size = (4 * 4) * 4 ; /* 4 DWORDS per vertex*/ +static int vb_size = (6 * 4) * 4 ; /* 6 DWORDS per vertex - and mask*/ static CARD32 src_blend, dst_blend; @@ -399,9 +392,11 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, { ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - CARD32 src_offset, src_pitch; - CARD32 mask_offset = 0, mask_pitch = 0; - CARD32 dst_format, dst_offset, dst_pitch; + CARD32 src_offset, src_pitch, src_tile_format = 0, src_tiled = 0; + CARD32 mask_offset = 0, mask_pitch = 0, mask_tile_format = 0, + mask_tiled = 0; + CARD32 dst_format, dst_offset, dst_pitch, dst_tile_format = 0, + dst_tiled = 0; Bool rotation_program = FALSE; IntelEmitInvarientState(pScrn); @@ -409,11 +404,23 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_offset = intel_get_pixmap_offset(pSrc); src_pitch = intel_get_pixmap_pitch(pSrc); + if (i830_pixmap_tiled(pSrc)) { + src_tiled = 1; + src_tile_format = 0; /* Tiled X */ + } dst_offset = intel_get_pixmap_offset(pDst); dst_pitch = intel_get_pixmap_pitch(pDst); + if (i830_pixmap_tiled(pDst)) { + dst_tiled = 1; + dst_tile_format = 0; /* Tiled X */ + } if (pMask) { mask_offset = intel_get_pixmap_offset(pMask); mask_pitch = intel_get_pixmap_pitch(pMask); + if (i830_pixmap_tiled(pMask)) { + mask_tiled = 1; + mask_tile_format = 0; /* Tiled X */ + } } pI830->scale_units[0][0] = pSrc->drawable.width; pI830->scale_units[0][1] = pSrc->drawable.height; @@ -503,7 +510,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, next_offset = mask_sampler_offset + sizeof(*mask_sampler_state); } /* Align VB to native size of elements, for safety */ - vb_offset = ALIGN(next_offset, 8); + vb_offset = ALIGN(next_offset, 32); next_offset = vb_offset + vb_size; /* And then the general state: */ @@ -641,6 +648,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, dest_surf_state->ss2.mip_count = 0; dest_surf_state->ss2.render_target_rotation = 0; dest_surf_state->ss3.pitch = dst_pitch - 1; + dest_surf_state->ss3.tile_walk = dst_tile_format; + dest_surf_state->ss3.tiled_surface = dst_tiled; dest_surf_state = (void *)(state_base + dest_surf_offset); memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local)); @@ -667,6 +676,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_surf_state->ss2.mip_count = 0; src_surf_state->ss2.render_target_rotation = 0; src_surf_state->ss3.pitch = src_pitch - 1; + src_surf_state->ss3.tile_walk = src_tile_format; + src_surf_state->ss3.tiled_surface = src_tiled; src_surf_state = (void *)(state_base + src_surf_offset); memcpy (src_surf_state, &src_surf_state_local, sizeof (src_surf_state_local)); @@ -695,6 +706,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, mask_surf_state->ss2.mip_count = 0; mask_surf_state->ss2.render_target_rotation = 0; mask_surf_state->ss3.pitch = mask_pitch - 1; + mask_surf_state->ss3.tile_walk = mask_tile_format; + mask_surf_state->ss3.tiled_surface = mask_tiled; mask_surf_state = (void *)(state_base + mask_surf_offset); memcpy (mask_surf_state, &mask_surf_state_local, sizeof (mask_surf_state_local)); @@ -800,7 +813,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, * back to SF which then hands pixels off to WM. */ if (pMask) - memcpy(sf_kernel, sf_kernel_static_mask, sizeof (sf_kernel_static)); + memcpy(sf_kernel, sf_kernel_static_mask, + sizeof (sf_kernel_static_mask)); else if (rotation_program) memcpy(sf_kernel, sf_kernel_static_rotation, sizeof (sf_kernel_static_rotation)); diff --git a/src/i965_video.c b/src/i965_video.c index 30842336..6ed7f01a 100644 --- a/src/i965_video.c +++ b/src/i965_video.c @@ -378,6 +378,8 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, dest_surf_state->ss2.mip_count = 0; dest_surf_state->ss2.render_target_rotation = 0; dest_surf_state->ss3.pitch = pPixmap->devKind - 1; + dest_surf_state->ss3.tiled_surface = i830_pixmap_tiled(pPixmap); + dest_surf_state->ss3.tile_walk = 0; /* TileX */ /* Set up the source surface state buffer */ memset(src_surf_state, 0, sizeof(*src_surf_state)); @@ -408,6 +410,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, src_surf_state->ss2.mip_count = 0; src_surf_state->ss2.render_target_rotation = 0; src_surf_state->ss3.pitch = video_pitch - 1; + /* FIXME: account for tiling if we ever do it */ /* Set up a binding table for our two surfaces. Only the PS will use it */ /* XXX: are these offset from the right place? */ |