diff options
author | Michel Daenzer <daenzer@loki.lorrainebruecke.local> | 2006-07-26 16:02:07 +0200 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2006-08-03 12:45:08 +0200 |
commit | 9de55a44f95f251df365f29884a1ff17492b470d (patch) | |
tree | c7db65f228ee6ac495020921d6f7d0c014b61e4e | |
parent | d140055f5be6185f634f7d13683c36ed698eb89a (diff) |
Merge branch 'master' of ssh+git://git.freedesktop.org/git/xorg/driver/xf86-video-intel into i810_texman_0_1_branchi810_texman_0_1_branch
Conflicts:
ChangeLog - removed
src/i810_driver.c
src/i830_dri.c
src/i830_driver.c
src/i830_memory.c
37 files changed, 6599 insertions, 1369 deletions
@@ -1,3 +1,5 @@ +.deps +.libs Makefile Makefile.in *.la diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index c1875424..00000000 --- a/ChangeLog +++ /dev/null @@ -1,65 +0,0 @@ -2006-03-24 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> - - * src/i830_driver.c: (I830BIOSCloseScreen): - Fix typo. - -2006-03-22 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> - - * src/i810_driver.c: - * src/i830_dri.c: (I830DRIDoMappings): - * src/i830_driver.c: (I830DrmMMInit), (I830DrmMMTakedown), - (I830BIOSScreenInit), (I830BIOSCloseScreen): - * src/i830_memory.c: (I830Allocate3DMemory), (I830FixupOffsets), - (I830BindGARTMemory), (I830UnbindGARTMemory): - New branch. Initialize the drm memory manager. Don't allocate - texture memory. - -2005-12-20 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version for X11R7 release. - -2005-12-14 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for final X11R7 release candidate. - -2005-12-06 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * man/Makefile.am: - Change *man_SOURCES ==> *man_PRE to fix autotools warnings. - -2005-12-03 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for X11R7 RC3 release. - -2005-12-01 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Remove extraneous AC_MSG_RESULT. - -2005-11-30 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - Bump libdrm dep to 2.0. - -2005-11-29 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - Only build dlloader modules by default. - -2005-11-19 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update dependencies to work with separate build roots. - -2005-11-09 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for X11R7 RC2 release. - -2005-11-01 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update pkgcheck dependencies to work with separate build roots. diff --git a/configure.ac b/configure.ac index e50b3d18..b1d3524f 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-i810], - 1.4.1.3, + 1.6.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-i810) @@ -89,6 +89,18 @@ if test x$DRI = xauto; then fi AC_MSG_RESULT([$DRI]) +dnl Use lots of warning flags with GCC + +WARN_CFLAGS="" + +if test "x$GCC" = "xyes"; then + WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wnested-externs -fno-strict-aliasing" +fi + +CFLAGS="$CFLAGS $WARN_CFLAGS" + AM_CONDITIONAL(DRI, test x$DRI = xyes) if test "$DRI" = yes; then PKG_CHECK_MODULES(DRI, [libdrm >= 2.0 xf86driproto]) diff --git a/man/.gitignore b/man/.gitignore new file mode 100644 index 00000000..a438e807 --- /dev/null +++ b/man/.gitignore @@ -0,0 +1,2 @@ +i810.4 +i810.4x diff --git a/man/i810.man b/man/i810.man index 8c432eff..099e1f8a 100644 --- a/man/i810.man +++ b/man/i810.man @@ -192,16 +192,18 @@ the machine has booted, but unfortunately it doesn't always work and is extremely dependent upon the Video BIOS. Default: disabled .TP -.BI "Option \*qRotate\*q \*qCW\*q" -.TP -.BI "Option \*qRotate\*q \*qCCW\*q" -Rotate the desktop 90 degrees clockwise or counterclockwise. This option -forces the ShadowFB option on, and disables acceleration. -Default: no rotation. -.TP -.BI "Option \*qShadowFB\*q \*q" boolean \*q -Enable or disable use of the shadow framebuffer layer. This option -disables acceleration. Default: off. +.BI "Option \*qRotate\*q \*q90\*q" +Rotate the desktop 90 degrees counterclockwise. Other valid options are +0, 90, 180 and 270 degrees. The RandR extension is used for rotation +functionality. So this option allows the Xserver to start with a rotated +mode of operation. +Default: 0 degrees. +.TP +.BI "Option \*qLinearAlloc\*q \*q" integer \*q +Allows more memory for the offscreen allocator. This usually helps in +situations where HDTV movies are required to play but not enough offscreen +memory is usually available. Set this to 6144 for upto 1920x1080 HDTV support. +Default 0KB (off). .SH "SEE ALSO" __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) diff --git a/src/.cvsignore b/src/.cvsignore deleted file mode 100644 index 9730646f..00000000 --- a/src/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.la -*.lo diff --git a/src/Makefile.am b/src/Makefile.am index fa695928..f97dc52a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,7 +53,13 @@ i810_drv_la_SOURCES = \ i830_memory.c \ i830_modes.c \ i830_video.c \ - i830_shadow.c + i830_rotate.c \ + i830_randr.c \ + i830_3d.c \ + i830_reg.h \ + i915_3d.c \ + i915_3d.h \ + i915_reg.h if DRI i810_drv_la_SOURCES += \ diff --git a/src/common.h b/src/common.h index 85a24ab3..31e67b90 100644 --- a/src/common.h +++ b/src/common.h @@ -39,13 +39,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _INTEL_COMMON_H_ #define _INTEL_COMMON_H_ -#ifdef __GNUC__ +/* Provide substitutes for gcc's __FUNCTION__ on other compilers */ +#ifndef __GNUC__ +# if defined(__STDC__) && (__STDC_VERSION__>=199901L) /* C99 */ +# define __FUNCTION__ __func__ +# else +# define __FUNCTION__ "" +# endif +#endif + + #define PFX __FILE__,__LINE__,__FUNCTION__ #define FUNCTION_NAME __FUNCTION__ -#else -#define PFX __FILE__,__LINE__,"" -#define FUNCTION_NAME "" -#endif #ifdef I830DEBUG #define MARKER() ErrorF("\n### %s:%d: >>> %s <<< ###\n\n", \ @@ -80,10 +85,10 @@ extern const char *I810ddcSymbols[]; extern const char *I810fbSymbols[]; extern const char *I810xaaSymbols[]; extern const char *I810shadowFBSymbols[]; +extern const char *I810shadowSymbols[]; #ifdef XF86DRI extern const char *I810driSymbols[]; extern const char *I810drmSymbols[]; -extern const char *I810shadowSymbols[]; #endif extern void I830DPRINTF_stub(const char *filename, int line, @@ -119,29 +124,21 @@ extern void I830DPRINTF_stub(const char *filename, int line, ErrorF( "OUT_RING %lx: %x, (mask %x)\n", \ (unsigned long)(outring), (unsigned int)(n), ringmask); \ *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ + outring += 4; ringused += 4; \ outring &= ringmask; \ } while (0) -#if 1 #define ADVANCE_LP_RING() do { \ + if (ringused > needed) \ + ErrorF("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ", \ + __FUNCTION__, ringused, needed); \ RecPtr->LpRing->tail = outring; \ + RecPtr->LpRing->space -= ringused; \ if (outring & 0x07) \ ErrorF("ADVANCE_LP_RING: " \ - "outring (0x%x) isn't on a QWord boundary", outring); \ + "outring (0x%x) isn't on a QWord boundary\n", outring); \ OUTREG(LP_RING + RING_TAIL, outring); \ } while (0) -#else -#define ADVANCE_LP_RING() { \ - RecPtr->LpRing->tail = outring; \ - if (outring & 0x07) \ - ErrorF("ADVANCE_LP_RING: " \ - "outring (0x%x) isn't on a QWord boundary", outring); \ - ErrorF("head is %d, tail is %d [%d]\n", INREG(LP_RING + RING_HEAD), INREG(LP_RING + RING_TAIL), outring); \ - OUTREG(LP_RING + RING_TAIL, outring); \ - ErrorF("head is %d, tail is %d [%d]\n", INREG(LP_RING + RING_HEAD), INREG(LP_RING + RING_TAIL), outring); \ -} -#endif /* * XXX Note: the head/tail masks are different for 810 and i830. @@ -158,54 +155,9 @@ extern void I830DPRINTF_stub(const char *filename, int line, } while (_head != _tail); \ } while( 0) -/* - * This is for debugging a potential problem writing the tail pointer - * close to the end of the ring buffer. - */ -#ifndef AVOID_TAIL_END -#define AVOID_TAIL_END 0 -#endif -#ifndef AVOID_SIZE -#define AVOID_SIZE 64 -#endif - -#if AVOID_TAIL_END - -#define BEGIN_LP_RING(n) \ - unsigned int outring, ringmask; \ - volatile unsigned char *virt; \ - int needed; \ - if ((n) & 1) \ - ErrorF("BEGIN_LP_RING called with odd argument: %d\n", n); \ - if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ - DO_RING_IDLE(); \ - needed = (n) * 4; \ - if ((RecPtr->LpRing->tail > RecPtr->LpRing->tail_mask - AVOID_SIZE) || \ - (RecPtr->LpRing->tail + needed) > \ - RecPtr->LpRing->tail_mask - AVOID_SIZE) { \ - needed += RecPtr->LpRing->tail_mask + 1 - RecPtr->LpRing->tail; \ - ErrorF("BEGIN_LP_RING: skipping last 64 bytes of " \ - "ring (%d vs %d)\n", needed, (n) * 4); \ - } \ - if (RecPtr->LpRing->space < needed) \ - WaitRingFunc(pScrn, needed, 0); \ - RecPtr->LpRing->space -= needed; \ - outring = RecPtr->LpRing->tail; \ - ringmask = RecPtr->LpRing->tail_mask; \ - virt = RecPtr->LpRing->virtual_start; \ - while (needed > (n) * 4) { \ - ErrorF("BEGIN_LP_RING: putting MI_NOOP at 0x%x (remaining %d)\n", \ - outring, needed - (n) * 4); \ - OUT_RING(MI_NOOP); \ - needed -= 4; \ - } \ - if (I810_DEBUG & DEBUG_VERBOSE_RING) \ - ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); - -#else /* AVOID_TAIL_END */ #define BEGIN_LP_RING(n) \ - unsigned int outring, ringmask; \ + unsigned int outring, ringmask, ringused = 0; \ volatile unsigned char *virt; \ int needed; \ if ((n) & 1) \ @@ -215,14 +167,12 @@ extern void I830DPRINTF_stub(const char *filename, int line, needed = (n) * 4; \ if (RecPtr->LpRing->space < needed) \ WaitRingFunc(pScrn, needed, 0); \ - RecPtr->LpRing->space -= needed; \ outring = RecPtr->LpRing->tail; \ ringmask = RecPtr->LpRing->tail_mask; \ virt = RecPtr->LpRing->virtual_start; \ if (I810_DEBUG & DEBUG_VERBOSE_RING) \ ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); -#endif /* AVOID_TAIL_END */ /* Memory mapped register access macros */ @@ -322,6 +272,11 @@ extern int I810_DEBUG; #define PCI_CHIP_I945_G_BRIDGE 0x2770 #endif +#ifndef PCI_CHIP_I945_GM +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 +#endif + #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 || \ pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \ pI810->PciInfo->chipType == PCI_CHIP_I810_E) @@ -332,11 +287,14 @@ extern int I810_DEBUG; #define IS_I852(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) #define IS_I855(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) #define IS_I865G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I865_G) + #define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G || pI810->PciInfo->chipType == PCI_CHIP_E7221_G) #define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM) #define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G) +#define IS_I945GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_GM) +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810)) +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) #define GTT_PAGE_SIZE KB(4) #define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) @@ -39,7 +39,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _I810_H_ #define _I810_H_ -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" @@ -66,7 +65,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I810_NAME "I810" #define I810_DRIVER_NAME "i810" #define I810_MAJOR_VERSION 1 -#define I810_MINOR_VERSION 4 +#define I810_MINOR_VERSION 6 #define I810_PATCHLEVEL 1 diff --git a/src/i810_accel.c b/src/i810_accel.c index f946ae2a..efbe2907 100644 --- a/src/i810_accel.c +++ b/src/i810_accel.c @@ -50,7 +50,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#include "xf86_ansic.h" #include "xf86.h" #include "xaarop.h" #include "i810.h" diff --git a/src/i810_cursor.c b/src/i810_cursor.c index 85c4e254..c293a3d5 100644 --- a/src/i810_cursor.c +++ b/src/i810_cursor.c @@ -55,7 +55,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86fbman.h" diff --git a/src/i810_dga.c b/src/i810_dga.c index e6713331..4ab7a3df 100644 --- a/src/i810_dga.c +++ b/src/i810_dga.c @@ -42,7 +42,6 @@ #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" #include "xf86Pci.h" #include "xf86PciInfo.h" #include "xaa.h" diff --git a/src/i810_dri.c b/src/i810_dri.c index f9b95bdc..a8c10ffc 100644 --- a/src/i810_dri.c +++ b/src/i810_dri.c @@ -16,9 +16,13 @@ #include "config.h" #endif +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" #include "xf86Priv.h" #include "xf86PciInfo.h" @@ -356,7 +360,7 @@ I810DRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL; - pDRIInfo->frameBufferPhysicalAddress = pI810->LinearAddr; + pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr; pDRIInfo->frameBufferSize = (((pScrn->displayWidth * pScrn->virtualY * pI810->cpp) + 4096 - 1) / 4096) * 4096; @@ -481,13 +485,14 @@ I810DRIScreenInit(ScreenPtr pScreen) pI810DRI->regsSize = I810_REG_SIZE; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr, - pI810DRI->regsSize, DRM_REGISTERS, 0, &pI810DRI->regs) < 0) { + pI810DRI->regsSize, DRM_REGISTERS, 0, + (drmAddress) &pI810DRI->regs) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", - pI810DRI->regs); + (int)pI810DRI->regs); pI810->backHandle = DRM_AGP_NO_HANDLE; pI810->zHandle = DRM_AGP_NO_HANDLE; @@ -522,11 +527,12 @@ I810DRIScreenInit(ScreenPtr pScreen) * under the DRI. */ - drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, &dcacheHandle); + drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, + (drmAddress) &dcacheHandle); pI810->dcacheHandle = dcacheHandle; xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n", - dcacheHandle); + (int)dcacheHandle); #define Elements(x) sizeof(x)/sizeof(*x) for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++) @@ -626,7 +632,8 @@ I810DRIScreenInit(ScreenPtr pScreen) "[agp] GART: no dcache memory found\n"); } - drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, &agpHandle); + drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, + (drmAddress) &agpHandle); pI810->backHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { @@ -652,7 +659,8 @@ I810DRIScreenInit(ScreenPtr pScreen) } if (dcacheHandle == DRM_AGP_NO_HANDLE) { - drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, &agpHandle); + drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, + (drmAddress) &agpHandle); pI810->zHandle = agpHandle; @@ -681,7 +689,8 @@ I810DRIScreenInit(ScreenPtr pScreen) /* Now allocate and bind the agp space. This memory will include the * regular framebuffer as well as texture memory. */ - drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, &agpHandle); + drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, + (drmAddress)&agpHandle); pI810->sysmemHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { @@ -724,7 +733,8 @@ I810DRIScreenInit(ScreenPtr pScreen) pI810->MC.Size = 8 * 1024 * 1024; pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024; } - drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, &agpHandle); + drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, + (drmAddress) &agpHandle); pI810->xvmcHandle = agpHandle; @@ -749,7 +759,8 @@ I810DRIScreenInit(ScreenPtr pScreen) } drmAgpAlloc(pI810->drmSubFD, 4096, 2, - (unsigned long *)&pI810->CursorPhysical, &agpHandle); + (unsigned long *)&pI810->CursorPhysical, + (drmAddress) &agpHandle); pI810->cursorHandle = agpHandle; @@ -773,7 +784,8 @@ I810DRIScreenInit(ScreenPtr pScreen) } drmAgpAlloc(pI810->drmSubFD, 16384, 2, - (unsigned long *)&pI810->CursorARGBPhysical, &agpHandle); + (unsigned long *)&pI810->CursorARGBPhysical, + (drmAddress) &agpHandle); pI810->cursorARGBHandle = agpHandle; @@ -851,7 +863,7 @@ I810DRIScreenInit(ScreenPtr pScreen) if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start, pI810->BackBuffer.Size, DRM_AGP, 0, - &pI810DRI->backbuffer) < 0) { + (drmAddress) &pI810DRI->backbuffer) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); DRICloseScreen(pScreen); @@ -861,7 +873,7 @@ I810DRIScreenInit(ScreenPtr pScreen) pI810DRI->depthbufferSize = pI810->DepthBuffer.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start, pI810->DepthBuffer.Size, DRM_AGP, 0, - &pI810DRI->depthbuffer) < 0) { + (drmAddress) &pI810DRI->depthbuffer) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); @@ -890,7 +902,8 @@ I810DRIScreenInit(ScreenPtr pScreen) return FALSE; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start, - pI810->BufferMem.Size, DRM_AGP, 0, &pI810->buffer_map) < 0) { + pI810->BufferMem.Size, DRM_AGP, 0, + (drmAddress) &pI810->buffer_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); @@ -901,7 +914,8 @@ I810DRIScreenInit(ScreenPtr pScreen) pI810DRI->agp_buf_size = pI810->BufferMem.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start, - pI810->LpRing->mem.Size, DRM_AGP, 0, &pI810->ring_map) < 0) { + pI810->LpRing->mem.Size, DRM_AGP, 0, + (drmAddress) &pI810->ring_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(ring_map) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); @@ -929,7 +943,8 @@ I810DRIScreenInit(ScreenPtr pScreen) I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize); if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start, - pI810->TexMem.Size, DRM_AGP, 0, &pI810DRI->textures) < 0) { + pI810->TexMem.Size, DRM_AGP, 0, + (drmAddress) &pI810DRI->textures) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(textures) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); diff --git a/src/i810_driver.c b/src/i810_driver.c index 8096612b..80ed3bd2 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -60,11 +60,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * DGA */ +#include <math.h> +#include <string.h> +#include <unistd.h> + /* * These are X and server generic header files. */ #include "xf86.h" -#include "xf86_ansic.h" #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86RAC.h" @@ -136,6 +139,7 @@ static SymTabRec I810Chipsets[] = { {PCI_CHIP_E7221_G, "E7221 (i915)"}, {PCI_CHIP_I915_GM, "915GM"}, {PCI_CHIP_I945_G, "945G"}, + {PCI_CHIP_I945_GM, "945GM"}, {-1, NULL} }; @@ -154,6 +158,7 @@ static PciChipsets I810PciChipsets[] = { {PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA}, {PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA}, {PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA}, + {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -299,6 +304,7 @@ const char *I810drmSymbols[] = { "drmGetInterruptFromBusID", "drmGetLibVersion", "drmGetVersion", + "drmRmMap", "drmMMInit", "drmMMtakedown", NULL @@ -308,6 +314,7 @@ const char *I810drmSymbols[] = { const char *I810driSymbols[] = { "DRICloseScreen", "DRICreateInfoRec", + "DRIGetContext", "DRIDestroyInfoRec", "DRIFinishScreenInit", "DRIGetSAREAPrivate", @@ -319,16 +326,17 @@ const char *I810driSymbols[] = { "DRICreatePCIBusID", NULL }; +#endif const char *I810shadowSymbols[] = { "shadowInit", "shadowSetup", "shadowAdd", + "shadowRemove", + "shadowUpdateRotatePacked", NULL }; -#endif - #ifndef I810_DEBUG int I810_DEBUG = (0 /* | DEBUG_ALWAYS_SYNC */ @@ -571,6 +579,7 @@ I810Probe(DriverPtr drv, int flags) case PCI_CHIP_E7221_G: case PCI_CHIP_I915_GM: case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: xf86SetEntitySharable(usedChips[i]); /* Allocate an entity private if necessary */ @@ -1086,7 +1095,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) #ifdef XF86DRI if (!pI810->directRenderingDisabled) { pI810->allowPageFlip = enable; - if (pI810->allowPageFlip == enable) + if (pI810->allowPageFlip == TRUE) { if (!xf86LoadSubModule(pScrn, "shadowfb")) { pI810->allowPageFlip = 0; @@ -1214,21 +1223,24 @@ I810PrintErrorState(ScrnInfoPtr pScrn) I810Ptr pI810 = I810PTR(pScrn); ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", - INREG(PGETBL_CTL), INREG(PGE_ERR)); + (unsigned long) INREG(PGETBL_CTL), (unsigned long) INREG(PGE_ERR)); - ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR), INREG(IPEHR)); + ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long) INREG(IPEIR), + (unsigned long) INREG(IPEHR)); ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", - INREG(LP_RING + RING_TAIL), - INREG(LP_RING + RING_HEAD) & HEAD_ADDR, - INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START)); + (unsigned long) INREG(LP_RING + RING_TAIL), + (unsigned long) INREG(LP_RING + RING_HEAD) & HEAD_ADDR, + (unsigned long) INREG(LP_RING + RING_LEN), + (unsigned long) INREG(LP_RING + RING_START)); ErrorF("eir: %x esr: %x emr: %x\n", INREG16(EIR), INREG16(ESR), INREG16(EMR)); ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM)); - ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS)); + ErrorF("memmode: %lx instps: %lx\n", (unsigned long) INREG(MEMMODE), + (unsigned long) INREG(INST_PS)); ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n", INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); diff --git a/src/i810_hwmc.c b/src/i810_hwmc.c index 5d253236..d56dfc40 100644 --- a/src/i810_hwmc.c +++ b/src/i810_hwmc.c @@ -38,10 +38,11 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" @@ -210,12 +211,12 @@ void I810InitMC(ScreenPtr pScreen) /* Cursor is at a page boundary, Overlay regs are not, don't forget */ if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart, - 4096, DRM_AGP, 0, &pI810->overlay_map) < 0) { + 4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n"); return; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start, - pI810->MC.Size, DRM_AGP, 0, &pI810->mc_map) < 0) { + pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n"); return; } @@ -245,14 +246,14 @@ int I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, if(!pI810->directRenderingEnabled) { - xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateContext: Cannot use XvMC without DRI!\n"); return BadAlloc; } /* Context Already in use! */ if(pI810->xvmcContext) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "I810XvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n"); return BadAlloc; } @@ -267,7 +268,7 @@ int I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, *num_priv = sizeof(I810XvMCCreateContextRec) >> 2; if(drmCreateContext(pI810->drmSubFD, &(contextRec->drmcontext) ) < 0) { - xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateContext: Unable to create DRMContext!\n"); xfree(*priv); return BadAlloc; @@ -299,7 +300,7 @@ int I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, *priv = (long *)xcalloc(2,sizeof(long)); if(!*priv) { - xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateSurface: Unable to allocate memory!\n"); *num_priv = 0; return BadAlloc; @@ -345,7 +346,7 @@ int I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, *priv = (long *)xcalloc(1,sizeof(long)); if(!*priv) { - xf86DrvMsg(X_ERROR, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateSubpicture: Unable to allocate memory!\n"); *num_priv = 0; return BadAlloc; diff --git a/src/i810_io.c b/src/i810_io.c index 8d097f21..abe1d6f0 100644 --- a/src/i810_io.c +++ b/src/i810_io.c @@ -50,7 +50,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "xf86.h" -#include "xf86_ansic.h" #include "xf86_OSproc.h" #include "compiler.h" diff --git a/src/i810_memory.c b/src/i810_memory.c index 816e5d80..82d86eb2 100644 --- a/src/i810_memory.c +++ b/src/i810_memory.c @@ -50,7 +50,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "xf86.h" -#include "xf86_ansic.h" #include "xf86_OSproc.h" #include "i810.h" @@ -265,7 +264,7 @@ I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start, CARD32 fence_mask = 0; if (nr < 0 || nr > 7) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, "%s - fence %d out of range\n", + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s - fence %d out of range\n", "I810SetTiledMemory", nr); return; } @@ -275,21 +274,21 @@ I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start, fence_mask = ~FENCE_START_MASK; if (start & fence_mask) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: start (%x) is not 512k aligned\n", "I810SetTiledMemory", nr, start); return; } if (start % size) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: start (%x) is not size (%x) aligned\n", "I810SetTiledMemory", nr, start, size); return; } if (pitch & 127) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: pitch (%x) not a multiple of 128 bytes\n", "I810SetTiledMemory", nr, pitch); return; @@ -320,7 +319,7 @@ I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start, val |= FENCE_SIZE_32M; break; default: - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: illegal size (0x%x)\n", "I810SetTiledMemory", nr, size); return; @@ -346,7 +345,7 @@ I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start, val |= FENCE_PITCH_32; break; default: - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: illegal size (0x%x)\n", "I810SetTiledMemory", nr, size); return; diff --git a/src/i810_video.c b/src/i810_video.c index f420d2f2..e65a7f6d 100644 --- a/src/i810_video.c +++ b/src/i810_video.c @@ -38,10 +38,11 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" @@ -75,7 +76,8 @@ static void I810QueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer); static int I810PutImage( ScrnInfoPtr, short, short, short, short, short, short, short, short, - int, unsigned char*, short, short, Bool, RegionPtr, pointer); + int, unsigned char*, short, short, Bool, RegionPtr, pointer, + DrawablePtr); static int I810QueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); @@ -973,7 +975,8 @@ I810PutImage( int id, unsigned char* buf, short width, short height, Bool sync, - RegionPtr clipBoxes, pointer data + RegionPtr clipBoxes, pointer data, + DrawablePtr pDraw ){ I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = (I810PortPrivPtr)data; @@ -47,7 +47,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _I830_H_ #define _I830_H_ -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" @@ -58,6 +57,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86int10.h" #include "vbe.h" #include "vgaHW.h" +#include "randrstr.h" #ifdef XF86DRI #include "xf86drm.h" @@ -168,6 +168,8 @@ typedef struct _I830Rec { int fixedPipe; + DisplayModePtr currentMode; + Bool Clone; int CloneRefresh; int CloneHDisplay; @@ -214,13 +216,25 @@ typedef struct _I830Rec { #ifdef I830_XV /* For Xvideo */ I830MemRange *OverlayMem; + I830MemRange LinearMem; #endif + unsigned int LinearAlloc; + + XF86ModReqInfo shadowReq; /* to test for later libshadow */ + I830MemRange RotatedMem; + I830MemRange RotatedMem2; + Rotation rotation; + int InitialRotation; + int displayWidth; + void (*PointerMoved)(int, int, int); + CreateScreenResourcesProcPtr CreateScreenResources; + int *used3D; + I830MemRange ContextMem; #ifdef XF86DRI I830MemRange BackBuffer; I830MemRange DepthBuffer; I830MemRange TexMem; - I830MemRange ContextMem; int TexGranularity; int drmMinor; Bool have3DWindows; @@ -234,6 +248,7 @@ typedef struct _I830Rec { Bool CursorNeedsPhysical; Bool CursorIsARGB; + CursorPtr pCurs; int MonType1; int MonType2; @@ -303,13 +318,6 @@ typedef struct _I830Rec { /* Broken-out options. */ OptionInfoPtr Options; - int rotate; - Bool shadowFB; - - /* Support for shadowFB and rotation. */ - unsigned char *shadowPtr; - int shadowPitch; - void (*PointerMoved)(int, int, int); /* Stolen memory support */ Bool StolenOnly; @@ -335,8 +343,9 @@ typedef struct _I830Rec { Bool checkDevices; int monitorSwitch; int operatingDevices; + int toggleDevices; int savedDevices; - int lastDevice1, lastDevice2; + int lastDevice0, lastDevice1, lastDevice2; /* These are indexed by the display types */ Bool displayAttached[NumDisplayTypes]; @@ -385,7 +394,9 @@ extern void I830PrintErrorState(ScrnInfoPtr pScrn); extern void I830Sync(ScrnInfoPtr pScrn); extern void I830InitHWCursor(ScrnInfoPtr pScrn); extern Bool I830CursorInit(ScreenPtr pScreen); +extern void IntelEmitInvarientState(ScrnInfoPtr pScrn); extern void I830EmitInvarientState(ScrnInfoPtr pScrn); +extern void I915EmitInvarientState(ScrnInfoPtr pScrn); extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer); extern void I830RefreshRing(ScrnInfoPtr pScrn); @@ -399,15 +410,28 @@ extern void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode); extern void I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode); #endif +extern Bool I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, const int flags); +extern Bool I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, const int flags); #ifdef XF86DRI extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags); +extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags); +extern Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags); +extern Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags); extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn); extern Bool I830DRIScreenInit(ScreenPtr pScreen); +extern Bool I830CheckDRIAvailable(ScrnInfoPtr pScrn); extern Bool I830DRIDoMappings(ScreenPtr pScreen); extern Bool I830DRIResume(ScreenPtr pScreen); extern void I830DRICloseScreen(ScreenPtr pScreen); extern Bool I830DRIFinishScreenInit(ScreenPtr pScreen); +extern Bool I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea); +extern void I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea); +extern Bool I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea); +extern void I830DRIUnlock(ScrnInfoPtr pScrn); +extern Bool I830DRILock(ScrnInfoPtr pScrn); +extern Bool I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on); #endif + extern Bool I830AccelInit(ScreenPtr pScreen); extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, @@ -432,11 +456,13 @@ extern Bool I830UnbindGARTMemory(ScrnInfoPtr pScrn); extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags); +extern void I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range); extern void I830PrintAllRegisters(I830RegPtr i830Reg); extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg); extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer); +extern Bool I830IsPrimary(ScrnInfoPtr pScrn); extern DisplayModePtr I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe); @@ -445,12 +471,18 @@ extern void I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe); extern void I830PrintModes(ScrnInfoPtr pScrn); extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh); extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode); -extern void I830PointerMoved(int index, int x, int y); -extern void I830RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); -extern void I830RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); -extern void I830RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); -extern void I830RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); -extern void I830RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode); +extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem); + +/* i830_memory.c */ +Bool I830BindAGPMemory(ScrnInfoPtr pScrn); +Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); + +/* i830_randr.c */ +Bool I830RandRInit(ScreenPtr pScreen, int rotation); +Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, + RRScreenSizePtr pSize); +Rotation I830GetRotation(ScreenPtr pScreen); /* * 12288 is set as the maximum, chosen because it is enough for diff --git a/src/i830_3d.c b/src/i830_3d.c new file mode 100644 index 00000000..debad7c9 --- /dev/null +++ b/src/i830_3d.c @@ -0,0 +1,131 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "i830.h" + +#include "i830_reg.h" + +#define CMD_3D (0x3<<29) + +void I830EmitInvarientState( ScrnInfoPtr pScrn ) +{ + I830Ptr pI830 = I830PTR(pScrn); + + BEGIN_LP_RING(38); + + OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(0)); + OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(1)); + OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(2)); + OUT_RING(_3DSTATE_MAP_CUBE | MAP_UNIT(3)); + + OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_RING(0); + + OUT_RING(_3DSTATE_DFLT_SPEC_CMD); + OUT_RING(0); + + OUT_RING(_3DSTATE_DFLT_Z_CMD); + OUT_RING(0); + + OUT_RING(_3DSTATE_FOG_MODE_CMD); + OUT_RING(FOGFUNC_ENABLE | + FOG_LINEAR_CONST | + FOGSRC_INDEX_Z | + ENABLE_FOG_DENSITY); + OUT_RING(0); + OUT_RING(0); + + + OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(0) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(0) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); + OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(1) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(1) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); + OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(2) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(2) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); + OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(3) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(3) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); + + OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); + OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); + OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); + OUT_RING(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); + + OUT_RING(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + ENABLE_TRI_STRIP_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | + TRI_STRIP_PROVOKE_VRTX(2)); + + OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + + OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_RING(0); + OUT_RING(0); + + OUT_RING(_3DSTATE_VERTEX_TRANSFORM); + OUT_RING(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); + + OUT_RING(_3DSTATE_W_STATE_CMD); + OUT_RING(MAGIC_W_STATE_DWORD1); + OUT_RING(0x3f800000 /* 1.0 in IEEE float */ ); + + + OUT_RING(_3DSTATE_COLOR_FACTOR_CMD); + OUT_RING(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ + + ADVANCE_LP_RING(); +} diff --git a/src/i830_accel.c b/src/i830_accel.c index 7211f4bd..a11f64b9 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -58,7 +58,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#include "xf86_ansic.h" #include "xf86.h" #include "xaarop.h" #include "i830.h" diff --git a/src/i830_common.h b/src/i830_common.h index a0a00ff4..a27bc011 100644 --- a/src/i830_common.h +++ b/src/i830_common.h @@ -51,6 +51,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_FREE 0x09 #define DRM_I830_INIT_HEAP 0x0a #define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_SET_VBLANK_PIPE 0x0d +#define DRM_I830_GET_VBLANK_PIPE 0x0e + typedef struct { enum { @@ -87,6 +91,30 @@ typedef struct { int pf_active; int pf_current_page; /* which buffer is being displayed? */ int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; } drmI830Sarea; /* Flags for perf_boxes @@ -164,5 +192,15 @@ typedef struct { int start; } drmI830MemInitHeap; +typedef struct { + int region; +} drmI830MemDestroyHeap; + +#define DRM_I830_VBLANK_PIPE_A 1 +#define DRM_I830_VBLANK_PIPE_B 2 + +typedef struct { + int pipe; +} drmI830VBlankPipe; #endif /* _I830_DRM_H_ */ diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 24114192..e465b98c 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -58,9 +58,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86fbman.h" @@ -86,12 +87,14 @@ I830InitHWCursor(ScrnInfoPtr pScrn) DPRINTF(PFX, "I830InitHWCursor\n"); /* Initialise the HW cursor registers, leaving the cursor hidden. */ - if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) { + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) { temp = INREG(CURSOR_A_CONTROL); temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL | MCURSOR_PIPE_SELECT); temp |= CURSOR_MODE_DISABLE; temp |= (pI830->pipe << 28); + if(pI830->CursorIsARGB) + temp |= MCURSOR_GAMMA_ENABLE; /* Need to set control, then address. */ OUTREG(CURSOR_A_CONTROL, temp); if (pI830->CursorIsARGB) @@ -112,6 +115,8 @@ I830InitHWCursor(ScrnInfoPtr pScrn) temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | CURSOR_ENABLE | CURSOR_STRIDE_MASK); temp |= (CURSOR_FORMAT_3C); + if (pI830->CursorIsARGB) + temp |= CURSOR_GAMMA_ENABLE; /* This initialises the format and leave the cursor disabled. */ OUTREG(CURSOR_CONTROL, temp); /* Need to set address and size after disabling. */ @@ -139,8 +144,8 @@ I830CursorInit(ScreenPtr pScreen) if (!infoPtr) return FALSE; - infoPtr->MaxWidth = 64; - infoPtr->MaxHeight = 64; + infoPtr->MaxWidth = I810_CURSOR_X; + infoPtr->MaxHeight = I810_CURSOR_Y; infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | HARDWARE_CURSOR_INVERT_MASK | @@ -155,6 +160,8 @@ I830CursorInit(ScreenPtr pScreen) infoPtr->ShowCursor = I830ShowCursor; infoPtr->UseHWCursor = I830UseHWCursor; + pI830->pCurs = NULL; + #ifdef ARGB_CURSOR pI830->CursorIsARGB = FALSE; @@ -179,6 +186,8 @@ I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); + pI830->pCurs = pCurs; + DPRINTF(PFX, "I830UseHWCursor\n"); if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical) return FALSE; @@ -198,6 +207,52 @@ I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) #ifdef ARGB_CURSOR pI830->CursorIsARGB = FALSE; #endif + + memset(pcurs, 0, 64 * 64 / 4); + +#define GetBit(image, x, y)\ + ((int)((*(image + ((x) / 8) + ((y) * (128/8))) &\ + (1 << ( 7 -((x) % 8) ))) ? 1 : 0)) + +#define SetBit(image, x, y)\ + (*(image + (x) / 8 + (y) * (128/8)) |=\ + (int) (1 << (7-((x) % 8)))) + + switch (pI830->rotation) { + case RR_Rotate_90: + for (y = 0; y < 64; y++) { + for (x = 0; x < 64; x++) { + if (GetBit(src, 64 - y - 1, x)) + SetBit(pcurs, x, y); + if (GetBit(src, 128 - y - 1, x)) + SetBit(pcurs, x + 64, y); + } + } + + return; + case RR_Rotate_180: + for (y = 0; y < 64; y++) { + for (x = 0; x < 64; x++) { + if (GetBit(src, 64 - x - 1, 64 - y - 1)) + SetBit(pcurs, x, y); + if (GetBit(src, 128 - x - 1, 64 - y - 1)) + SetBit(pcurs, x + 64, y); + } + } + + return; + case RR_Rotate_270: + for (y = 0; y < 64; y++) { + for (x = 0; x < 64; x++) { + if (GetBit(src, y, 64 - x - 1)) + SetBit(pcurs, x, y); + if (GetBit(src, y + 64, 64 - x - 1)) + SetBit(pcurs, x + 64, y); + } + } + + return; + } for (y = 0; y < 64; y++) { for (x = 0; x < 64 / 4; x++) { @@ -215,6 +270,9 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "I830UseHWCursorARGB\n"); + + pI830->pCurs = pCurs; + if (pScrn->bitsPerPixel == 8) return FALSE; @@ -239,13 +297,52 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) if (!image) return; /* XXX can't happen */ -#ifdef ARGB_CURSOR pI830->CursorIsARGB = TRUE; -#endif w = pCurs->bits->width; h = pCurs->bits->height; + switch (pI830->rotation) { + case RR_Rotate_90: + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + dst[(y) + ((64 - x - 1) * 64)] = *image++; + for(; x < 64; x++) + dst[(y) + ((64 - x - 1) * 64)] = 0; + } + for(; y < 64; y++) { + for(x = 0; x < 64; x++) + dst[(y) + ((64 - x - 1) * 64)] = 0; + } + return; + + case RR_Rotate_180: + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + dst[(64 - x - 1) + ((64 - y - 1) * 64)] = *image++; + for(; x < 64; x++) + dst[(64 - x - 1) + ((64 - y - 1) * 64)] = 0; + } + for(; y < 64; y++) { + for(x = 0; x < 64; x++) + dst[(64 - x - 1) + ((64 - y - 1) * 64)] = 0; + } + return; + + case RR_Rotate_270: + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + dst[(64 - y - 1) + (x * 64)] = *image++; + for(; x < 64; x++) + dst[(64 - y - 1) + (x * 64)] = 0; + } + for(; y < 64; y++) { + for(x = 0; x < 64; x++) + dst[(64 - y - 1) + (x * 64)] = 0; + } + return; + } + for(y = 0; y < h; y++) { for(x = 0; x < w; x++) *dst++ = *image++; @@ -265,9 +362,53 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { I830Ptr pI830 = I830PTR(pScrn); CARD32 temp = 0; - static Bool outsideViewport = FALSE; Bool hide = FALSE, show = FALSE; + int oldx = x, oldy = y; + int hotspotx = 0, hotspoty = 0; +#if 0 + static Bool outsideViewport = FALSE; +#endif + + oldx += pScrn->frameX0; /* undo what xf86HWCurs did */ + oldy += pScrn->frameY0; + + switch (pI830->rotation) { + case RR_Rotate_0: + x = oldx; + y = oldy; + break; + case RR_Rotate_90: + x = oldy; + y = pScrn->pScreen->width - oldx; + hotspoty = I810_CURSOR_X; + break; + case RR_Rotate_180: + x = pScrn->pScreen->width - oldx; + y = pScrn->pScreen->height - oldy; + hotspotx = I810_CURSOR_X; + hotspoty = I810_CURSOR_Y; + break; + case RR_Rotate_270: + x = pScrn->pScreen->height - oldy; + y = oldx; + hotspotx = I810_CURSOR_Y; + break; + } + + x -= hotspotx; + y -= hotspoty; + + /* Now, readjust */ + x -= pScrn->frameX0; + y -= pScrn->frameY0; + /* Clamp the cursor position to the visible screen area */ + if (x >= pScrn->currentMode->HDisplay) x = pScrn->currentMode->HDisplay - 1; + if (y >= pScrn->currentMode->VDisplay) y = pScrn->currentMode->VDisplay - 1; + if (x <= -I810_CURSOR_X) x = -I810_CURSOR_X + 1; + if (y <= -I810_CURSOR_Y) y = -I810_CURSOR_Y + 1; + +#if 0 /* * There is a screen display problem when the cursor position is set * wholely outside of the viewport. We trap that here, turning the @@ -283,6 +424,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) show = TRUE; outsideViewport = FALSE; } +#endif if (x < 0) { temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); @@ -308,7 +450,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) } /* have to upload the base for the new position */ - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + if (IS_I9XX(pI830)) { if (pI830->CursorIsARGB) OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical); else @@ -339,11 +481,11 @@ I830ShowCursor(ScrnInfoPtr pScrn) pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start); pI830->cursorOn = TRUE; - if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) { + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) { temp = INREG(CURSOR_A_CONTROL); temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); if (pI830->CursorIsARGB) - temp |= CURSOR_MODE_64_ARGB_AX; + temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; else temp |= CURSOR_MODE_64_4C_AX; temp |= (pI830->pipe << 28); /* Connect to correct pipe */ @@ -367,7 +509,7 @@ I830ShowCursor(ScrnInfoPtr pScrn) temp &= ~(CURSOR_FORMAT_MASK); temp |= CURSOR_ENABLE; if (pI830->CursorIsARGB) - temp |= CURSOR_FORMAT_ARGB; + temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; else temp |= CURSOR_FORMAT_3C; OUTREG(CURSOR_CONTROL, temp); @@ -387,9 +529,9 @@ I830HideCursor(ScrnInfoPtr pScrn) DPRINTF(PFX, "I830HideCursor\n"); pI830->cursorOn = FALSE; - if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) { + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) { temp = INREG(CURSOR_A_CONTROL); - temp &= ~CURSOR_MODE; + temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE); temp |= CURSOR_MODE_DISABLE; OUTREG(CURSOR_A_CONTROL, temp); /* This is needed to flush the above change. */ @@ -406,7 +548,7 @@ I830HideCursor(ScrnInfoPtr pScrn) } } else { temp = INREG(CURSOR_CONTROL); - temp &= ~CURSOR_ENABLE; + temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE); OUTREG(CURSOR_CONTROL, temp); } } diff --git a/src/i830_dga.c b/src/i830_dga.c index e1991db4..1129fa31 100644 --- a/src/i830_dga.c +++ b/src/i830_dga.c @@ -42,7 +42,6 @@ #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" #include "xf86Pci.h" #include "xf86PciInfo.h" #include "xaa.h" @@ -54,6 +53,7 @@ static Bool I830_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, int *, int *, int *); +static void I830_CloseFramebuffer(ScrnInfoPtr pScrn); static Bool I830_SetMode(ScrnInfoPtr, DGAModePtr); static void I830_Sync(ScrnInfoPtr); static int I830_GetViewport(ScrnInfoPtr); @@ -69,7 +69,7 @@ static void I830_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, static DGAFunctionRec I830DGAFuncs = { I830_OpenFramebuffer, - NULL, + I830_CloseFramebuffer, I830_SetMode, I830_SetViewport, I830_GetViewport, @@ -131,11 +131,22 @@ I830DGAInit(ScreenPtr pScreen) currentMode->yViewportStep = 1; currentMode->viewportFlags = DGA_FLIP_RETRACE; currentMode->offset = 0; - currentMode->address = pI830->FbBase + pScrn->fbOffset; + if (I830IsPrimary(pScrn)) { + currentMode->address = pI830->FbBase + pI830->FrontBuffer.Start; + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + currentMode->address = pI830->FbBase + pI8301->FrontBuffer2.Start; + } - currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; - currentMode->imageWidth = pI830->FbMemBox.x2; - currentMode->imageHeight = pI830->FbMemBox.y2; + currentMode->bytesPerScanline = ((pI830->displayWidth * Bpp) + 3) & ~3L; + if (I830IsPrimary(pScrn)) { + currentMode->imageWidth = pI830->FbMemBox.x2; + currentMode->imageHeight = pI830->FbMemBox.y2; + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + currentMode->imageWidth = pI8301->FbMemBox2.x2; + currentMode->imageHeight = pI8301->FbMemBox2.y2; + } currentMode->pixmapWidth = currentMode->imageWidth; currentMode->pixmapHeight = currentMode->imageHeight; currentMode->maxViewportX = currentMode->imageWidth - @@ -168,6 +179,7 @@ I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) if (!pMode) { /* restore the original mode */ DPRINTF(PFX, "Restoring original mode (from DGA mode)\n"); if (pI830->DGAactive) { + I830_CloseFramebuffer(pScrn); pScrn->currentMode = I830SavedDGAModes[index]; pScrn->SwitchMode(index, pScrn->currentMode, 0); pScrn->AdjustFrame(index, 0, 0, 0); @@ -178,6 +190,15 @@ I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) DPRINTF(PFX, "Setting DGA mode\n"); I830SavedDGAModes[index] = pScrn->currentMode; pI830->DGAactive = TRUE; + if (I830IsPrimary(pScrn)) { + pScrn->fbOffset = pI830->FrontBuffer.Start; + } + else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pScrn->fbOffset = pI8301->FrontBuffer2.Start; + } + pScrn->displayWidth = pI830->displayWidth; + I830SelectBuffer(pScrn, I830_SELECT_FRONT); } pScrn->SwitchMode(index, pMode->mode, 0); @@ -284,13 +305,19 @@ I830_OpenFramebuffer(ScrnInfoPtr pScrn, MARKER(); *name = NULL; /* no special device */ - *mem = (unsigned char *)(pI830->LinearAddr + pScrn->fbOffset); - if (pI830->init == 0) + if (I830IsPrimary(pScrn)) { *size = pI830->FrontBuffer.Size; + *mem = (unsigned char *)(pI830->LinearAddr + pI830->FrontBuffer.Start); + pScrn->fbOffset = pI830->FrontBuffer.Start; + } else { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); *size = pI8301->FrontBuffer2.Size; + *mem = (unsigned char *)(pI8301->LinearAddr + pI8301->FrontBuffer2.Start); + pScrn->fbOffset = pI8301->FrontBuffer2.Start; } + pScrn->displayWidth = pI830->displayWidth; + I830SelectBuffer(pScrn, I830_SELECT_FRONT); *offset = 0; *flags = DGA_NEED_ROOT; @@ -300,3 +327,77 @@ I830_OpenFramebuffer(ScrnInfoPtr pScrn, return TRUE; } + +static void +I830_CloseFramebuffer(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int i; + /* Good pitches to allow tiling. Don't care about pitches < 1024. */ + static const int pitches[] = { +/* + 128 * 2, + 128 * 4, +*/ + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 + }; + + if (I830IsPrimary(pScrn)) { + if (pI830->rotation != RR_Rotate_0) + pScrn->fbOffset = pI830->RotatedMem.Start; + else + pScrn->fbOffset = pI830->FrontBuffer.Start; + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + + if (pI830->rotation != RR_Rotate_0) + pScrn->fbOffset = pI8301->RotatedMem2.Start; + else + pScrn->fbOffset = pI8301->FrontBuffer2.Start; + } + I830SelectBuffer(pScrn, I830_SELECT_FRONT); + + switch (pI830->rotation) { + case RR_Rotate_0: + pScrn->displayWidth = pI830->displayWidth; + break; + case RR_Rotate_90: + pScrn->displayWidth = pScrn->pScreen->width; + break; + case RR_Rotate_180: + pScrn->displayWidth = pI830->displayWidth; + break; + case RR_Rotate_270: + pScrn->displayWidth = pScrn->pScreen->width; + break; + } + + /* As DRI doesn't run on the secondary head, we know that disableTiling + * is always TRUE. + */ + if (I830IsPrimary(pScrn) && !pI830->disableTiling) { +#if 0 + int dWidth = pScrn->displayWidth; /* save current displayWidth */ +#endif + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + break; + } + } + + /* + * If the displayWidth is a tilable pitch, test if there's enough + * memory available to enable tiling. + */ + if (pScrn->displayWidth == pitches[i]) { + /* TODO */ + } + } + +} diff --git a/src/i830_dri.c b/src/i830_dri.c index 092a6ee7..8f8449a9 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -62,9 +62,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <stdio.h> +#include <string.h> +#include <assert.h> + #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" #include "xf86Priv.h" #include "xf86PciInfo.h" @@ -101,7 +104,9 @@ static void I830DRITransitionTo3d(ScreenPtr pScreen); static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); +#if 0 static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); +#endif extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig * configs, @@ -149,9 +154,9 @@ I830InitDma(ScrnInfoPtr pScrn) info.depth_offset = pI830->DepthBuffer.Start; info.w = pScrn->virtualX; info.h = pScrn->virtualY; - info.pitch = pI830->backPitch; - info.back_pitch = pI830->backPitch; - info.depth_pitch = pI830->backPitch; + info.pitch = pI830->displayWidth; + info.back_pitch = pI830->displayWidth; + info.depth_pitch = pI830->displayWidth; info.cpp = pI830->cpp; if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT, @@ -405,18 +410,12 @@ I830InitVisualConfigs(ScreenPtr pScreen) } Bool -I830DRIScreenInit(ScreenPtr pScreen) +I830CheckDRIAvailable(ScrnInfoPtr pScrn) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - DRIInfoPtr pDRIInfo; - I830DRIPtr pI830DRI; - - DPRINTF(PFX, "I830DRIScreenInit\n"); /* Hardware 3D rendering only implemented for 16bpp and 32 bpp */ if (((pScrn->bitsPerPixel / 8) != 2 && pScrn->depth != 16) && (pScrn->bitsPerPixel / 8) != 4) { - xf86DrvMsg(pScreen->myNum, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] Direct rendering only supported in 16 and 32 bpp modes\n"); return FALSE; } @@ -428,7 +427,7 @@ I830DRIScreenInit(ScreenPtr pScreen) if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { - xf86DrvMsg(pScreen->myNum, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] %s failed (libdri.a too old)\n", "I830DRIScreenInit"); return FALSE; } @@ -439,7 +438,7 @@ I830DRIScreenInit(ScreenPtr pScreen) DRIQueryVersion(&major, &minor, &patch); if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { - xf86DrvMsg(pScreen->myNum, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] %s failed because of a version mismatch.\n" "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", @@ -449,6 +448,22 @@ I830DRIScreenInit(ScreenPtr pScreen) } } + return TRUE; +} + +Bool +I830DRIScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo; + I830DRIPtr pI830DRI; + + DPRINTF(PFX, "I830DRIScreenInit\n"); + + if (!I830CheckDRIAvailable(pScrn)) + return FALSE; + pDRIInfo = DRICreateInfoRec(); if (!pDRIInfo) { xf86DrvMsg(pScreen->myNum, X_ERROR, @@ -473,11 +488,13 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL; - pDRIInfo->frameBufferPhysicalAddress = pI830->LinearAddr + +#if 1 /* temporary until this gets removed from the libdri layer */ + pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr + pI830->FrontBuffer.Start; pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp; +#endif pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES; if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES) @@ -572,11 +589,11 @@ I830DRIScreenInit(ScreenPtr pScreen) /* Check the i915 DRM version */ version = drmGetVersion(pI830->drmSubFD); if (version) { - if (version->version_major != 1 || version->version_minor < 1) { + if (version->version_major != 1 || version->version_minor < 4) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] %s failed because of a version mismatch.\n" - "[dri] i915 kernel module version is %d.%d.%d but version 1.1 or greater is needed.\n" + "[dri] i915 kernel module version is %d.%d.%d but version 1.4 or greater is needed.\n" "[dri] Disabling DRI.\n", "I830DRIScreenInit", version->version_major, @@ -601,87 +618,185 @@ I830DRIScreenInit(ScreenPtr pScreen) } Bool -I830DRIDoMappings(ScreenPtr pScreen) +I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); - DRIInfoPtr pDRIInfo = pI830->pDRIInfo; - I830DRIPtr pI830DRI = pDRIInfo->devPrivate; - DPRINTF(PFX, "I830DRIDoMappings\n"); - pI830DRI->regsSize = I830_REG_SIZE; - if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, - pI830DRI->regsSize, DRM_REGISTERS, 0, &pI830DRI->regs) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] Mapping front buffer\n"); + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_FRAME_BUFFER, /*DRM_AGP,*/ + 0, + (drmAddress) &sarea->front_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", - pI830DRI->regs); - - /* - * The tile setup is now initiated from I830BIOSScreenInit(). - */ - - pI830->backPitch = pScrn->displayWidth; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n", + (int)sarea->front_handle); - pI830DRI->backbufferSize = pI830->BackBuffer.Size; + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(sarea->back_offset + pI830->LinearAddr), + sarea->back_size, DRM_AGP, 0, + (drmAddress) &sarea->back_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08x\n", + (int)sarea->back_handle); if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->BackBuffer.Start + pI830->LinearAddr, - pI830->BackBuffer.Size, DRM_AGP, 0, - &pI830DRI->backbuffer) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); + (drm_handle_t)sarea->depth_offset + pI830->LinearAddr, + sarea->depth_size, DRM_AGP, 0, + (drmAddress) &sarea->depth_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Back Buffer = 0x%08x\n", - pI830DRI->backbuffer); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Depth Buffer = 0x%08x\n", + (int)sarea->depth_handle); - pI830DRI->depthbufferSize = pI830->DepthBuffer.Size; +#ifdef NOTTM if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->DepthBuffer.Start + pI830->LinearAddr, - pI830->DepthBuffer.Size, DRM_AGP, 0, - &pI830DRI->depthbuffer) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAddMap(depthbuffer) failed. Disabling DRI\n"); + (drm_handle_t)sarea->tex_offset + pI830->LinearAddr, + sarea->tex_size, DRM_AGP, 0, + (drmAddress) &sarea->tex_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } - xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Depth Buffer = 0x%08x\n", - pI830DRI->depthbuffer); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] textures = 0x%08x\n", + (int)sarea->tex_handle); +#endif + + return TRUE; +} + + +void +I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) +{ + I830Ptr pI830 = I830PTR(pScrn); + +#if 1 + if (sarea->front_handle) { + drmRmMap(pI830->drmSubFD, sarea->front_handle); + sarea->front_handle = 0; + } +#endif + if (sarea->back_handle) { + drmRmMap(pI830->drmSubFD, sarea->back_handle); + sarea->back_handle = 0; + } + if (sarea->depth_handle) { + drmRmMap(pI830->drmSubFD, sarea->depth_handle); + sarea->depth_handle = 0; + } +#ifdef NOTTM + if (sarea->tex_handle) { + drmRmMap(pI830->drmSubFD, sarea->tex_handle); + sarea->tex_handle = 0; + } +#endif +} + +#ifdef NOTTM +static void +I830InitTextureHeap(ScrnInfoPtr pScrn, drmI830Sarea *sarea) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Start up the simple memory manager for agp space */ + drmI830MemInitHeap drmHeap; + drmHeap.region = I830_MEM_REGION_AGP; + drmHeap.start = 0; + drmHeap.size = sarea->tex_size; + + if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT_HEAP, + &drmHeap, sizeof(drmHeap))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] Failed to initialized agp heap manager\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] Initialized kernel agp heap manager, %d\n", + sarea->tex_size); + + I830SetParam(pScrn, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, + sarea->log_tex_granularity); + } +} +#endif + +Bool +I830DRIDoMappings(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + I830DRIPtr pI830DRI = pDRIInfo->devPrivate; + drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); + DPRINTF(PFX, "I830DRIDoMappings\n"); + pI830DRI->regsSize = I830_REG_SIZE; + if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, + pI830DRI->regsSize, DRM_REGISTERS, 0, + (drmAddress) &pI830DRI->regs) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", + (int)pI830DRI->regs); if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr, pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { + (drmAddress) &pI830->ring_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); -#ifdef NOTTM - pI830DRI->textureSize = pI830->TexMem.Size; - pI830DRI->logTextureGranularity = pI830->TexGranularity; + (int)pI830->ring_map); - if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->TexMem.Start + pI830->LinearAddr, - pI830->TexMem.Size, DRM_AGP, 0, - &pI830DRI->textures) < 0) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] drmAddMap(textures) failed. Disabling DRI\n"); + if (!I830InitDma(pScrn)) { DRICloseScreen(pScreen); return FALSE; } +#ifdef NOTTM xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] textures = 0x%08x\n", pI830DRI->textures); #endif - if (!I830InitDma(pScrn)) { + /* init to zero to be safe */ + sarea->front_handle = 0; + sarea->back_handle = 0; + sarea->depth_handle = 0; +#ifdef NOTTM + sarea->tex_handle = 0; +#endif + + /* Assign pScreen */ + pScrn->pScreen = pScreen; + + /* Need to initialize pScreen now to let RandR know. */ + pScrn->pScreen->width = pScrn->virtualX; + pScrn->pScreen->height = pScrn->virtualY; + + /* this will map the screen regions */ + if (!I830UpdateDRIBuffers(pScrn, sarea)) { + /* screen mappings probably failed */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] drmAddMap(screen mappings) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } @@ -714,29 +829,6 @@ I830DRIDoMappings(ScreenPtr pScreen) pI830DRI->irq); } - /* Start up the simple memory manager for agp space */ - { - drmI830MemInitHeap drmHeap; - drmHeap.region = I830_MEM_REGION_AGP; - drmHeap.start = 0; - drmHeap.size = pI830DRI->textureSize; - - if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] Failed to initialized agp heap manager\n"); - } else { - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] Initialized kernel agp heap manager, %d\n", - pI830DRI->textureSize); - - I830SetParam(pScrn, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, - pI830->TexGranularity); - } - } - - - pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate; pI830DRI->deviceID = pI830->PciInfo->chipType; pI830DRI->width = pScrn->virtualX; @@ -857,23 +949,22 @@ I830DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, Bool I830DRIFinishScreenInit(ScreenPtr pScreen) { - drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "I830DRIFinishScreenInit\n"); - memset(sPriv, 0, sizeof(sPriv)); - /* Have shadow run only while there is 3d active. */ +#if 0 if (pI830->allowPageFlip && pI830->drmMinor >= 1) { - shadowSetup(pScreen); shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0); } else +#endif pI830->allowPageFlip = 0; + return DRIFinishScreenInit(pScreen); } @@ -968,8 +1059,13 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, DDXPointPtr pptTmp, pptNew2; int xdir, ydir; +#if 0 int screenwidth = pScrn->virtualX; int screenheight = pScrn->virtualY; +#else + int screenwidth = pScreen->width; + int screenheight = pScreen->height; +#endif BoxPtr pbox = REGION_RECTS(prgnSrc); int nbox = REGION_NUM_RECTS(prgnSrc); @@ -1109,28 +1205,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, pI830->AccelInfoRec->NeedToSync = TRUE; } -/* Initialize the first context */ -void -I830EmitInvarientState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - CARD32 ctx_addr; - - - ctx_addr = pI830->ContextMem.Start; - /* Align to a 2k boundry */ - ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048; - - { - BEGIN_LP_RING(2); - OUT_RING(MI_SET_CONTEXT); - OUT_RING(ctx_addr | - CTXT_NO_RESTORE | - CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); - ADVANCE_LP_RING(); - } -} - /* Use callbacks from dri.c to support pageflipping mode for a single * 3d context without need for any specific full-screen extension. * @@ -1154,7 +1228,7 @@ I830EmitInvarientState(ScrnInfoPtr pScrn) * might be faster, but seems like a lot more work... */ - +#if 0 /* This should be done *before* XAA syncs, * Otherwise will have to sync again??? */ @@ -1163,7 +1237,7 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - RegionPtr damage = &pBuf->damage; + RegionPtr damage = (RegionPtr) shadowDamage(pBuf); int i, num = REGION_NUM_RECTS(damage); BoxPtr pbox = REGION_RECTS(damage); drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); @@ -1199,7 +1273,7 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) ADVANCE_LP_RING(); } } - +#endif static void I830EnablePageFlip(ScreenPtr pScreen) @@ -1264,7 +1338,6 @@ I830DRITransitionMultiToSingle3d(ScreenPtr pScreen) I830EnablePageFlip(pScreen); } - static void I830DRITransitionTo3d(ScreenPtr pScreen) { @@ -1297,3 +1370,136 @@ I830DRITransitionTo2d(ScreenPtr pScreen) } +/** + * Update the SAREA fields with the most recent values. + * This gets called after the screen orientation/rotation changes. + */ +Bool +I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) +{ + I830Ptr pI830 = I830PTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + Bool success; + + I830DRIUnmapScreenRegions(pScrn, sarea); + + if (pI830->rotation == RR_Rotate_0) { + sarea->front_offset = pI830->FrontBuffer.Start; + /* Don't use FrontBuffer.Size here as it includes the pixmap cache area + * Instead, calculate the entire framebuffer. + */ + sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp; + } else { + /* Need to deal with rotated2 once we have dual head DRI */ + sarea->front_offset = pI830->RotatedMem.Start; + sarea->front_size = pI830->RotatedMem.Size; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] init sarea width,height = %d x %d (pitch %d)\n", + pScreen->width, pScreen->height,pScrn->displayWidth); + + sarea->width = pScreen->width; + sarea->height = pScreen->height; + sarea->back_offset = pI830->BackBuffer.Start; + sarea->back_size = pI830->BackBuffer.Size; + sarea->depth_offset = pI830->DepthBuffer.Start; + sarea->depth_size = pI830->DepthBuffer.Size; +#ifdef NOTTM + sarea->tex_offset = pI830->TexMem.Start; + sarea->tex_size = pI830->TexMem.Size; +#endif + sarea->log_tex_granularity = pI830->TexGranularity; + sarea->pitch = pScrn->displayWidth; + sarea->virtualX = pScrn->virtualX; + sarea->virtualY = pScrn->virtualY; + + switch (pI830->rotation) { + case RR_Rotate_0: + sarea->rotation = 0; + break; + case RR_Rotate_90: + sarea->rotation = 90; + break; + case RR_Rotate_180: + sarea->rotation = 180; + break; + case RR_Rotate_270: + sarea->rotation = 270; + break; + default: + sarea->rotation = 0; + } + if (pI830->rotation == RR_Rotate_0) { + sarea->rotated_offset = -1; + sarea->rotated_size = 0; + } + else { + sarea->rotated_offset = pI830->FrontBuffer.Start; + sarea->rotated_size = pI830->FrontBuffer.Size; + } + + /* This is the original pitch */ + sarea->rotated_pitch = pI830->displayWidth; + + success = I830DRIMapScreenRegions(pScrn, sarea); + +#ifdef NOTTM + I830InitTextureHeap(pScrn, sarea); +#endif + + return success; +} + +Bool +I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on) +{ + I830Ptr pI830 = I830PTR(pScrn); + drmI830VBlankPipe pipe; + + if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) { + if (on) { + if (pI830->planeEnabled[1]) + pipe.pipe = DRM_I830_VBLANK_PIPE_B; + else + pipe.pipe = DRM_I830_VBLANK_PIPE_A; + } else { + pipe.pipe = 0; + } + if (drmCommandWrite(pI830->drmSubFD, DRM_I830_SET_VBLANK_PIPE, + &pipe, sizeof (pipe))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Vblank Pipe Setup Failed\n"); + return FALSE; + } + } + + return TRUE; +} + +Bool +I830DRILock(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->directRenderingEnabled && !pI830->LockHeld) { + DRILock(screenInfo.screens[pScrn->scrnIndex], 0); + pI830->LockHeld = 1; + I830RefreshRing(pScrn); + return TRUE; + } + else + return FALSE; +} + + + +void +I830DRIUnlock(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->directRenderingEnabled && pI830->LockHeld) { + DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); + pI830->LockHeld = 0; + } +} diff --git a/src/i830_dri.h b/src/i830_dri.h index 5ac99e5e..31232b80 100644 --- a/src/i830_dri.h +++ b/src/i830_dri.h @@ -9,7 +9,7 @@ #define I830_MAX_DRAWABLES 256 #define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 4 +#define I830_MINOR_VERSION 6 #define I830_PATCHLEVEL 1 #define I830_REG_SIZE 0x80000 @@ -24,6 +24,9 @@ typedef struct _I830DRIRec { drmSize depthbufferSize; drm_handle_t depthbuffer; + drmSize rotatedSize; + drm_handle_t rotatedbuffer; + drm_handle_t textures; int textureSize; @@ -46,6 +49,9 @@ typedef struct _I830DRIRec { int depthOffset; int depthPitch; + int rotatedOffset; + int rotatedPitch; + int logTextureGranularity; int textureOffset; diff --git a/src/i830_driver.c b/src/i830_driver.c index 49a5f055..a9efe991 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -144,8 +144,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * - Fix Xvideo with high-res LFP's * - Add ARGB HW cursor support * - * 30/2005 Alan Hourihane + * 05/2005 Alan Hourihane * - Add Intel(R) 945G support. + * + * 09/2005 Alan Hourihane + * - Add Intel(R) 945GM support. + * */ #ifdef HAVE_CONFIG_H @@ -156,8 +160,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define PRINT_MODE_INFO 0 #endif +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + #include "xf86.h" -#include "xf86_ansic.h" #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86RAC.h" @@ -168,14 +176,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mipointer.h" #include "micmap.h" #include "shadowfb.h" - +#include <X11/extensions/randr.h> #include "fb.h" #include "miscstruct.h" #include "xf86xv.h" #include <X11/extensions/Xv.h> #include "vbe.h" #include "vbeModes.h" - +#include "shadow.h" #include "i830.h" #ifdef XF86DRI @@ -196,6 +204,7 @@ static SymTabRec I830BIOSChipsets[] = { {PCI_CHIP_E7221_G, "E7221 (i915)"}, {PCI_CHIP_I915_GM, "915GM"}, {PCI_CHIP_I945_G, "945G"}, + {PCI_CHIP_I945_GM, "945GM"}, {-1, NULL} }; @@ -208,6 +217,7 @@ static PciChipsets I830BIOSPciChipsets[] = { {PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA}, {PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA}, {PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA}, + {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED} }; @@ -234,8 +244,8 @@ typedef enum { OPTION_CLONE_REFRESH, OPTION_CHECKDEVICES, OPTION_FIXEDPIPE, - OPTION_SHADOW_FB, - OPTION_ROTATE + OPTION_ROTATE, + OPTION_LINEARALLOC } I830Opts; static OptionInfoRec I830BIOSOptions[] = { @@ -255,8 +265,8 @@ static OptionInfoRec I830BIOSOptions[] = { {OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER, {0}, FALSE}, {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE}, {OPTION_FIXEDPIPE, "FixedPipe", OPTV_ANYSTR, {0}, FALSE}, - {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ @@ -271,10 +281,12 @@ static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock *block); static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg); static Bool SetPipeAccess(ScrnInfoPtr pScrn); -static Bool IsPrimary(ScrnInfoPtr pScrn); extern int I830EntityIndex; +/* temporary */ +extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); + #ifdef I830DEBUG void @@ -354,10 +366,12 @@ I830BIOSFreeRec(ScrnInfoPtr pScrn) } while (mode && mode != pScrn->modes); } - if (pI830->vbeInfo) - VBEFreeVBEInfo(pI830->vbeInfo); - if (pI830->pVbe) - vbeFree(pI830->pVbe); + if (I830IsPrimary(pScrn)) { + if (pI830->vbeInfo) + VBEFreeVBEInfo(pI830->vbeInfo); + if (pI830->pVbe) + vbeFree(pI830->pVbe); + } pVesa = pI830->vesa; if (pVesa->monitor) @@ -434,6 +448,94 @@ GetToggleList(ScrnInfoPtr pScrn, int toggle) } static int +GetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + int devices = 0; + int pipe = 0; + int i; + + DPRINTF(PFX, "GetNextDisplayDeviceList\n"); + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f64; + pVbe->pInt10->bx = 0xA00; + pVbe->pInt10->bx |= toggle; + pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); + pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) + return 0; + + for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) { + CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i]; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n", + i, (unsigned long) VODA); + + /* Check if it's a custom Video Output Device Attribute */ + if (!(VODA & 0x80000000)) + continue; + + pipe = (VODA & 0x000000F0) >> 4; + + if (pipe != 0 && pipe != 1) { + pipe = 0; +#if 0 + ErrorF("PIPE %d\n",pipe); +#endif + } + + switch ((VODA & 0x00000F00) >> 8) { + case 0x0: + case 0x1: /* CRT */ + devices |= PIPE_CRT << (pipe == 1 ? 8 : 0); + break; + case 0x2: /* TV/HDTV */ + devices |= PIPE_TV << (pipe == 1 ? 8 : 0); + break; + case 0x3: /* DFP */ + devices |= PIPE_DFP << (pipe == 1 ? 8 : 0); + break; + case 0x4: /* LFP */ + devices |= PIPE_LFP << (pipe == 1 ? 8 : 0); + break; + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle devices 0x%x\n", devices); + + return devices; +} + +static int +GetAttachableDisplayDeviceList(ScrnInfoPtr pScrn) +{ + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe; + int i; + + DPRINTF(PFX, "GetAttachableDisplayDeviceList\n"); + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x5f64; + pVbe->pInt10->bx = 0x900; + pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); + pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); + + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn); + if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) + return 0; + + for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attachable device 0x%lx.\n", + (unsigned long) ((CARD32*)pVbe->memory)[i]); + + return pVbe->pInt10->cx & 0xffff; +} + +static int BitToRefresh(int bits) { int i; @@ -624,6 +726,7 @@ SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh) return 0; } +#if 0 static Bool SetPowerStatus(ScrnInfoPtr pScrn, int mode) { @@ -640,6 +743,7 @@ SetPowerStatus(ScrnInfoPtr pScrn, int mode) return FALSE; } +#endif static Bool GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB, @@ -677,6 +781,7 @@ GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB, return FALSE; } +#if 0 static int GetLFPCompMode(ScrnInfoPtr pScrn) { @@ -695,7 +800,6 @@ GetLFPCompMode(ScrnInfoPtr pScrn) return -1; } -#if 0 static Bool SetLFPCompMode(ScrnInfoPtr pScrn, int compMode) { @@ -849,7 +953,25 @@ I830Set640x480(ScrnInfoPtr pScrn) break; } m |= (1 << 15) | (1 << 14); - return VBESetVBEMode(pI830->pVbe, m, NULL); + if (VBESetVBEMode(pI830->pVbe, m, NULL)) + return TRUE; + + /* if the first failed, let's try the next - usually 800x600 */ + m = 0x32; + switch (pScrn->depth) { + case 15: + case 16: + m = 0x42; + break; + case 24: + m = 0x52; + break; + } + m |= (1 << 15) | (1 << 14); + if (VBESetVBEMode(pI830->pVbe, m, NULL)) + return TRUE; + + return FALSE; } /* This is needed for SetDisplayDevices to work correctly on I915G. @@ -882,7 +1004,7 @@ SetDisplayDevices(ScrnInfoPtr pScrn, int devices) setmode = FALSE; if (pI830->closing) setmode = FALSE; - + if (setmode) { VBEGetVBEMode(pVbe, &getmode1); I830Set640x480(pScrn); @@ -1323,7 +1445,7 @@ I830DetectMemory(ScrnInfoPtr pScrn) * The GTT varying according the the FbMapSize and the popup is 4KB */ range = (pI830->FbMapSize / (1024*1024)) + 4; - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { switch (gmch_ctrl & I830_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: memsize = MB(1) - KB(range); @@ -1341,11 +1463,11 @@ I830DetectMemory(ScrnInfoPtr pScrn) memsize = MB(32) - KB(range); break; case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) + if (IS_I9XX(pI830)) memsize = MB(48) - KB(range); break; case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) + if (IS_I9XX(pI830)) memsize = MB(64) - KB(range); break; } @@ -1414,7 +1536,7 @@ I830MapMem(ScrnInfoPtr pScrn) if (!pI830->FbBase) return FALSE; - if (IsPrimary(pScrn)) + if (I830IsPrimary(pScrn)) pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start; return TRUE; @@ -1513,6 +1635,9 @@ SaveBIOSMemSize(ScrnInfoPtr pScrn) DPRINTF(PFX, "SaveBIOSMemSize\n"); + if (!I830IsPrimary(pScrn)) + return FALSE; + pI830->useSWF1 = FALSE; #if HAVE_GET_PUT_BIOSMEMSIZE @@ -1572,6 +1697,9 @@ TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize, Bool preinit) PCITAG tag =pciTag(0,0,0); + if (!I830IsPrimary(pScrn)) + return 0; + if(!pI830->PciInfo || !(IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830))) return 0; @@ -1618,10 +1746,16 @@ TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize, Bool preinit) if (preinit) { /* reinitialize VBE for new size */ - VBEFreeVBEInfo(pI830->vbeInfo); - vbeFree(pI830->pVbe); - pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + if (I830IsPrimary(pScrn)) { + VBEFreeVBEInfo(pI830->vbeInfo); + vbeFree(pI830->pVbe); + pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); + pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->pVbe = pI8301->pVbe; + pI830->vbeInfo = pI8301->vbeInfo; + } /* verify that change was successful */ if (pI830->vbeInfo->TotalMemory != (newsize >> 16)){ @@ -1648,8 +1782,11 @@ RestoreBIOSMemSize(ScrnInfoPtr pScrn) DPRINTF(PFX, "RestoreBIOSMemSize\n"); + if (!I830IsPrimary(pScrn)) + return; + if (TweakMemorySize(pScrn, pI830->saveBIOSMemSize,FALSE)) - return; + return; if (!pI830->overrideBIOSMemSize) return; @@ -1712,6 +1849,8 @@ SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize) } } +static CARD32 val8[256]; + static void I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) @@ -1786,6 +1925,19 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, } break; default: +#if 1 + /* Dual head 8bpp modes seem to squish the primary's cmap - reload */ + if (I830IsPrimary(pScrn) && xf86IsEntityShared(pScrn->entityList[0]) && + pScrn->depth == 8) { + for(i = 0; i < numColors; i++) { + index = indices[i]; + r = colors[index].red; + g = colors[index].green; + b = colors[index].blue; + val8[index] = (r << 16) | (g << 8) | b; + } + } +#endif for(i = 0; i < numColors; i++) { index = indices[i]; r = colors[index].red; @@ -1793,6 +1945,16 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, b = colors[index].blue; val = (r << 16) | (g << 8) | b; OUTREG(palreg + index * 4, val); +#if 1 + /* Dual head 8bpp modes seem to squish the primary's cmap - reload */ + if (!I830IsPrimary(pScrn) && xf86IsEntityShared(pScrn->entityList[0]) && + pScrn->depth == 8) { + if (palreg == PALETTE_A) + OUTREG(PALETTE_B + index * 4, val8[index]); + else + OUTREG(PALETTE_A + index * 4, val8[index]); + } +#endif } break; } @@ -1868,30 +2030,32 @@ PreInitCleanup(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - if (IsPrimary(pScrn)) + if (I830IsPrimary(pScrn)) { + SetPipeAccess(pScrn); + pI830->entityPrivate->pScrn_1 = NULL; - if (IsPrimary(pScrn) && pI830->LpRing) { - xfree(pI830->LpRing); + if (pI830->LpRing) + xfree(pI830->LpRing); pI830->LpRing = NULL; - } - if (IsPrimary(pScrn) && pI830->CursorMem) { - xfree(pI830->CursorMem); + if (pI830->CursorMem) + xfree(pI830->CursorMem); pI830->CursorMem = NULL; - } - if (IsPrimary(pScrn) && pI830->CursorMemARGB) { - xfree(pI830->CursorMemARGB); + if (pI830->CursorMemARGB) + xfree(pI830->CursorMemARGB); pI830->CursorMemARGB = NULL; - } - if (IsPrimary(pScrn) && pI830->OverlayMem) { - xfree(pI830->OverlayMem); + if (pI830->OverlayMem) + xfree(pI830->OverlayMem); pI830->OverlayMem = NULL; - } - if (IsPrimary(pScrn) && pI830->overlayOn) { - xfree(pI830->overlayOn); + if (pI830->overlayOn) + xfree(pI830->overlayOn); pI830->overlayOn = NULL; + if (pI830->used3D) + xfree(pI830->used3D); + pI830->used3D = NULL; + } else { + if (pI830->entityPrivate) + pI830->entityPrivate->pScrn_2 = NULL; } - if (!IsPrimary(pScrn) && pI830->entityPrivate) - pI830->entityPrivate->pScrn_2 = NULL; RestoreBIOSMemSize(pScrn); if (pI830->swfSaved) { OUTREG(SWF0, pI830->saveSWF0); @@ -1902,8 +2066,8 @@ PreInitCleanup(ScrnInfoPtr pScrn) I830BIOSFreeRec(pScrn); } -static Bool -IsPrimary(ScrnInfoPtr pScrn) +Bool +I830IsPrimary(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); @@ -1920,7 +2084,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) { vgaHWPtr hwp; I830Ptr pI830; - MessageType from; + MessageType from = X_PROBED; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; I830EntPtr pI830Ent = NULL; @@ -1974,6 +2138,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->SaveGeneration = -1; pI830->pEnt = pEnt; + pI830->displayWidth = 640; /* default it */ + if (pI830->pEnt->location.type != BUS_PCI) return FALSE; @@ -1994,6 +2160,30 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } + if (xf86IsEntityShared(pScrn->entityList[0])) { + if (xf86IsPrimInitDone(pScrn->entityList[0])) { + pI830->init = 1; + + if (!pI830Ent->pScrn_1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to setup second head due to primary head failure.\n"); + return FALSE; + } + } else { + xf86SetPrimInitDone(pScrn->entityList[0]); + pI830->init = 0; + } + } + + if (xf86IsEntityShared(pScrn->entityList[0])) { + if (!I830IsPrimary(pScrn)) { + pI830Ent->pScrn_2 = pScrn; + } else { + pI830Ent->pScrn_1 = pScrn; + pI830Ent->pScrn_2 = NULL; + } + } + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; pScrn->monitor = pScrn->confScreen->monitor; pScrn->progClock = TRUE; @@ -2039,9 +2229,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) I830SetPIOAccess(pI830); /* Initialize VBE record */ - if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n"); - return FALSE; + if (I830IsPrimary(pScrn)) { + if ((pI830->pVbe = VBEInit(NULL, pI830->pEnt->index)) == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VBE initialization failed.\n"); + return FALSE; + } + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->pVbe = pI8301->pVbe; } switch (pI830->PciInfo->chipType) { @@ -2090,6 +2285,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) case PCI_CHIP_I945_G: chipname = "945G"; break; + case PCI_CHIP_I945_GM: + chipname = "945GM"; + break; default: chipname = "unknown chipset"; break; @@ -2097,7 +2295,12 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Integrated Graphics Chipset: Intel(R) %s\n", chipname); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + if (I830IsPrimary(pScrn)) { + pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->vbeInfo = pI8301->vbeInfo; + } /* Set the Chipset and ChipRev, allowing config file entries to override. */ if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) { @@ -2109,6 +2312,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) from = X_CONFIG; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", pI830->pEnt->device->chipID); + pI830->PciInfo->chipType = pI830->pEnt->device->chipID; } else { from = X_PROBED; pScrn->chipset = (char *)xf86TokenToString(I830BIOSChipsets, @@ -2127,8 +2331,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->LinearAddr = pI830->pEnt->device->MemBase; from = X_CONFIG; } else { - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { - pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xF0000000; + if (IS_I9XX(pI830)) { + pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xFF000000; from = X_PROBED; } else if (pI830->PciInfo->memBase[1] != 0) { /* XXX Check mask. */ @@ -2149,7 +2353,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->MMIOAddr = pI830->pEnt->device->IOBase; from = X_CONFIG; } else { - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + if (IS_I9XX(pI830)) { pI830->MMIOAddr = pI830->PciInfo->memBase[0] & 0xFFF80000; from = X_PROBED; } else if (pI830->PciInfo->memBase[1]) { @@ -2194,7 +2398,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ } } else { - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + if (IS_I9XX(pI830)) { if (pI830->PciInfo->memBase[2] & 0x08000000) pI830->FbMapSize = 0x8000000; /* 128MB aperture */ else @@ -2207,27 +2411,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->FbMapSize = 0x8000000; } - - if (xf86IsEntityShared(pScrn->entityList[0])) { - if (xf86IsPrimInitDone(pScrn->entityList[0])) { - pI830->init = 1; - - if (!pI830Ent->pScrn_1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to setup second head due to primary head failure.\n"); - return FALSE; - } - - } else { - xf86SetPrimInitDone(pScrn->entityList[0]); - pI830->init = 0; - } - } - if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G) pI830->availablePipes = 1; else - if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) pI830->availablePipes = 2; else pI830->availablePipes = 1; @@ -2251,7 +2438,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } /* Find the maximum amount of agpgart memory available. */ - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { mem = I830CheckAvailableMemory(pScrn); pI830->StolenOnly = FALSE; } else { @@ -2302,9 +2489,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } #endif + pI830->LinearAlloc = 0; + if (xf86GetOptValInteger(pI830->Options, OPTION_LINEARALLOC, + &(pI830->LinearAlloc))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %dKbytes of memory\n", + pI830->LinearAlloc); + } + pI830->fixedPipe = -1; if ((s = xf86GetOptValString(pI830->Options, OPTION_FIXEDPIPE)) && - IsPrimary(pScrn)) { + I830IsPrimary(pScrn)) { if (strstr(s, "A") || strstr(s, "a") || strstr(s, "0")) pI830->fixedPipe = 0; @@ -2317,7 +2511,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->specifiedMonitor = FALSE; if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) && - IsPrimary(pScrn)) { + I830IsPrimary(pScrn)) { char *Mon1; char *Mon2; char *sub; @@ -2429,7 +2623,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - if ((pI830->entityPrivate && IsPrimary(pScrn)) || pI830->Clone) { + if ((pI830->entityPrivate && I830IsPrimary(pScrn)) || pI830->Clone) { if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout " "defined for use in a DualHead or Clone setup.\n"); @@ -2443,37 +2637,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) PreInitCleanup(pScrn); return FALSE; } - } - - xf86GetOptValBool(pI830->Options, OPTION_SHADOW_FB, &pI830->shadowFB); - if (pI830->shadowFB) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: shadow FB enabled\n"); - } - - if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) { - if(!xf86NameCmp(s, "CW")) { - /* accel is disabled below for shadowFB */ - pI830->shadowFB = TRUE; - pI830->rotate = 1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Rotating screen clockwise - acceleration disabled\n"); - } else if(!xf86NameCmp(s, "CCW")) { - pI830->shadowFB = TRUE; - pI830->rotate = -1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" - "counter clockwise - acceleration disabled\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" - "value for Option \"Rotate\"\n", s); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid options are \"CW\" or \"CCW\"\n"); - } - } + } - if (pI830->shadowFB && !pI830->noAccel) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "HW acceleration not supported with \"shadowFB\".\n"); - pI830->noAccel = TRUE; + pI830->rotation = RR_Rotate_0; + if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) { + pI830->InitialRotation = 0; + if(!xf86NameCmp(s, "CW") || !xf86NameCmp(s, "270")) + pI830->InitialRotation = 270; + if(!xf86NameCmp(s, "CCW") || !xf86NameCmp(s, "90")) + pI830->InitialRotation = 90; + if(!xf86NameCmp(s, "180")) + pI830->InitialRotation = 180; } /* @@ -2486,7 +2660,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->checkDevices = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); } else - if (pI830->entityPrivate && !IsPrimary(pScrn) && + if (pI830->entityPrivate && !I830IsPrimary(pScrn) && !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { /* If checklid is off, on the primary head, then * turn it off on the secondary*/ @@ -2525,8 +2699,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pScrn->videoRam = I830_DEFAULT_VIDEOMEM_2D; if (xf86IsEntityShared(pScrn->entityList[0])) { - if (IsPrimary(pScrn)) - pScrn->videoRam *= 2; + if (I830IsPrimary(pScrn)) + pScrn->videoRam += I830_DEFAULT_VIDEOMEM_2D; else pScrn->videoRam = I830_MAXIMUM_VBIOS_MEM; } @@ -2538,6 +2712,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pScrn->videoRam = pI830->pEnt->device->videoRam; } + /* Make sure it's on a page boundary */ + if (pScrn->videoRam & (GTT_PAGE_SIZE - 1)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRAM reduced to %d kByte " + "(page aligned - was %d)\n", pScrn->videoRam & ~(GTT_PAGE_SIZE - 1), pScrn->videoRam); + pScrn->videoRam &= ~(GTT_PAGE_SIZE - 1); + } + DPRINTF(PFX, "Available memory: %dk\n" "Requested memory: %dk\n", mem, pScrn->videoRam); @@ -2597,10 +2779,16 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) pI830->overrideBIOSMemSize = TRUE; SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); - VBEFreeVBEInfo(pI830->vbeInfo); - vbeFree(pI830->pVbe); - pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + if (I830IsPrimary(pScrn)) { + VBEFreeVBEInfo(pI830->vbeInfo); + vbeFree(pI830->pVbe); + pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); + pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->pVbe = pI8301->pVbe; + pI830->vbeInfo = pI8301->vbeInfo; + } pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64); xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2698,21 +2886,15 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS Build: %d\n",pI830->bios_version); - /* Great.. - * Intel changed the BIOS version codes and started at 1200. - * We know that bios codes for 830M started around 2400. - * So we test those conditions to make this judgement. Ugh. - */ - if (pI830->availablePipes == 2 && pI830->bios_version < 2000) + if (IS_I9XX(pI830)) pI830->newPipeSwitch = TRUE; - else if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) + else + if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) { /* BIOS build 3062 changed the pipe switching functionality */ pI830->newPipeSwitch = TRUE; - else - pI830->newPipeSwitch = FALSE; - - if (pI830->newPipeSwitch) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n"); + } else + pI830->newPipeSwitch = FALSE; pI830->devicePresence = FALSE; from = X_DEFAULT; @@ -2727,7 +2909,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) * or, at least it's meant to..... alas it doesn't seem to always work. */ if (pI830->devicePresence) { - int req, att, enc; + int req=0, att=0, enc=0; GetDevicePresence(pScrn, &req, &att, &enc); for (i = 0; i < NumDisplayTypes; i++) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2741,7 +2923,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) /* Save old configuration of detected devices */ pI830->savedDevices = GetDisplayDevices(pScrn); - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { pI830->pipe = pI830->origPipe = GetBIOSPipe(pScrn); /* Override */ @@ -2783,7 +2965,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) "Primary Pipe has been switched from original pipe (%s to %s)\n", pI830->origPipe ? "B" : "A", pI830->pipe ? "B" : "A"); } else { - I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1); + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); pI830->operatingDevices = pI8301->operatingDevices; pI830->pipe = !pI8301->pipe; pI830->MonType1 = pI8301->MonType1; @@ -2815,7 +2997,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to switch to monitor configuration (0x%x)\n", @@ -2832,18 +3014,13 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) PrintDisplayDeviceInfo(pScrn); if (xf86IsEntityShared(pScrn->entityList[0])) { - if (!IsPrimary(pScrn)) { - pI830Ent->pScrn_2 = pScrn; - + if (!I830IsPrimary(pScrn)) { /* This could be made to work with a little more fiddling */ pI830->directRenderingDisabled = TRUE; xf86DrvMsg(pScrn->scrnIndex, from, "Secondary head is using Pipe %s\n", pI830->pipe ? "B" : "A"); } else { - pI830Ent->pScrn_1 = pScrn; - pI830Ent->pScrn_2 = NULL; - xf86DrvMsg(pScrn->scrnIndex, from, "Primary head is using Pipe %s\n", pI830->pipe ? "B" : "A"); } @@ -2853,14 +3030,15 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } /* Alloc our pointers for the primary head */ - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { pI830->LpRing = xalloc(sizeof(I830RingBuffer)); pI830->CursorMem = xalloc(sizeof(I830MemRange)); pI830->CursorMemARGB = xalloc(sizeof(I830MemRange)); pI830->OverlayMem = xalloc(sizeof(I830MemRange)); pI830->overlayOn = xalloc(sizeof(Bool)); + pI830->used3D = xalloc(sizeof(int)); if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB || - !pI830->OverlayMem || !pI830->overlayOn) { + !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not allocate primary data structures.\n"); PreInitCleanup(pScrn); @@ -2872,7 +3050,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } /* Check if the HW cursor needs physical address. */ - if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) pI830->CursorNeedsPhysical = TRUE; else pI830->CursorNeedsPhysical = FALSE; @@ -2884,8 +3062,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) * XXX If we knew the pre-initialised GTT format for certain, we could * probably figure out the physical address even in the StolenOnly case. */ - if (!IsPrimary(pScrn)) { - I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1); + if (!I830IsPrimary(pScrn)) { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); if (!pI8301->SWCursor) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using HW Cursor because it's enabled on primary head.\n"); @@ -3110,7 +3288,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) Clock = pMon->Clock; } - if (DDCclock < 2550 && Clock / 1000.0 > DDCclock) { + if (Clock != 100000000 && DDCclock < 2550 && Clock / 1000.0 > DDCclock) { ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n", p->name, pScrn->monitor->id, Clock/1000.0, DDCclock); @@ -3157,13 +3335,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) * for it, and if there's also enough to allow tiling to be enabled. */ #if defined(XF86DRI) - if (IsPrimary(pScrn) && !pI830->directRenderingDisabled) { + if (!I830CheckDRIAvailable(pScrn)) + pI830->directRenderingDisabled = TRUE; + + if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { int savedDisplayWidth = pScrn->displayWidth; int memNeeded = 0; - /* Good pitches to allow tiling. Don't care about pitches < 256. */ + /* Good pitches to allow tiling. Don't care about pitches < 1024. */ static const int pitches[] = { +/* 128 * 2, 128 * 4, +*/ 128 * 8, 128 * 16, 128 * 32, @@ -3264,8 +3447,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) "Unexpected dry run allocation failure (2).\n"); } } - } + } else #endif + pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ + + pI830->displayWidth = pScrn->displayWidth; SetPipeAccess(pScrn); I830PrintModes(pScrn); @@ -3325,19 +3511,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); - if (pI830->shadowFB) { - if (!xf86LoadSubModule(pScrn, "shadowfb")) { - I830BIOSFreeRec(pScrn); - vbeFree(pI830->pVbe); - return FALSE; - } - xf86LoaderReqSymLists(I810shadowFBSymbols, NULL); +#if 0 + if (I830IsPrimary(pScrn)) { + VBEFreeVBEInfo(pI830->vbeInfo); + vbeFree(pI830->pVbe); } - - VBEFreeVBEInfo(pI830->vbeInfo); pI830->vbeInfo = NULL; - vbeFree(pI830->pVbe); pI830->pVbe = NULL; +#endif /* Use the VBE mode restore workaround by default. */ pI830->vbeRestoreWorkaround = TRUE; @@ -3357,15 +3538,30 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810driSymbols, I810drmSymbols, NULL); } } +#endif - if (!pI830->directRenderingDisabled) { - if (!xf86LoadSubModule(pScrn, "shadow")) { - PreInitCleanup(pScrn); - return FALSE; + /* rotation requires the newer libshadow */ + if (I830IsPrimary(pScrn)) { + int errmaj, errmin; + pI830->shadowReq.majorversion = 1; + pI830->shadowReq.minorversion = 1; + + if (!LoadSubModule(pScrn->module, "shadow", NULL, NULL, NULL, + &pI830->shadowReq, &errmaj, &errmin)) { + pI830->shadowReq.minorversion = 0; + if (!LoadSubModule(pScrn->module, "shadow", NULL, NULL, NULL, + &pI830->shadowReq, &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "shadow", errmaj, errmin); + return FALSE; + } } - xf86LoaderReqSymLists(I810shadowSymbols, NULL); + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->shadowReq.majorversion = pI8301->shadowReq.majorversion; + pI830->shadowReq.minorversion = pI8301->shadowReq.minorversion; + pI830->shadowReq.patchlevel = pI8301->shadowReq.patchlevel; } -#endif + xf86LoaderReqSymLists(I810shadowSymbols, NULL); pI830->preinit = FALSE; @@ -3383,7 +3579,7 @@ CheckInheritedState(ScrnInfoPtr pScrn) int errors = 0, fatal = 0; unsigned long temp, head, tail; - if (!IsPrimary(pScrn)) return TRUE; + if (!I830IsPrimary(pScrn)) return TRUE; /* Check first for page table errors */ temp = INREG(PGE_ERR); @@ -3438,7 +3634,7 @@ ResetState(ScrnInfoPtr pScrn, Bool flush) DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush)); - if (!IsPrimary(pScrn)) return; + if (!I830IsPrimary(pScrn)) return; if (pI830->entityPrivate) pI830->entityPrivate->RingRunning = 0; @@ -3460,9 +3656,9 @@ ResetState(ScrnInfoPtr pScrn, Bool flush) OUTREG(LP_RING + RING_HEAD, 0); OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_START, 0); - + if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor) - pI830->CursorInfoRec->HideCursor(pScrn); + pI830->CursorInfoRec->HideCursor(pScrn); } static void @@ -3473,7 +3669,7 @@ SetFenceRegs(ScrnInfoPtr pScrn) DPRINTF(PFX, "SetFenceRegs\n"); - if (!IsPrimary(pScrn)) return; + if (!I830IsPrimary(pScrn)) return; for (i = 0; i < 8; i++) { OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]); @@ -3493,7 +3689,7 @@ SetRingRegs(ScrnInfoPtr pScrn) if (pI830->noAccel) return; - if (!IsPrimary(pScrn)) return; + if (!I830IsPrimary(pScrn)) return; if (pI830->entityPrivate) pI830->entityPrivate->RingRunning = 1; @@ -3556,7 +3752,7 @@ SaveHWState(ScrnInfoPtr pScrn) DPRINTF(PFX, "SaveHWState\n"); - if (IsPrimary(pScrn) && pI830->pipe != pI830->origPipe) + if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe) SetBIOSPipe(pScrn, pI830->origPipe); else SetPipeAccess(pScrn); @@ -3631,7 +3827,10 @@ RestoreHWState(ScrnInfoPtr pScrn) DPRINTF(PFX, "RestoreHWState\n"); - if (IsPrimary(pScrn) && pI830->pipe != pI830->origPipe) +#ifdef XF86DRI + I830DRISetVBlankInterrupt (pScrn, FALSE); +#endif + if (I830IsPrimary(pScrn) && pI830->pipe != pI830->origPipe) SetBIOSPipe(pScrn, pI830->origPipe); else SetPipeAccess(pScrn); @@ -3745,6 +3944,16 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block) DPRINTF(PFX, "Setting mode 0x%.8x\n", mode); +#if 0 + /* Clear the framebuffer (could do this with VBIOS call) */ + if (I830IsPrimary(pScrn)) + memset(pI830->FbBase + pI830->FrontBuffer.Start, 0, + pScrn->virtualY * pI830->displayWidth * pI830->cpp); + else + memset(pI830->FbBase + pI830->FrontBuffer2.Start, 0, + pScrn->virtualY * pI830->displayWidth * pI830->cpp); +#endif + if (pI830->Clone && pI830->CloneHDisplay && pI830->CloneVDisplay && !pI830->preinit && !pI830->closing) { VbeCRTCInfoBlock newblock; @@ -3814,7 +4023,6 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block) "Set refresh rate to %dHz on Clone head.\n", pI830->CloneRefresh); } - SetPipeAccess(pScrn); } @@ -3894,11 +4102,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) mode = data->mode | (1 << 15) | (1 << 14); #ifdef XF86DRI - if (pI830->directRenderingEnabled && !pI830->LockHeld) { - DRILock(screenInfo.screens[pScrn->scrnIndex], 0); - pI830->LockHeld = 1; - didLock = TRUE; - } + didLock = I830DRILock(pScrn); #endif if (pI830->Clone) { @@ -3925,13 +4129,13 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) * memory than it's aware of. We check for this later, and set it * explicitly if necessary. */ - if (data->data->XResolution != pScrn->displayWidth) { + if (data->data->XResolution != pI830->displayWidth) { if (pI830->Clone) { SetBIOSPipe(pScrn, !pI830->pipe); - VBESetLogicalScanline(pVbe, pScrn->displayWidth); + VBESetLogicalScanline(pVbe, pI830->displayWidth); } SetPipeAccess(pScrn); - VBESetLogicalScanline(pVbe, pScrn->displayWidth); + VBESetLogicalScanline(pVbe, pI830->displayWidth); } if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) { @@ -4007,28 +4211,28 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) * Print out the PIPEACONF and PIPEBCONF registers. */ temp = INREG(PIPEACONF); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", temp); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", + (unsigned long) temp); if (pI830->availablePipes == 2) { temp = INREG(PIPEBCONF); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", temp); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", + (unsigned long) temp); } - - if (xf86IsEntityShared(pScrn->entityList[0])) { /* Clean this up !! */ - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE; CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE; I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); temp = INREG(stridereg); - if (temp / pI8301->cpp != (CARD32)(pI830->entityPrivate->pScrn_1->displayWidth)) { + if (temp / pI8301->cpp != (CARD32)(pI830->displayWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), - (int)(temp / pI8301->cpp), pI830->entityPrivate->pScrn_1->displayWidth); - OUTREG(stridereg, pI830->entityPrivate->pScrn_1->displayWidth * pI8301->cpp); + "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), + (int)(temp / pI8301->cpp), pI830->displayWidth); + OUTREG(stridereg, pI830->displayWidth * pI8301->cpp); } OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); /* Trigger update */ @@ -4042,11 +4246,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE; temp = INREG(stridereg); - if (temp / pI8302->cpp != (CARD32)(pI830->entityPrivate->pScrn_2->displayWidth)) { + if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), - (int)(temp / pI8302->cpp), pI830->entityPrivate->pScrn_2->displayWidth); - OUTREG(stridereg, pI830->entityPrivate->pScrn_2->displayWidth * pI8302->cpp); + "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), + (int)(temp / pI8302->cpp), pI8302->displayWidth); + OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp); } OUTREG(sizereg, (pI830->entityPrivate->pScrn_2->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_2->currentMode->VDisplay - 1) << 16)); /* Trigger update */ @@ -4061,11 +4265,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); temp = INREG(stridereg); - if (temp / pI8301->cpp != (CARD32)(pI830->entityPrivate->pScrn_1->displayWidth)) { + if (temp / pI8301->cpp != (CARD32)(pI8301->displayWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), - (int)(temp / pI8301->cpp), pI830->entityPrivate->pScrn_1->displayWidth); - OUTREG(stridereg, pI830->entityPrivate->pScrn_1->displayWidth * pI8301->cpp); + (int)(temp / pI8301->cpp), pI8301->displayWidth); + OUTREG(stridereg, pI8301->displayWidth * pI8301->cpp); } OUTREG(sizereg, (pI830->entityPrivate->pScrn_1->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_1->currentMode->VDisplay - 1) << 16)); /* Trigger update */ @@ -4077,11 +4281,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE; temp = INREG(stridereg); - if (temp / pI8302->cpp != ((CARD32)pI830->entityPrivate->pScrn_2->displayWidth)) { + if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), - (int)(temp / pI8302->cpp), pI830->entityPrivate->pScrn_2->displayWidth); - OUTREG(stridereg, pI830->entityPrivate->pScrn_2->displayWidth * pI8302->cpp); + (int)(temp / pI8302->cpp), pI8302->displayWidth); + OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp); } OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); /* Trigger update */ @@ -4098,11 +4302,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) continue; temp = INREG(stridereg); - if (temp / pI830->cpp != (CARD32)pScrn->displayWidth) { + if (temp / pI830->cpp != (CARD32)pI830->displayWidth) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i), - (int)(temp / pI830->cpp), pScrn->displayWidth); - OUTREG(stridereg, pScrn->displayWidth * pI830->cpp); + (int)(temp / pI830->cpp), pI830->displayWidth); + OUTREG(stridereg, pI830->displayWidth * pI830->cpp); } OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); /* Trigger update */ @@ -4211,10 +4415,11 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled && didLock) { - DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); - pI830->LockHeld = 0; - } + I830DRISetVBlankInterrupt (pScrn, TRUE); +#endif +#ifdef XF86DRI + if (didLock) + I830DRIUnlock(pScrn); #endif pScrn->vtSema = TRUE; @@ -4228,7 +4433,7 @@ InitRegisterRec(ScrnInfoPtr pScrn) I830RegPtr i830Reg = &pI830->ModeReg; int i; - if (!IsPrimary(pScrn)) return; + if (!I830IsPrimary(pScrn)) return; for (i = 0; i < 8; i++) i830Reg->Fence[i] = 0; @@ -4242,21 +4447,24 @@ I830PrintErrorState(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", - INREG(PGETBL_CTL), INREG(PGE_ERR)); + (unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR)); - ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR), INREG(IPEHR)); + ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR), + (unsigned long)INREG(IPEHR)); ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", - INREG(LP_RING + RING_TAIL), - INREG(LP_RING + RING_HEAD) & HEAD_ADDR, - INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START)); + (unsigned long)INREG(LP_RING + RING_TAIL), + (unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR, + (unsigned long)INREG(LP_RING + RING_LEN), + (unsigned long)INREG(LP_RING + RING_START)); ErrorF("eir: %x esr: %x emr: %x\n", INREG16(EIR), INREG16(ESR), INREG16(EMR)); ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM)); - ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS)); + ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE), + (unsigned long)INREG(INST_PS)); ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n", INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); @@ -4511,6 +4719,129 @@ I830DrmMMTakedown(int drmFD) #endif +static void +I830PointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + I830Ptr pI830 = I830PTR(pScrn); + int newX = x, newY = y; + + switch (pI830->rotation) { + case RR_Rotate_0: + break; + case RR_Rotate_90: + newX = y; + newY = pScrn->pScreen->width - x - 1; + break; + case RR_Rotate_180: + newX = pScrn->pScreen->width - x - 1; + newY = pScrn->pScreen->height - y - 1; + break; + case RR_Rotate_270: + newX = pScrn->pScreen->height - y - 1; + newY = x; + break; + } + + (*pI830->PointerMoved)(index, newX, newY); +} + +static Bool +I830CreateScreenResources (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + pScreen->CreateScreenResources = pI830->CreateScreenResources; + if (!(*pScreen->CreateScreenResources)(pScreen)) + return FALSE; + + if (pI830->rotation != RR_Rotate_0) { + RRScreenSize p; + Rotation requestedRotation = pI830->rotation; + + pI830->rotation = RR_Rotate_0; + + /* Just setup enough for an initial rotate */ + p.width = pScreen->width; + p.height = pScreen->height; + p.mmWidth = pScreen->mmWidth; + p.mmHeight = pScreen->mmHeight; + + pI830->starting = TRUE; /* abuse this for dual head & rotation */ + I830RandRSetConfig (pScreen, requestedRotation, 0, &p); + pI830->starting = FALSE; + } + + return TRUE; +} + +static Bool +I830InitFBManager( + ScreenPtr pScreen, + BoxPtr FullBox +){ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RegionRec ScreenRegion; + RegionRec FullRegion; + BoxRec ScreenBox; + Bool ret; + + ScreenBox.x1 = 0; + ScreenBox.y1 = 0; + ScreenBox.x2 = pScrn->displayWidth; + if (pScrn->virtualX > pScrn->virtualY) + ScreenBox.y2 = pScrn->virtualX; + else + ScreenBox.y2 = pScrn->virtualY; + + if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) || + (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) { + return FALSE; + } + + if (FullBox->y2 < FullBox->y1) return FALSE; + if (FullBox->x2 < FullBox->x2) return FALSE; + + REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1); + REGION_INIT(pScreen, &FullRegion, FullBox, 1); + + REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion); + + ret = xf86InitFBManagerRegion(pScreen, &FullRegion); + + REGION_UNINIT(pScreen, &ScreenRegion); + REGION_UNINIT(pScreen, &FullRegion); + + return ret; +} + +/* Initialize the first context */ +void +IntelEmitInvarientState(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + CARD32 ctx_addr; + + ctx_addr = pI830->ContextMem.Start; + /* Align to a 2k boundry */ + ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048; + + { + BEGIN_LP_RING(2); + OUT_RING(MI_SET_CONTEXT); + OUT_RING(ctx_addr | + CTXT_NO_RESTORE | + CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); + ADVANCE_LP_RING(); + } + + if (IS_I9XX(pI830)) + I915EmitInvarientState(pScrn); + else + I830EmitInvarientState(pScrn); +} + static Bool I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -4518,10 +4849,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) vgaHWPtr hwp; I830Ptr pI830; VisualPtr visual; - I830EntPtr pI830Ent = NULL; I830Ptr pI8301 = NULL; - int width, height, displayWidth; - unsigned char *fbbase; #ifdef XF86DRI Bool driDisabled; #endif @@ -4530,12 +4858,20 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830 = I830PTR(pScrn); hwp = VGAHWPTR(pScrn); - if (xf86IsEntityShared(pScrn->entityList[0])) { - pI830Ent = pI830->entityPrivate; - pI8301 = I830PTR(pI830Ent->pScrn_1); + pScrn->displayWidth = pI830->displayWidth; + + if (I830IsPrimary(pScrn)) { + /* Rotated Buffer */ + memset(&(pI830->RotatedMem), 0, sizeof(pI830->RotatedMem)); + pI830->RotatedMem.Key = -1; + /* Rotated2 Buffer */ + memset(&(pI830->RotatedMem2), 0, sizeof(pI830->RotatedMem2)); + pI830->RotatedMem2.Key = -1; + } + if (xf86IsEntityShared(pScrn->entityList[0])) { /* PreInit failed on the second head, so make sure we turn it off */ - if (IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) { + if (I830IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) { if (pI830->pipe == 0) { pI830->operatingDevices &= 0xFF; } else { @@ -4547,7 +4883,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->starting = TRUE; /* Alloc our pointers for the primary head */ - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { if (!pI830->LpRing) pI830->LpRing = xalloc(sizeof(I830RingBuffer)); if (!pI830->CursorMem) @@ -4558,8 +4894,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->OverlayMem = xalloc(sizeof(I830MemRange)); if (!pI830->overlayOn) pI830->overlayOn = xalloc(sizeof(Bool)); + if (!pI830->used3D) + pI830->used3D = xalloc(sizeof(int)); if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB || - !pI830->OverlayMem || !pI830->overlayOn) { + !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not allocate primary data structures.\n"); return FALSE; @@ -4569,31 +4907,47 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->entityPrivate->XvInUse = -1; } - if (xf86IsEntityShared(pScrn->entityList[0])) { - /* Make our second head point to the first heads structures */ - if (!IsPrimary(pScrn)) { - pI830->LpRing = pI8301->LpRing; - pI830->CursorMem = pI8301->CursorMem; - pI830->CursorMemARGB = pI8301->CursorMemARGB; - pI830->OverlayMem = pI8301->OverlayMem; - pI830->overlayOn = pI8301->overlayOn; - } + /* Make our second head point to the first heads structures */ + if (!I830IsPrimary(pScrn)) { + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->LpRing = pI8301->LpRing; + pI830->CursorMem = pI8301->CursorMem; + pI830->CursorMemARGB = pI8301->CursorMemARGB; + pI830->OverlayMem = pI8301->OverlayMem; + pI830->overlayOn = pI8301->overlayOn; + pI830->used3D = pI8301->used3D; } /* * If we're changing the BIOS's view of the video memory size, do that * first, then re-initialise the VBE information. */ - if (pI830->pVbe) - vbeFree(pI830->pVbe); - pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); - if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE)) - SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + if (I830IsPrimary(pScrn)) { + SetPipeAccess(pScrn); + if (pI830->pVbe) + vbeFree(pI830->pVbe); + pI830->pVbe = VBEInit(NULL, pI830->pEnt->index); + } else { + pI830->pVbe = pI8301->pVbe; + } + + if (I830IsPrimary(pScrn)) { + if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE)) + SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + } + if (!pI830->pVbe) return FALSE; - if (pI830->vbeInfo) - VBEFreeVBEInfo(pI830->vbeInfo); - pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + + if (I830IsPrimary(pScrn)) { + if (pI830->vbeInfo) + VBEFreeVBEInfo(pI830->vbeInfo); + pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe); + } else { + pI830->vbeInfo = pI8301->vbeInfo; + } + + SetPipeAccess(pScrn); miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, @@ -4606,7 +4960,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #ifdef I830_XV pI830->XvEnabled = !pI830->XvDisabled; if (pI830->XvEnabled) { - if (!IsPrimary(pScrn)) { + if (!I830IsPrimary(pScrn)) { if (!pI8301->XvEnabled || pI830->noAccel) { pI830->XvEnabled = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled.\n"); @@ -4622,7 +4976,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { I830ResetAllocations(pScrn, 0); if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL)) @@ -4678,7 +5032,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) */ if (pI830->directRenderingEnabled) { - if (pI830->noAccel || pI830->SWCursor || (pI830->StolenOnly && IsPrimary(pScrn))) { + if (pI830->noAccel || pI830->SWCursor || (pI830->StolenOnly && I830IsPrimary(pScrn))) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it " "needs HW cursor, 2D accel and AGPGART.\n"); pI830->directRenderingEnabled = FALSE; @@ -4706,7 +5060,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * After the 3D allocations have been done, see if there's any free space * that can be added to the framebuffer allocation. */ - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { I830Allocate2DMemory(pScrn, 0); DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n"); @@ -4731,10 +5085,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->memPhysBase = (unsigned long)pI830->FbBase; - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { pScrn->fbOffset = pI830->FrontBuffer.Start; } else { - I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1); pScrn->fbOffset = pI8301->FrontBuffer2.Start; } @@ -4756,26 +5109,10 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n"); - if (pI830->rotate) { - height = pScrn->virtualX; - width = pScrn->virtualY; - } else { - width = pScrn->virtualX; - height = pScrn->virtualY; - } - if (pI830->shadowFB) { - pI830->shadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); - pI830->shadowPtr = xalloc(pI830->shadowPitch * height); - displayWidth = pI830->shadowPitch / (pScrn->bitsPerPixel >> 3); - fbbase = pI830->shadowPtr; - } else { - pI830->shadowPtr = NULL; - fbbase = pI830->FbBase; - displayWidth = pScrn->displayWidth; - } - if (!fbScreenInit(pScreen, fbbase + pScrn->fbOffset, width, height, + if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, + pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - displayWidth, pScrn->bitsPerPixel)) + pScrn->displayWidth, pScrn->bitsPerPixel)) return FALSE; if (pScrn->bitsPerPixel > 8) { @@ -4797,22 +5134,24 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86SetBlackWhitePixels(pScreen); - if (!pI830->shadowFB) - I830DGAInit(pScreen); + I830DGAInit(pScreen); DPRINTF(PFX, - "assert( if(!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) )\n"); - if (IsPrimary(pScrn)) { - if (!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) { + "assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n"); + if (I830IsPrimary(pScrn)) { + if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); - return FALSE; } + + if (pI830->LinearAlloc && xf86InitFBManagerLinear(pScreen, pI830->LinearMem.Offset / pI830->cpp, pI830->LinearMem.Size / pI830->cpp)) + xf86DrvMsg(scrnIndex, X_INFO, + "Using %ld bytes of offscreen memory for linear (offset=0x%lx)\n", pI830->LinearMem.Size, pI830->LinearMem.Offset); + } else { - if (!xf86InitFBManager(pScreen, &(pI8301->FbMemBox2))) { + if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); - return FALSE; } } @@ -4836,31 +5175,6 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n"); - if (pI830->shadowFB) { - RefreshAreaFuncPtr refreshArea = I830RefreshArea; - if (pI830->rotate) { - if (!pI830->PointerMoved) { - pI830->PointerMoved = pScrn->PointerMoved; - pScrn->PointerMoved = I830PointerMoved; - } - switch (pScrn->bitsPerPixel) { - case 8: - refreshArea = I830RefreshArea8; - break; - case 16: - refreshArea = I830RefreshArea16; - break; - case 24: - refreshArea = I830RefreshArea24; - break; - case 32: - refreshArea = I830RefreshArea32; - break; - } - } - ShadowFBInit(pScreen, refreshArea); - } - DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n"); if (!miCreateDefColormap(pScreen)) return FALSE; @@ -4886,12 +5200,13 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif + /* Setup 3D engine, needed for rotation too */ + IntelEmitInvarientState(pScrn); + #ifdef XF86DRI if (pI830->directRenderingEnabled) { pI830->directRenderingOpen = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n"); - /* Setup 3D engine */ - I830EmitInvarientState(pScrn); } else { if (driDisabled) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n"); @@ -4905,7 +5220,23 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScreen->SaveScreen = I830BIOSSaveScreen; pI830->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = I830BIOSCloseScreen; - + + if (pI830->shadowReq.minorversion >= 1) { + /* Rotation */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n"); + xf86DisableRandR(); /* Disable built-in RandR extension */ + shadowSetup(pScreen); + /* support all rotations */ + I830RandRInit(pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270); + pI830->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = I830PointerMoved; + pI830->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = I830CreateScreenResources; + } else { + /* Rotation */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel); + } + if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -4952,6 +5283,30 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif + + switch (pI830->InitialRotation) { + case 0: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 0 degrees\n"); + pI830->rotation = RR_Rotate_0; + break; + case 90: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 90 degrees\n"); + pI830->rotation = RR_Rotate_90; + break; + case 180: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 180 degrees\n"); + pI830->rotation = RR_Rotate_180; + break; + case 270: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotating to 270 degrees\n"); + pI830->rotation = RR_Rotate_270; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad rotation setting - defaulting to 0 degrees\n"); + pI830->rotation = RR_Rotate_0; + break; + } + return TRUE; } @@ -4962,6 +5317,7 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags) ScrnInfoPtr pScrn; I830Ptr pI830; vbeInfoPtr pVbe; + unsigned long Start; pScrn = xf86Screens[scrnIndex]; pI830 = I830PTR(pScrn); @@ -4971,46 +5327,35 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags) x, pI830->xoffset, y, pI830->yoffset); /* Sync the engine before adjust frame */ - if (!pI830->noAccel && pI830->AccelInfoRec) + if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { (*pI830->AccelInfoRec->Sync)(pScrn); + pI830->AccelInfoRec->NeedToSync = FALSE; + } - /* The i830M just happens to have some problems programming offsets via - * this VESA BIOS call. Especially in dual head configurations which - * have high resolutions which cause the DSP{A,B}BASE registers to be - * programmed incorrectly. Thus, it warrants bypassing the BIOS for i830M - * and hitting the DSP{A,B}BASE registers directly. - * - * We could probably do this for other platforms too, but we don't - * know what else the Video BIOS may do when calling it. It seems safe - * though for i830M during testing...... - * - * Also note, calling the Video BIOS version first and then fixing the - * registers fail on i830M and eventually cause a lockup of the hardware - * in my testing. + if (I830IsPrimary(pScrn)) + Start = pI830->FrontBuffer.Start; + else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + Start = pI8301->FrontBuffer2.Start; + } + + /* Sigh... + * It seems that there are quite a few Video BIOS' that get this wrong. + * So, we'll bypass the VBE call and hit the hardware directly. */ if (pI830->Clone) { - if (!IS_I830(pI830)) { - SetBIOSPipe(pScrn, !pI830->pipe); - VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE); + if (!pI830->pipe == 0) { + OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); } else { - if (!pI830->pipe == 0) { - OUTREG(DSPABASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } else { - OUTREG(DSPBBASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } + OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); } } - if (!IS_I830(pI830)) { - SetPipeAccess(pScrn); - VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE); + if (pI830->pipe == 0) { + OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); } else { - if (pI830->pipe == 0) { - OUTREG(DSPABASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } else { - OUTREG(DSPBBASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp)); - } + OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); } } @@ -5075,7 +5420,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags) pI830->CloneVDisplay = 0; } - if (!IsPrimary(pScrn)) { + if (!I830IsPrimary(pScrn)) { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); if (!pI8301->GttBound) { return; @@ -5084,9 +5429,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags) #ifdef XF86DRI if (pI830->directRenderingOpen) { - DPRINTF(PFX, "calling dri lock\n"); - DRILock(screenInfo.screens[scrnIndex], 0); - pI830->LockHeld = 1; + DRILock(screenInfo.screens[pScrn->scrnIndex], 0); drmCtlUninstHandler(pI830->drmSubFD); } @@ -5102,7 +5445,7 @@ I830BIOSLeaveVT(int scrnIndex, int flags) ResetState(pScrn, TRUE); - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { if (!SetDisplayDevices(pScrn, pI830->savedDevices)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch back to original display devices (0x%x)\n", @@ -5115,13 +5458,13 @@ I830BIOSLeaveVT(int scrnIndex, int flags) RestoreHWState(pScrn); RestoreBIOSMemSize(pScrn); - if (IsPrimary(pScrn)) - I830UnbindGARTMemory(pScrn); + if (I830IsPrimary(pScrn)) + I830UnbindAGPMemory(pScrn); if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */ - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { if (!SetDisplayDevices(pScrn, pI830->savedDevices)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch back to original display devices (0x%x) (2)\n", @@ -5215,7 +5558,7 @@ I830DetectMonitorChange(ScrnInfoPtr pScrn) Clock = pMon->Clock; } - if (DDCclock < 2550 && Clock / 1000.0 > DDCclock) { + if (Clock != 100000000 && DDCclock < 2550 && Clock / 1000.0 > DDCclock) { ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n", p->name, pScrn->monitor->id, Clock/1000.0, DDCclock); @@ -5327,7 +5670,13 @@ I830BIOSEnterVT(int scrnIndex, int flags) pI830->leaving = FALSE; - if (IsPrimary(pScrn)) { +#if 1 + /* Clear the framebuffer */ + memset(pI830->FbBase + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * pI830->cpp); +#endif + + if (I830IsPrimary(pScrn)) { /* * This is needed for restoring from ACPI modes (especially S3) * so that we warmboot the Video BIOS. Some platforms have problems, @@ -5335,9 +5684,7 @@ I830BIOSEnterVT(int scrnIndex, int flags) * the Video BIOS with our saved devices, and only when that fails, * we'll warm boot it. */ - /* Check Pipe conf registers or possibly HTOTAL/VTOTAL for 0x00000000)*/ - CARD32 temp = pI830->pipe ? INREG(PIPEBCONF) : INREG(PIPEACONF); - if (!I830Set640x480(pScrn) || !(temp & 0x80000000)) { + if (!I830Set640x480(pScrn)) { xf86Int10InfoPtr pInt; xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -5356,7 +5703,7 @@ I830BIOSEnterVT(int scrnIndex, int flags) "Re-POSTing via int10 failed, trying to continue.\n"); } } - + /* Finally, re-setup the display devices */ if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -5366,25 +5713,21 @@ I830BIOSEnterVT(int scrnIndex, int flags) } /* Setup for device monitoring status */ - pI830->monitorSwitch = INREG(SWF0) & 0x0000FFFF; + pI830->monitorSwitch = pI830->toggleDevices = INREG(SWF0) & 0x0000FFFF; - if (IsPrimary(pScrn)) - if (!I830BindGARTMemory(pScrn)) + if (I830IsPrimary(pScrn)) + if (!I830BindAGPMemory(pScrn)) return FALSE; CheckInheritedState(pScrn); - if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE)) - SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + if (I830IsPrimary(pScrn)) { + if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE)) + SetBIOSMemSize(pScrn, pI830->newBIOSMemSize); + } ResetState(pScrn, FALSE); SetHWOperatingState(pScrn); -#if 1 - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); -#endif - /* Detect monitor change and switch to suitable mode */ if (!pI830->starting) I830DetectMonitorChange(pScrn); @@ -5410,21 +5753,28 @@ I830BIOSEnterVT(int scrnIndex, int flags) if (!pI830->starting) { I830DRIResume(screenInfo.screens[scrnIndex]); - I830EmitInvarientState(pScrn); I830RefreshRing(pScrn); I830Sync(pScrn); DO_RING_IDLE(); DPRINTF(PFX, "calling dri unlock\n"); - DRIUnlock(screenInfo.screens[scrnIndex]); + DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); } pI830->LockHeld = 0; } #endif + /* Needed for rotation */ + IntelEmitInvarientState(pScrn); + if (pI830->checkDevices) pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn); + pI830->currentMode = pScrn->currentMode; + + /* Force invarient state when rotated to be emitted */ + *pI830->used3D = 1<<31; + return TRUE; } @@ -5434,35 +5784,64 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - int ret = TRUE; + Bool ret = TRUE; + PixmapPtr pspix = (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen); DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode); - /* Sync the engine before mode switch */ - if (!pI830->noAccel && pI830->AccelInfoRec) - (*pI830->AccelInfoRec->Sync)(pScrn); - -#ifndef BINDUNBIND -#define BINDUNBIND 0 -#endif -#if BINDUNBIND - if (IsPrimary(pScrn)) - I830UnbindGARTMemory(pScrn); -#endif #ifdef I830_XV /* Give the video overlay code a chance to see the new mode. */ I830VideoSwitchModeBefore(pScrn, mode); #endif - if (!I830VESASetMode(pScrn, mode)) - ret = FALSE; + + /* Sync the engine before mode switch */ + if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { + (*pI830->AccelInfoRec->Sync)(pScrn); + pI830->AccelInfoRec->NeedToSync = FALSE; + } + + /* Check if our currentmode is about to change. We do this so if we + * are rotating, we don't need to call the mode setup again. + */ + if (pI830->currentMode != mode) { + if (!I830VESASetMode(pScrn, mode)) + ret = FALSE; + } + + /* Kludge to detect Rotate or Vidmode switch. Not very elegant, but + * workable given the implementation currently. We only need to call + * the rotation function when we know that the framebuffer has been + * disabled by the EnableDisableFBAccess() function. + * + * The extra WindowTable check detects a rotation at startup. + */ + if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) && + !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved) ) { + if (!I830Rotate(pScrn, mode)) + ret = FALSE; + } + + /* Either the original setmode or rotation failed, so restore the previous + * video mode here, as we'll have already re-instated the original rotation. + */ + if (!ret) { + if (!I830VESASetMode(pScrn, pI830->currentMode)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Failed to restore previous mode (SwitchMode)\n"); + } + #ifdef I830_XV - /* Give the video overlay code a chance to see the new mode. */ - I830VideoSwitchModeAfter(pScrn, mode); + /* Give the video overlay code a chance to see the new mode. */ + I830VideoSwitchModeAfter(pScrn, pI830->currentMode); #endif -#if BINDUNBIND - if (IsPrimary(pScrn)) - I830BindGARTMemory(pScrn); + } else { + pI830->currentMode = mode; + +#ifdef I830_XV + /* Give the video overlay code a chance to see the new mode. */ + I830VideoSwitchModeAfter(pScrn, mode); #endif + } return ret; } @@ -5614,7 +5993,7 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) pI830->CursorInfoRec = 0; } - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { xf86GARTCloseScreen(scrnIndex); xfree(pI830->LpRing); @@ -5627,8 +6006,13 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen) pI830->OverlayMem = NULL; xfree(pI830->overlayOn); pI830->overlayOn = NULL; + xfree(pI830->used3D); + pI830->used3D = NULL; } + if (pI830->shadowReq.minorversion >= 1) + pScrn->PointerMoved = pI830->PointerMoved; + pScrn->vtSema = FALSE; pI830->closing = FALSE; pScreen->CloseScreen = pI830->CloseScreen; @@ -5667,7 +6051,7 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo) I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "Enter VT, event %d, undo: %s\n", event, BOOLTOSTRING(undo)); - + switch(event) { case XF86_APM_SYS_SUSPEND: case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend?*/ @@ -5702,6 +6086,34 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo) SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); } break; + /* This is currently used for ACPI */ + case XF86_APM_CAPABILITY_CHANGED: +#if 0 + /* If we had status checking turned on, turn it off now */ + if (pI830->checkDevices) { + if (pI830->devicesTimer) + TimerCancel(pI830->devicesTimer); + pI830->devicesTimer = NULL; + pI830->checkDevices = FALSE; + } +#endif + if (!I830IsPrimary(pScrn)) + return TRUE; + + ErrorF("I830PMEvent: Capability change\n"); + + /* ACPI Toggle */ + pI830->toggleDevices = GetNextDisplayDeviceList(pScrn, 1); + if (xf86IsEntityShared(pScrn->entityList[0])) { + I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); + pI8302->toggleDevices = pI830->toggleDevices; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ACPI Toggle to 0x%x\n",pI830->toggleDevices); + + I830CheckDevicesTimer(NULL, 0, pScrn); + SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); + break; default: ErrorF("I830PMEvent: received APM event %d\n", event); } @@ -5733,28 +6145,40 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) CARD32 adjust; CARD32 temp = INREG(SWF0) & 0x0000FFFF; int fixup = 0; + I830Ptr pI8301; + I830Ptr pI8302 = NULL; - /* this avoids a BIOS call if possible */ - if (pI830->monitorSwitch != temp) { - I830Ptr pI8301; - I830Ptr pI8302 = NULL; - unsigned int toggle = GetToggleList(pScrn, 1); + if (I830IsPrimary(pScrn)) + pI8301 = pI830; + else + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - GetToggleList(pScrn, 2); - GetToggleList(pScrn, 3); - GetToggleList(pScrn, 4); - - if (IsPrimary(pScrn)) - pI8301 = pI830; - else - pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + if (xf86IsEntityShared(pScrn->entityList[0])) + pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - if (xf86IsEntityShared(pScrn->entityList[0])) - pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); + /* this avoids several BIOS calls if possible */ + if (pI830->monitorSwitch != temp || pI830->monitorSwitch != pI830->toggleDevices) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Hotkey switch to 0x%lx.\n", (unsigned long) temp); + + if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { + (*pI830->AccelInfoRec->Sync)(pScrn); + pI830->AccelInfoRec->NeedToSync = FALSE; + if (xf86IsEntityShared(pScrn->entityList[0])) + pI8302->AccelInfoRec->NeedToSync = FALSE; + } + GetAttachableDisplayDeviceList(pScrn); + + pI8301->lastDevice0 = pI8301->lastDevice1; pI8301->lastDevice1 = pI8301->lastDevice2; pI8301->lastDevice2 = pI8301->monitorSwitch; + if (temp != pI8301->lastDevice1 && + temp != pI8301->lastDevice2) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Detected three device configs.\n"); + } else if (CountBits(temp & 0xff) > 1) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected cloned pipe mode (A).\n"); @@ -5783,22 +6207,23 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) } if (cloned && - ((CountBits(pI830->lastDevice1 & 0xff) > 1) || - ((CountBits((pI830->lastDevice1 & 0xff00) >> 8) > 1))) ) { + ((CountBits(pI8301->lastDevice1 & 0xff) > 1) || + ((CountBits((pI8301->lastDevice1 & 0xff00) >> 8) > 1))) ) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected duplicate (1).\n"); cloned = 0; } else if (cloned && - ((CountBits(pI830->lastDevice2 & 0xff) > 1) || - ((CountBits((pI830->lastDevice2 & 0xff00) >> 8) > 1))) ) { + ((CountBits(pI8301->lastDevice2 & 0xff) > 1) || + ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected duplicate (2).\n"); cloned = 0; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Requested display devices 0x%lx.\n", temp); + "Requested display devices 0x%lx.\n", + (unsigned long) temp); /* If the BIOS doesn't flip between CRT, LFP and CRT+LFP we fake @@ -5809,9 +6234,23 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) * * Cloned pipe mode should only be done when running single head. */ - if (xf86IsEntityShared(pScrn->entityList[0])) + if (xf86IsEntityShared(pScrn->entityList[0])) { cloned = 0; + /* Some BIOS' don't realize we may be in true dual head mode. + * And only display the primary output on both when switching. + * We detect this here and cycle back to both pipes. + */ + if ((pI830->lastDevice0 == temp) && + ((CountBits(pI8301->lastDevice2 & 0xff) > 1) || + ((CountBits((pI8301->lastDevice2 & 0xff00) >> 8) > 1))) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Detected cloned pipe mode when dual head on previous switch. (0x%x -> 0x%x)\n", (int)temp, pI8301->MonType2 << 8 | pI8301->MonType1); + temp = pI8301->MonType2 << 8 | pI8301->MonType1; + } + + } + if (cloned) { if (pI830->Clone) temp = pI8301->MonType2 << 8 | pI8301->MonType1; @@ -5822,19 +6261,39 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) } /* Jump to our next mode if we detect we've been here before */ - if (temp == pI830->lastDevice1 || temp == pI830->lastDevice2) { - temp = toggle; + if (temp == pI8301->lastDevice1 || temp == pI8301->lastDevice2) { + temp = GetToggleList(pScrn, 1); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected duplicate devices. Toggling (0x%lx)\n", temp); + "Detected duplicate devices. Toggling (0x%lx)\n", + (unsigned long) temp); } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected display change operation (0x%x, 0x%x, 0x%lx).\n", - pI8301->lastDevice1, pI8301->lastDevice2, temp); + pI8301->lastDevice1, pI8301->lastDevice2, + (unsigned long) temp); /* So that if we close on the wrong config, we restore correctly */ pI830->specifiedMonitor = TRUE; + if (!xf86IsEntityShared(pScrn->entityList[0])) { + if ((temp & 0xFF00) && (temp & 0x00FF)) { + pI830->Clone = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n"); + } else { + pI830->Clone = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clearing Clone mode\n"); + } + } + + { + /* Turn Cursor off before switching */ + Bool on = pI830->cursorOn; + if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor) + pI830->CursorInfoRec->HideCursor(pScrn); + pI830->cursorOn = on; + } + /* double check the display devices are what's configured and try * not to do it twice because of dual heads with the code above */ if (!SetDisplayDevices(pScrn, temp)) { @@ -5843,24 +6302,43 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) (CountBits((temp & 0xff00) >> 8) > 1)) ) { temp = pI8301->lastDevice2 | pI8301->lastDevice1; xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cloning failed, " - "trying dual pipe clone mode (0x%lx)\n", temp); + "trying dual pipe clone mode (0x%lx)\n", + (unsigned long) temp); if (!SetDisplayDevices(pScrn, temp)) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch " - "to configured display devices (0x%lx).\n", temp); - else + "to configured display devices (0x%lx).\n", + (unsigned long) temp); + else { pI830->Clone = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting Clone mode\n"); + } } } + pI8301->monitorSwitch = temp; pI8301->operatingDevices = temp; + pI8301->toggleDevices = temp; + if (xf86IsEntityShared(pScrn->entityList[0])) { - pI8302->operatingDevices = temp; - pI8302->monitorSwitch = temp; + pI8302->operatingDevices = pI8301->operatingDevices; + pI8302->monitorSwitch = pI8301->monitorSwitch; + pI8302->toggleDevices = pI8301->toggleDevices; } fixup = 1; + +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "ACPI _DGS queried devices is 0x%x, but probed is 0x%x monitorSwitch=0x%x\n", + pI830->toggleDevices, INREG(SWF0), pI830->monitorSwitch); +#endif } else { - int offset = pScrn->fbOffset + ((pScrn->frameY0 * pScrn->displayWidth + pScrn->frameX0) * pI830->cpp); + int offset = -1; + if (I830IsPrimary(pScrn)) + offset = pI8301->FrontBuffer.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp); + else { + offset = pI8301->FrontBuffer2.Start + ((pScrn->frameY0 * pI830->displayWidth + pScrn->frameX0) * pI830->cpp); + } if (pI830->pipe == 0) adjust = INREG(DSPABASE); @@ -5879,6 +6357,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) ScreenPtr pCursorScreen; int x = 0, y = 0; + pCursorScreen = miPointerCurrentScreen(); if (pScrn->pScreen == pCursorScreen) miPointerPosition(&x, &y); @@ -5893,13 +6372,15 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) "Primary pipe is now %s.\n", pI830->pipe ? "B" : "A"); } + pI830->currentMode = NULL; I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0); I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0); + if (xf86IsEntityShared(pScrn->entityList[0])) { ScrnInfoPtr pScrn2; I830Ptr pI8302; - if (IsPrimary(pScrn)) { + if (I830IsPrimary(pScrn)) { pScrn2 = pI830->entityPrivate->pScrn_2; pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); } else { @@ -5907,8 +6388,16 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) pI8302 = I830PTR(pI830->entityPrivate->pScrn_1); } + if (pScrn2->pScreen == pCursorScreen) + miPointerPosition(&x, &y); + + pI8302->currentMode = NULL; I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0); I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0); + + (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE); + (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE); + if (pScrn2->pScreen == pCursorScreen) { int sigstate = xf86BlockSIGIO (); miPointerWarpCursor(pScrn2->pScreen,x,y); @@ -5917,12 +6406,16 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) xf86UnblockSIGIO (sigstate); if (pI8302->CursorInfoRec && !pI8302->SWCursor && pI8302->cursorOn) { pI8302->CursorInfoRec->HideCursor(pScrn); + xf86SetCursor(pScrn2->pScreen, pI830->pCurs, x, y); pI8302->CursorInfoRec->ShowCursor(pScrn); pI8302->cursorOn = TRUE; } } } + (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE); + (*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE); + if (pScrn->pScreen == pCursorScreen) { int sigstate = xf86BlockSIGIO (); miPointerWarpCursor(pScrn->pScreen,x,y); @@ -5931,12 +6424,14 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) xf86UnblockSIGIO (sigstate); if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) { pI830->CursorInfoRec->HideCursor(pScrn); + xf86SetCursor(pScrn->pScreen, pI830->pCurs, x, y); pI830->CursorInfoRec->ShowCursor(pScrn); pI830->cursorOn = TRUE; } } } } + return 1000; } diff --git a/src/i830_memory.c b/src/i830_memory.c index 38b84c02..9b0b2e87 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -54,13 +54,35 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <string.h> + #include "xf86.h" -#include "xf86_ansic.h" #include "xf86_OSproc.h" #include "i830.h" #include "i810_reg.h" +static int nextTile = 0; +static unsigned int tileGeneration = -1; + +#ifndef ALLOCATE_ALL_BIOSMEM +#define ALLOCATE_ALL_BIOSMEM 1 +#endif + +static unsigned long +GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + /* * Allocate memory from the given pool. Grow the pool if needed and if * possible. @@ -212,6 +234,59 @@ AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size, return size; } +void +I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (!range || range->Size == 0) + return; + + if (range->Key != -1) + xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key); + + if (range->Pool) { + /* + * This code essentially resets what I830DoPoolAllocation() did. + * And if things are freed in the wrong order this can break wildly! + * USE CAUTION when changing anything here... + */ + I830MemPool *Pool = range->Pool; + if (pI830->overrideBIOSMemSize && + pI830->BIOSMemorySize > pI830->StolenMemory.Size) + Pool->Total.End = pI830->BIOSMemorySize; + else + Pool->Total.End = pI830->StolenMemory.End; + + if (pI830->StolenOnly) + Pool->Free.End += range->Size; + else + Pool->Free.End = Pool->Total.End; + + if (Pool->Free.End < Pool->Free.Start) { + Pool->Free.End = Pool->Free.Start; + } + + Pool->Free.Size = Pool->Free.End - Pool->Free.Start; + Pool->Total.Size = Pool->Total.End - Pool->Total.Start; + + if (!pI830->StolenOnly) { + pI830->FreeMemory -= Pool->Free.Size; + pI830->MemoryAperture.Start -= (range->Size - Pool->Free.Size); + pI830->MemoryAperture.Size += (range->Size - Pool->Free.Size); + } + } else { + if (range->Alignment == GTT_PAGE_SIZE) + pI830->MemoryAperture.End = range->End; + else + pI830->MemoryAperture.End = range->End - range->Size + range->Alignment; + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; + } + + if (!pI830->StolenOnly) + pI830->FreeMemory += range->Size; + pI830->allocatedMemory -= range->Size; +} unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, @@ -345,25 +420,30 @@ AllocateOverlay(ScrnInfoPtr pScrn, int flags) alloced / 1024, pI830->OverlayMem->Start, pI830->OverlayMem->Physical); } - return TRUE; -} -#endif -static unsigned long -GetFreeSpace(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long extra = 0; + /* Clear linearmem info */ + if (pI830->LinearAlloc) { + memset(&(pI830->LinearMem), 0, sizeof(I830MemRange)); + pI830->LinearMem.Key = -1; - /* First check for free space in StolenPool. */ - if (pI830->StolenPool.Free.Size > 0) - extra = pI830->StolenPool.Free.Size; - /* Next check for unallocated space. */ - if (pI830->FreeMemory > 0) - extra += pI830->FreeMemory; + size = KB(pI830->LinearAlloc); + alloced = I830AllocVidMem(pScrn, &(pI830->LinearMem), &(pI830->StolenPool), + size, GTT_PAGE_SIZE, + FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate linear buffer space\n"); + } + } else + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the linear buffer at 0x%lx\n", s, + alloced / 1024, pI830->LinearMem.Start); + } - return extra; + return TRUE; } +#endif static Bool IsTileable(int pitch) @@ -386,6 +466,150 @@ IsTileable(int pitch) } } +Bool +I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int align; + Bool tileable; + int lines; + int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX; + + /* Rotated Buffer */ + memset(&(pI830->RotatedMem), 0, sizeof(I830MemRange)); + pI830->RotatedMem.Key = -1; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pScrn->displayWidth * pI830->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (height + 15) / 16 * 16; + } else { + lines = height; + } + + size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); + /* + * Try to allocate on the best tile-friendly boundaries. + */ + alloced = 0; + if (tileable) { + align = GetBestTileAlignment(size); + for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) { + alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } + } + if (alloced < size) { + /* Give up on trying to tile */ + tileable = FALSE; + size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); + align = GTT_PAGE_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + } + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate rotated buffer space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the rotated buffer at 0x%lx.\n", s, + alloced / 1024, pI830->RotatedMem.Start); + return TRUE; +} + +Bool +I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int align; + Bool tileable; + int lines; + I830EntPtr pI830Ent = pI830->entityPrivate; + I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); + int height = (pI8302->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pI830Ent->pScrn_2->virtualY : pI830Ent->pScrn_2->virtualX; + + /* Rotated Buffer */ + memset(&(pI830->RotatedMem2), 0, sizeof(I830MemRange)); + pI830->RotatedMem2.Key = -1; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (height + 15) / 16 * 16; + } else { + lines = height; + } + + size = ROUND_TO_PAGE(pI830Ent->pScrn_2->displayWidth * lines * pI8302->cpp); + /* + * Try to allocate on the best tile-friendly boundaries. + */ + alloced = 0; + if (tileable) { + align = GetBestTileAlignment(size); + for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) { + alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } + } + if (alloced < size) { + /* Give up on trying to tile */ + tileable = FALSE; + size = ROUND_TO_PAGE(pI830Ent->pScrn_2->displayWidth * height * pI8302->cpp); + align = GTT_PAGE_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->RotatedMem2), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + } + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate rotated2 buffer space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the rotated2 buffer at 0x%lx.\n", s, + alloced / 1024, pI830->RotatedMem2.Start); + return TRUE; +} + +static unsigned long +GetFreeSpace(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long extra = 0; + + /* First check for free space in StolenPool. */ + if (pI830->StolenPool.Free.Size > 0) + extra = pI830->StolenPool.Free.Size; + /* Next check for unallocated space. */ + if (pI830->FreeMemory > 0) + extra += pI830->FreeMemory; + + return extra; +} + /* * Allocate memory for 2D operation. This includes the (front) framebuffer, * ring buffer, scratch memory, HW cursor. @@ -452,7 +676,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) pI830->FbMemBox2.x1 = 0; pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth; pI830->FbMemBox2.y1 = 0; - pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY; + if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY) + pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX; + else + pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY; /* * Calculate how much framebuffer memory to allocate. For the @@ -511,8 +738,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) alignflags = 0; } - size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines); + if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY) + size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines); + else + size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines); size = ROUND_TO_PAGE(size); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sSecondary framebuffer allocation size: %ld kByte\n", s, size / 1024); @@ -537,7 +768,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) pI830->FbMemBox.x1 = 0; pI830->FbMemBox.x2 = pScrn->displayWidth; pI830->FbMemBox.y1 = 0; - pI830->FbMemBox.y2 = pScrn->virtualY; + if (pScrn->virtualX > pScrn->virtualY) + pI830->FbMemBox.y2 = pScrn->virtualX; + else + pI830->FbMemBox.y2 = pScrn->virtualY; /* * Calculate how much framebuffer memory to allocate. For the @@ -596,8 +830,12 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) alignflags = 0; } - size = lineSize * (pScrn->virtualY + cacheLines); + if (pScrn->virtualX > pScrn->virtualY) + size = lineSize * (pScrn->virtualX + cacheLines); + else + size = lineSize * (pScrn->virtualY + cacheLines); size = ROUND_TO_PAGE(size); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sInitial framebuffer allocation size: %ld kByte\n", s, size / 1024); @@ -633,7 +871,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) maxFb = ROUND_DOWN_TO(maxFb, lineSize); if (maxFb > lineSize * MAX_DISPLAY_HEIGHT) maxFb = lineSize * MAX_DISPLAY_HEIGHT; - if (maxFb > pI830->FrontBuffer.Size) { + if (0/*maxFb > pI830->FrontBuffer.Size*/) { unsigned long oldsize; /* * Sanity check -- the fb should be the last thing allocated at @@ -699,8 +937,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) */ if (!dryrun) { memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); - pI830->Dummy.Key = - xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); + pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); pI830->Dummy.Offset = 0; } #endif @@ -827,13 +1064,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) alloced / 1024, pI830->Scratch2.Start); } } + return TRUE; } -#ifndef ALLOCATE_ALL_BIOSMEM -#define ALLOCATE_ALL_BIOSMEM 1 -#endif - void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags) { @@ -870,20 +1104,6 @@ I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn) } #ifdef XF86DRI -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - static unsigned int myLog2(unsigned int n) { @@ -897,18 +1117,16 @@ myLog2(unsigned int n) } Bool -I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) +I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size, alloced, align = 0; - int i; Bool tileable; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); int verbosity = dryrun ? 4 : 1; const char *s = dryrun ? "[dryrun] " : ""; int lines; - - DPRINTF(PFX, "I830Allocate3DMemory\n"); + int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX; /* Back Buffer */ memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); @@ -917,9 +1135,9 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) IsTileable(pScrn->displayWidth * pI830->cpp); if (tileable) { /* Make the height a multiple of the tile height (16) */ - lines = (pScrn->virtualY + 15) / 16 * 16; + lines = (height + 15) / 16 * 16; } else { - lines = pScrn->virtualY; + lines = height; } size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); @@ -941,7 +1159,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) if (alloced < size) { /* Give up on trying to tile */ tileable = FALSE; - size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); + size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); align = GTT_PAGE_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), &(pI830->StolenPool), size, align, @@ -958,16 +1176,41 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s, alloced / 1024, pI830->BackBuffer.Start); + return TRUE; +} + +Bool +I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced, align = 0; + Bool tileable; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int lines; + int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX; + /* Depth Buffer -- same size as the back buffer */ memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); pI830->DepthBuffer.Key = -1; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pScrn->displayWidth * pI830->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (height + 15) / 16 * 16; + } else { + lines = height; + } + + size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); /* * Try to allocate on the best tile-friendly boundaries. */ alloced = 0; if (tileable) { - /* Start with the previous align value. */ - for (; align >= KB(512); align >>= 1) { + align = GetBestTileAlignment(size); + for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) { alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), &(pI830->StolenPool), size, align, flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | @@ -979,7 +1222,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) if (alloced < size) { /* Give up on trying to tile */ tileable = FALSE; - size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); + size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); align = GTT_PAGE_SIZE; alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), &(pI830->StolenPool), size, align, @@ -996,24 +1239,18 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s, alloced / 1024, pI830->DepthBuffer.Start); - /* Space for logical context. 32k is fine for right now. */ - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate logical context space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the logical context at 0x%lx.\n", s, - alloced / 1024, pI830->ContextMem.Start); + return TRUE; +} +Bool +I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + int i; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; /* Allocate the remaining space for textures. */ memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); @@ -1056,6 +1293,47 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) return TRUE; } + +Bool +I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + + DPRINTF(PFX, "I830Allocate3DMemory\n"); + + /* Space for logical context. 32k is fine for right now. */ + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), + &(pI830->StolenPool), size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate logical context space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the logical context at 0x%lx.\n", s, + alloced / 1024, pI830->ContextMem.Start); + + if (!I830AllocateBackBuffer(pScrn, flags)) + return FALSE; + + if (!I830AllocateDepthBuffer(pScrn, flags)) + return FALSE; + + if (!I830AllocateTextureMemory(pScrn, flags)) + return FALSE; + + return TRUE; +} #endif /* Allocate pool space that isn't pre-allocated */ @@ -1083,9 +1361,8 @@ I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool) if (pool->Total.Size > pool->Fixed.Size) { pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size; - pool->Allocated.Key = - xf86AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size, - 0, NULL); + pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, + pool->Allocated.Size, 0, NULL); if (pool->Allocated.Key == -1) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n"); return FALSE; @@ -1119,8 +1396,8 @@ static unsigned long topOfMem = 0; #define PACK_RANGES 0 #define POOL_RANGES 0 -static Bool -FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem) +Bool +I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem) { #if POOL_RANGES I830Ptr pI830 = I830PTR(pScrn); @@ -1190,26 +1467,28 @@ I830FixupOffsets(ScrnInfoPtr pScrn) topOfMem = pI830->StolenPool.Total.End; if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - FixOffset(pScrn, &(pI830->FrontBuffer2)); - FixOffset(pScrn, &(pI830->FrontBuffer)); - FixOffset(pScrn, pI830->CursorMem); - FixOffset(pScrn, pI830->CursorMemARGB); - FixOffset(pScrn, &(pI830->LpRing->mem)); - FixOffset(pScrn, &(pI830->Scratch)); + I830FixOffset(pScrn, &(pI830->FrontBuffer2)); + I830FixOffset(pScrn, &(pI830->FrontBuffer)); + I830FixOffset(pScrn, pI830->CursorMem); + I830FixOffset(pScrn, pI830->CursorMemARGB); + I830FixOffset(pScrn, &(pI830->LpRing->mem)); + I830FixOffset(pScrn, &(pI830->Scratch)); if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - FixOffset(pScrn, &(pI830->Scratch2)); + I830FixOffset(pScrn, &(pI830->Scratch2)); #ifdef I830_XV if (pI830->XvEnabled) { - FixOffset(pScrn, pI830->OverlayMem); + I830FixOffset(pScrn, pI830->OverlayMem); + if (pI830->LinearAlloc) + I830FixOffset(pScrn, &(pI830->LinearMem)); } #endif #ifdef XF86DRI if (pI830->directRenderingEnabled) { - FixOffset(pScrn, &(pI830->BackBuffer)); - FixOffset(pScrn, &(pI830->DepthBuffer)); - FixOffset(pScrn, &(pI830->ContextMem)); + I830FixOffset(pScrn, &(pI830->ContextMem)); + I830FixOffset(pScrn, &(pI830->BackBuffer)); + I830FixOffset(pScrn, &(pI830->DepthBuffer)); #ifdef NOTTM - FixOffset(pScrn, &(pI830->TexMem)); + I830FixOffset(pScrn, &(pI830->TexMem)); #endif } #endif @@ -1238,34 +1517,34 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, nr, start, pitch, size / 1024); if (nr < 0 || nr > 7) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: fence %d out of range\n",nr); return; } i830Reg->Fence[nr] = 0; - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) + if (IS_I9XX(pI830)) fence_mask = ~I915G_FENCE_START_MASK; else fence_mask = ~I830_FENCE_START_MASK; if (start & fence_mask) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) ? "1MB" : "512k"); + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); return; } if (start % size) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", nr, start, size / 1024); return; } if (pitch & 127) { - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", nr, pitch); return; @@ -1273,7 +1552,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val = (start | FENCE_X_MAJOR | FENCE_VALID); - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + if (IS_I9XX(pI830)) { switch (size) { case MB(1): val |= I915G_FENCE_SIZE_1M; @@ -1297,7 +1576,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= I915G_FENCE_SIZE_64M; break; default: - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); return; } @@ -1328,13 +1607,13 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= FENCE_SIZE_64M; break; default: - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); return; } } - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) + if (IS_I9XX(pI830)) fence_pitch = pitch / 512; else fence_pitch = pitch / 128; @@ -1362,7 +1641,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= FENCE_PITCH_64; break; default: - xf86DrvMsg(X_WARNING, pScrn->scrnIndex, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "SetFence: %d: illegal pitch (%d)\n", nr, pitch); return; } @@ -1375,8 +1654,6 @@ MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem) { I830Ptr pI830 = I830PTR(pScrn); int pitch, ntiles, i; - static int nextTile = 0; - static unsigned int tileGeneration = -1; #if 0 /* Hack to "improve" the alignment of the front buffer. @@ -1411,6 +1688,14 @@ void I830SetupMemoryTiling(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + int i; + + /* Clear out */ + for (i = 0; i < 8; i++) + pI830->ModeReg.Fence[i] = 0; + + nextTile = 0; + tileGeneration = -1; /* We currently only attempt to tile the back and depth buffers. */ if (!pI830->directRenderingEnabled) @@ -1464,10 +1749,31 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) "Activating tiled memory for the depth buffer.\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the back buffer.\n"); + "MakeTiles failed for the depth buffer.\n"); } } + if (pI830->RotatedMem.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->RotatedMem))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Activating tiled memory for the rotated buffer.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the rotated buffer.\n"); + } + } + +#if 0 + if (pI830->RotatedMem2.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->RotatedMem2))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Activating tiled memory for the rotated2 buffer.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the rotated buffer.\n"); + } + } +#endif } #endif /* XF86DRI */ @@ -1484,12 +1790,12 @@ BindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) } Bool -I830BindGARTMemory(ScrnInfoPtr pScrn) +I830BindAGPMemory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, - "I830BindGARTMemory: StolenOnly is %s, pI830->GttBound is %s\n", + "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); if (pI830->StolenOnly == TRUE) @@ -1523,17 +1829,29 @@ I830BindGARTMemory(ScrnInfoPtr pScrn) if (!BindMemRange(pScrn, &(pI830->Scratch2))) return FALSE; #ifdef I830_XV - if (!BindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; + if (pI830->XvEnabled) { + if (!BindMemRange(pScrn, pI830->OverlayMem)) + return FALSE; + if (pI830->LinearAlloc) + if (!BindMemRange(pScrn, &(pI830->LinearMem))) + return FALSE; + } #endif + if (pI830->RotatedMem.Start) + if (!BindMemRange(pScrn, &(pI830->RotatedMem))) + return FALSE; + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2 && + pI830->RotatedMem2.Start) + if (!BindMemRange(pScrn, &(pI830->RotatedMem2))) + return FALSE; #ifdef XF86DRI if (pI830->directRenderingEnabled) { + if (!BindMemRange(pScrn, &(pI830->ContextMem))) + return FALSE; if (!BindMemRange(pScrn, &(pI830->BackBuffer))) return FALSE; if (!BindMemRange(pScrn, &(pI830->DepthBuffer))) return FALSE; - if (!BindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; #ifdef NOTTM if (!BindMemRange(pScrn, &(pI830->TexMem))) return FALSE; @@ -1560,12 +1878,12 @@ UnbindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) Bool -I830UnbindGARTMemory(ScrnInfoPtr pScrn) +I830UnbindAGPMemory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, - "I830UnbindGARTMemory: StolenOnly is %s, pI830->GttBound is %s\n", + "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); if (pI830->StolenOnly == TRUE) @@ -1597,17 +1915,29 @@ I830UnbindGARTMemory(ScrnInfoPtr pScrn) if (!UnbindMemRange(pScrn, &(pI830->Scratch2))) return FALSE; #ifdef I830_XV - if (!UnbindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; + if (pI830->XvEnabled) { + if (!UnbindMemRange(pScrn, pI830->OverlayMem)) + return FALSE; + if (pI830->LinearAlloc) + if (!UnbindMemRange(pScrn, &(pI830->LinearMem))) + return FALSE; + } #endif + if (pI830->RotatedMem.Start) + if (!UnbindMemRange(pScrn, &(pI830->RotatedMem))) + return FALSE; + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2 && + pI830->RotatedMem2.Start) + if (!UnbindMemRange(pScrn, &(pI830->RotatedMem2))) + return FALSE; #ifdef XF86DRI if (pI830->directRenderingEnabled) { + if (!UnbindMemRange(pScrn, &(pI830->ContextMem))) + return FALSE; if (!UnbindMemRange(pScrn, &(pI830->BackBuffer))) return FALSE; if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer))) return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; #ifdef NOTTM if (!UnbindMemRange(pScrn, &(pI830->TexMem))) return FALSE; @@ -1627,7 +1957,7 @@ long I830CheckAvailableMemory(ScrnInfoPtr pScrn) { AgpInfoPtr agpinf; - long maxPages; + int maxPages; if (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex) || @@ -1636,9 +1966,8 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn) return -1; maxPages = agpinf->totalPages - agpinf->usedPages; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, - "Checking Available AGP Memory: %ld kB available (total %ld kB, used %ld kB)\n", - maxPages * 4, agpinf->totalPages * 4, agpinf->usedPages * 4); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", + "I830CheckAvailableMemory", maxPages * 4); return maxPages * 4; } diff --git a/src/i830_modes.c b/src/i830_modes.c index 457b583e..97e40e0a 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -38,8 +38,10 @@ #include "config.h" #endif +#include <stdio.h> +#include <string.h> + #include "xf86.h" -#include "xf86_ansic.h" #include "vbe.h" #include "vbeModes.h" #include "i830.h" @@ -346,7 +348,7 @@ I830GetGTF (int h_pixels, int v_lines, float freq, m->Clock = (int)(pixel_freq * 1000); m->SynthClock = m->Clock; m->HSync = h_freq; - m->VRefresh = freq; + m->VRefresh = v_frame_rate /* freq */; snprintf(modename, sizeof(modename), "%dx%d", m->HDisplay,m->VDisplay); m->name = xnfstrdup(modename); @@ -512,7 +514,7 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, xf86ErrorFVerb(DEBUG_VERB, " WinBSegment: 0x%x\n", mode->WinBSegment); xf86ErrorFVerb(DEBUG_VERB, - " WinFuncPtr: 0x%lx\n", mode->WinFuncPtr); + " WinFuncPtr: 0x%lx\n", (unsigned long)mode->WinFuncPtr); xf86ErrorFVerb(DEBUG_VERB, " BytesPerScanline: %d\n", mode->BytesPerScanline); xf86ErrorFVerb(DEBUG_VERB, @@ -555,7 +557,8 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, " DirectColorModeInfo: %d\n", mode->DirectColorModeInfo); if (major >= 2) { xf86ErrorFVerb(DEBUG_VERB, - " PhysBasePtr: 0x%lx\n", mode->PhysBasePtr); + " PhysBasePtr: 0x%lx\n", + (unsigned long)mode->PhysBasePtr); if (major >= 3) { xf86ErrorFVerb(DEBUG_VERB, " LinBytesPerScanLine: %d\n", mode->LinBytesPerScanLine); @@ -580,7 +583,8 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, xf86ErrorFVerb(DEBUG_VERB, " LinRsvdFieldPosition: %d\n", mode->LinRsvdFieldPosition); xf86ErrorFVerb(DEBUG_VERB, - " MaxPixelClock: %ld\n", mode->MaxPixelClock); + " MaxPixelClock: %ld\n", (unsigned long) + mode->MaxPixelClock); } } diff --git a/src/i830_randr.c b/src/i830_randr.c new file mode 100644 index 00000000..0311f2b6 --- /dev/null +++ b/src/i830_randr.c @@ -0,0 +1,355 @@ +/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.3 2004/07/30 21:53:09 eich Exp $ */ +/* + * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.7tsi Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xf86.h" +#include "os.h" +#include "mibank.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include <randrstr.h> + +#include "i830.h" + +typedef struct _i830RandRInfo { + int virtualX; + int virtualY; + int mmWidth; + int mmHeight; + int maxX; + int maxY; + Rotation rotation; /* current mode */ + Rotation supported_rotations; /* driver supported */ +} XF86RandRInfoRec, *XF86RandRInfoPtr; + +static int i830RandRIndex; +static int i830RandRGeneration; + +#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[i830RandRIndex].ptr) + +static int +I830RandRModeRefresh (DisplayModePtr mode) +{ + if (mode->VRefresh) + return (int) (mode->VRefresh + 0.5); + else + return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5); +} + +static Bool +I830RandRGetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + RRScreenSizePtr pSize; + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int refresh0 = 60; + int maxX = 0, maxY = 0; + + *rotations = randrp->supported_rotations; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = scrp->virtualX; + randrp->virtualY = scrp->virtualY; + } + + for (mode = scrp->modes; ; mode = mode->next) + { + int refresh = I830RandRModeRefresh (mode); + if (randrp->maxX == 0 || randrp->maxY == 0) + { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode == scrp->modes) + refresh0 = refresh; + pSize = RRRegisterSize (pScreen, + mode->HDisplay, mode->VDisplay, + randrp->mmWidth, randrp->mmHeight); + if (!pSize) + return FALSE; + RRRegisterRate (pScreen, pSize, refresh); + if (mode == scrp->currentMode && + mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY) + RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize); + if (mode->next == scrp->modes) + break; + } + + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + + if (scrp->currentMode->HDisplay != randrp->virtualX || + scrp->currentMode->VDisplay != randrp->virtualY) + { + mode = scrp->modes; + pSize = RRRegisterSize (pScreen, + randrp->virtualX, randrp->virtualY, + randrp->mmWidth, + randrp->mmHeight); + if (!pSize) + return FALSE; + RRRegisterRate (pScreen, pSize, refresh0); + if (scrp->virtualX == randrp->virtualX && + scrp->virtualY == randrp->virtualY) + { + RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize); + } + } + + return TRUE; +} + +static Bool +I830RandRSetMode (ScreenPtr pScreen, + DisplayModePtr mode, + Bool useVirtual, + int mmWidth, + int mmHeight) +{ + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int oldWidth = pScreen->width; + int oldHeight = pScreen->height; + int oldmmWidth = pScreen->mmWidth; + int oldmmHeight = pScreen->mmHeight; + WindowPtr pRoot = WindowTable[pScreen->myNum]; + DisplayModePtr currentMode = NULL; + Bool ret = TRUE; + PixmapPtr pspix = NULL; + + if (pRoot) + (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE); + if (useVirtual) + { + scrp->virtualX = randrp->virtualX; + scrp->virtualY = randrp->virtualY; + } + else + { + scrp->virtualX = mode->HDisplay; + scrp->virtualY = mode->VDisplay; + } + if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270)) + { + /* If the screen is rotated 90 or 270 degrees, swap the sizes. */ + pScreen->width = scrp->virtualY; + pScreen->height = scrp->virtualX; + pScreen->mmWidth = mmHeight; + pScreen->mmHeight = mmWidth; + } + else + { + pScreen->width = scrp->virtualX; + pScreen->height = scrp->virtualY; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + } + if (scrp->currentMode == mode) { + /* Save current mode */ + currentMode = scrp->currentMode; + /* Reset, just so we ensure the drivers SwitchMode is called */ + scrp->currentMode = NULL; + } + /* + * We know that if the driver failed to SwitchMode to the rotated + * version, then it should revert back to it's prior mode. + */ + if (!xf86SwitchMode (pScreen, mode)) + { + ret = FALSE; + scrp->virtualX = pScreen->width = oldWidth; + scrp->virtualY = pScreen->height = oldHeight; + pScreen->mmWidth = oldmmWidth; + pScreen->mmHeight = oldmmHeight; + scrp->currentMode = currentMode; + } + /* + * Get the new Screen pixmap ptr as SwitchMode might have called + * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back... + * Unfortunately. + */ + pspix = (*pScreen->GetScreenPixmap) (pScreen); + if (pspix->devPrivate.ptr) + scrp->pixmapPrivate = pspix->devPrivate; + + /* + * Make sure the layout is correct + */ + xf86ReconfigureLayout(); + + /* + * Make sure the whole screen is visible + */ + xf86SetViewport (pScreen, pScreen->width, pScreen->height); + xf86SetViewport (pScreen, 0, 0); + if (pRoot) + (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE); + return ret; +} + +Bool +I830RandRSetConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize) +{ + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int px, py; + Bool useVirtual = FALSE; + int maxX = 0, maxY = 0; + Rotation oldRotation = randrp->rotation; + + randrp->rotation = rotation; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = scrp->virtualX; + randrp->virtualY = scrp->virtualY; + } + + miPointerPosition (&px, &py); + for (mode = scrp->modes; ; mode = mode->next) + { + if (randrp->maxX == 0 || randrp->maxY == 0) + { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode->HDisplay == pSize->width && + mode->VDisplay == pSize->height && + (rate == 0 || I830RandRModeRefresh (mode) == rate)) + break; + if (mode->next == scrp->modes) + { + if (pSize->width == randrp->virtualX && + pSize->height == randrp->virtualY) + { + mode = scrp->modes; + useVirtual = TRUE; + break; + } + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + return FALSE; + } + } + + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + + if (!I830RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) { + randrp->rotation = oldRotation; + return FALSE; + } + + /* + * Move the cursor back where it belongs; SwitchMode repositions it + */ + if (pScreen == miPointerCurrentScreen ()) + { + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + xf86SetViewport(pScreen, px, py); + + (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE); + } + + return TRUE; +} + +Rotation +I830GetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + return randrp->rotation; +} + +Bool +I830RandRInit (ScreenPtr pScreen, int rotation) +{ + rrScrPrivPtr rp; + XF86RandRInfoPtr randrp; + +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + return TRUE; +#endif + if (i830RandRGeneration != serverGeneration) + { + i830RandRIndex = AllocateScreenPrivateIndex(); + i830RandRGeneration = serverGeneration; + } + + randrp = xalloc (sizeof (XF86RandRInfoRec)); + if (!randrp) + return FALSE; + + if (!RRScreenInit(pScreen)) + { + xfree (randrp); + return FALSE; + } + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = I830RandRGetInfo; + rp->rrSetConfig = I830RandRSetConfig; + + randrp->virtualX = -1; + randrp->virtualY = -1; + randrp->mmWidth = pScreen->mmWidth; + randrp->mmHeight = pScreen->mmHeight; + + randrp->rotation = RR_Rotate_0; /* initial rotated mode */ + + randrp->supported_rotations = rotation; + + randrp->maxX = randrp->maxY = 0; + + pScreen->devPrivates[i830RandRIndex].ptr = randrp; + + return TRUE; +} diff --git a/src/i830_reg.h b/src/i830_reg.h new file mode 100644 index 00000000..be12e760 --- /dev/null +++ b/src/i830_reg.h @@ -0,0 +1,637 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + + +#ifndef _I830_REG_H_ +#define _I830_REG_H_ + +#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) +#define AA_LINE_ENABLE ((1<<1) | 1) +#define AA_LINE_DISABLE (1<<1) + +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) + +#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ + ((0x90+(stage))<<16)) + +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_IS_Z 0 +#define DEPTH_IS_W (1<<6) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 0 +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + + +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) +#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) +#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) +#define DISABLE_LOGIC_OP (1<<23) +#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_TEST (1<<21) +#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) +#define DISABLE_DEPTH_BIAS (1<<11) +#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) +#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) +#define DISABLE_SPEC_ADD (1<<9) +#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) +#define ENABLE_FOG ((1<<7)|(1<<6)) +#define DISABLE_FOG (1<<7) +#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) +#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) +#define DISABLE_ALPHA_TEST (1<<5) +#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) +#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) +#define DISABLE_COLOR_BLEND (1<<3) +#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) +#define ENABLE_DEPTH_TEST ((1<<1)|1) +#define DISABLE_DEPTH_TEST (1<<1) + +/* _3DSTATE_ENABLES_2, p138 */ +#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) +#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_WRITE (1<<21) +#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) +#define DISABLE_TEX_CACHE (1<<17) +#define ENABLE_DITHER ((1<<9)|(1<<8)) +#define DISABLE_DITHER (1<<9) +#define ENABLE_COLOR_MASK (1<<10) +#define WRITEMASK_ALPHA (1<<7) +#define WRITEMASK_ALPHA_SHIFT 7 +#define WRITEMASK_RED (1<<6) +#define WRITEMASK_RED_SHIFT 6 +#define WRITEMASK_GREEN (1<<5) +#define WRITEMASK_GREEN_SHIFT 5 +#define WRITEMASK_BLUE (1<<4) +#define WRITEMASK_BLUE_SHIFT 4 +#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) +#define DISABLE_COLOR_WRITE (1<<3) +#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 +#define ENABLE_DEPTH_WRITE ((1<<1)|1) +#define DISABLE_DEPTH_WRITE (1<<1) + +/* _3DSTATE_FOG_COLOR, p139 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p140 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FOGFUNC_ENABLE (1<<31) +#define FOGFUNC_VERTEX 0 +#define FOGFUNC_PIXEL_EXP (1<<28) +#define FOGFUNC_PIXEL_EXP2 (2<<28) +#define FOGFUNC_PIXEL_LINEAR (3<<28) +#define FOGSRC_INDEX_Z (1<<27) +#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) +#define FOG_LINEAR_CONST (1<<24) +#define FOG_CONST_1(x) ((x)<<4) +#define ENABLE_FOG_DENSITY (1<<23) +/* Dword 2 */ +#define FOG_CONST_2(x) (x) +/* Dword 3 */ +#define FOG_DENSITY(x) (x) + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ +#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) +#define DISABLE_INDPT_ALPHA_BLEND (1<<23) +#define ALPHA_BLENDFUNC_MASK 0x3f0000 +#define ENABLE_ALPHA_BLENDFUNC (1<<21) +#define ABLENDFUNC_ADD 0 +#define ABLENDFUNC_SUB (1<<16) +#define ABLENDFUNC_RVSE_SUB (2<<16) +#define ABLENDFUNC_MIN (3<<16) +#define ABLENDFUNC_MAX (4<<16) +#define SRC_DST_ABLEND_MASK 0xfff +#define ENABLE_SRC_ABLEND_FACTOR (1<<11) +#define SRC_ABLEND_FACT(x) ((x)<<6) +#define ENABLE_DST_ABLEND_FACTOR (1<<5) +#define DST_ABLEND_FACT(x) (x) + + +/* _3DSTATE_MAP_BLEND_ARG, p152 */ +#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) + +#define TEXPIPE_COLOR 0 +#define TEXPIPE_ALPHA (1<<18) +#define TEXPIPE_KILL (2<<18) +#define TEXBLEND_ARG0 0 +#define TEXBLEND_ARG1 (1<<15) +#define TEXBLEND_ARG2 (2<<15) +#define TEXBLEND_ARG3 (3<<15) +#define TEXBLENDARG_MODIFY_PARMS (1<<6) +#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) +#define TEXBLENDARG_INV_ARG (1<<4) +#define TEXBLENDARG_ONE 0 +#define TEXBLENDARG_FACTOR 0x01 +#define TEXBLENDARG_ACCUM 0x02 +#define TEXBLENDARG_DIFFUSE 0x03 +#define TEXBLENDARG_SPEC 0x04 +#define TEXBLENDARG_CURRENT 0x05 +#define TEXBLENDARG_TEXEL0 0x06 +#define TEXBLENDARG_TEXEL1 0x07 +#define TEXBLENDARG_TEXEL2 0x08 +#define TEXBLENDARG_TEXEL3 0x09 +#define TEXBLENDARG_FACTOR_N 0x0e + +/* _3DSTATE_MAP_BLEND_OP, p155 */ +#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) +#if 0 +# define TEXPIPE_COLOR 0 +# define TEXPIPE_ALPHA (1<<18) +# define TEXPIPE_KILL (2<<18) +#endif +#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) +#define TEXOP_OUTPUT_CURRENT 0 +#define TEXOP_OUTPUT_ACCUM (1<<15) +#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) +#define DISABLE_TEX_CNTRL_STAGE (1<<12) +#define TEXOP_SCALE_SHIFT 9 +#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) +#define TEXOP_MODIFY_PARMS (1<<8) +#define TEXOP_LAST_STAGE (1<<7) +#define TEXBLENDOP_KILLPIXEL 0x02 +#define TEXBLENDOP_ARG1 0x01 +#define TEXBLENDOP_ARG2 0x02 +#define TEXBLENDOP_MODULATE 0x03 +#define TEXBLENDOP_ADD 0x06 +#define TEXBLENDOP_ADDSIGNED 0x07 +#define TEXBLENDOP_BLEND 0x08 +#define TEXBLENDOP_BLEND_AND_ADD 0x09 +#define TEXBLENDOP_SUBTRACT 0x0a +#define TEXBLENDOP_DOT3 0x0b +#define TEXBLENDOP_DOT4 0x0c +#define TEXBLENDOP_MODULATE_AND_ADD 0x0d +#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e +#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f + +/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ +/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ + +#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) +#define DISABLE_TEX_TRANSFORM (1<<28) +#define TEXTURE_SET(x) (x<<29) + +#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) + + +/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ +#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) +#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) +#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) +#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) + +#define TEXBIND_SET3(x) ((x)<<12) +#define TEXBIND_SET2(x) ((x)<<8) +#define TEXBIND_SET1(x) ((x)<<4) +#define TEXBIND_SET0(x) (x) + +#define TEXCOORDSRC_KEEP 0 +#define TEXCOORDSRC_DEFAULT 0x01 +#define TEXCOORDSRC_VTXSET_0 0x08 +#define TEXCOORDSRC_VTXSET_1 0x09 +#define TEXCOORDSRC_VTXSET_2 0x0a +#define TEXCOORDSRC_VTXSET_3 0x0b +#define TEXCOORDSRC_VTXSET_4 0x0c +#define TEXCOORDSRC_VTXSET_5 0x0d +#define TEXCOORDSRC_VTXSET_6 0x0e +#define TEXCOORDSRC_VTXSET_7 0x0f + +#define MAP_UNIT(unit) ((unit)<<16) +#define MAP_UNIT_MASK (0x7<<16) + +/* _3DSTATE_MAP_COORD_SETS, p164 */ +#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) +#define ENABLE_TEXCOORD_PARAMS (1<<15) +#define TEXCOORDS_ARE_NORMAL (1<<14) +#define TEXCOORDS_ARE_IN_TEXELUNITS 0 +#define TEXCOORDTYPE_CARTESIAN 0 +#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) +#define TEXCOORDTYPE_VECTOR (2<<11) +#define TEXCOORDTYPE_MASK (0x7<<11) +#define ENABLE_ADDR_V_CNTL (1<<7) +#define ENABLE_ADDR_U_CNTL (1<<3) +#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) +#define TEXCOORD_ADDR_U_MODE(x) (x) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP 2 +#define TEXCOORDMODE_WRAP_SHORTEST 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORD_ADDR_V_MASK 0x70 +#define TEXCOORD_ADDR_U_MASK 0x7 + +/* _3DSTATE_MAP_CUBE, p168 TODO */ +#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) +#define CUBE_NEGX_ENABLE (1<<5) +#define CUBE_POSX_ENABLE (1<<4) +#define CUBE_NEGY_ENABLE (1<<3) +#define CUBE_POSY_ENABLE (1<<2) +#define CUBE_NEGZ_ENABLE (1<<1) +#define CUBE_POSZ_ENABLE (1<<0) + + +/* _3DSTATE_MODES_1, p190 */ +#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) +#define BLENDFUNC_MASK 0x3f0000 +#define ENABLE_COLR_BLND_FUNC (1<<21) +#define BLENDFUNC_ADD 0 +#define BLENDFUNC_SUB (1<<16) +#define BLENDFUNC_RVRSE_SUB (2<<16) +#define BLENDFUNC_MIN (3<<16) +#define BLENDFUNC_MAX (4<<16) +#define SRC_DST_BLND_MASK 0xfff +#define ENABLE_SRC_BLND_FACTOR (1<<11) +#define ENABLE_DST_BLND_FACTOR (1<<5) +#define SRC_BLND_FACT(x) ((x)<<6) +#define DST_BLND_FACT(x) (x) + + +/* _3DSTATE_MODES_2, p192 */ +#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) +#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) +#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) +#define ENABLE_ALPHA_TEST_FUNC (1<<13) +#define ENABLE_ALPHA_REF_VALUE (1<<8) +#define ALPHA_TEST_FUNC(x) ((x)<<9) +#define ALPHA_REF_VALUE(x) (x) + +#define ALPHA_TEST_REF_MASK 0x3fff + +/* _3DSTATE_MODES_3, p193 */ +#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) +#define DEPTH_TEST_FUNC_MASK 0x1f0000 +#define ENABLE_DEPTH_TEST_FUNC (1<<20) +/* Uses COMPAREFUNC */ +#define DEPTH_TEST_FUNC(x) ((x)<<16) +#define ENABLE_ALPHA_SHADE_MODE (1<<11) +#define ENABLE_FOG_SHADE_MODE (1<<9) +#define ENABLE_SPEC_SHADE_MODE (1<<7) +#define ENABLE_COLOR_SHADE_MODE (1<<5) +#define ALPHA_SHADE_MODE(x) ((x)<<10) +#define FOG_SHADE_MODE(x) ((x)<<8) +#define SPEC_SHADE_MODE(x) ((x)<<6) +#define COLOR_SHADE_MODE(x) ((x)<<4) +#define CULLMODE_MASK 0xf +#define ENABLE_CULL_MODE (1<<3) +#define CULLMODE_BOTH 0 +#define CULLMODE_NONE 1 +#define CULLMODE_CW 2 +#define CULLMODE_CCW 3 + +#define SHADE_MODE_LINEAR 0 +#define SHADE_MODE_FLAT 0x1 + +/* _3DSTATE_MODES_4, p195 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) ((x)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p196 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define ENABLE_SPRITE_POINT_TEX (1<<23) +#define SPRITE_POINT_TEX_ON (1<<22) +#define SPRITE_POINT_TEX_OFF 0 +#define FLUSH_RENDER_CACHE (1<<18) +#define FLUSH_TEXTURE_CACHE (1<<16) +#define FIXED_LINE_WIDTH_MASK 0xfc00 +#define ENABLE_FIXED_LINE_WIDTH (1<<15) +#define FIXED_LINE_WIDTH(x) ((x)<<10) +#define FIXED_POINT_WIDTH_MASK 0x3ff +#define ENABLE_FIXED_POINT_WIDTH (1<<9) +#define FIXED_POINT_WIDTH(x) (x) + +/* _3DSTATE_RASTERIZATION_RULES, p198 */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) +#define TRI_STRIP_PROVOKE_VRTX(x) (x) + +/* _3DSTATE_SCISSOR_ENABLE, p200 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* _3DSTATE_STENCIL_TEST, p202 */ +#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) +#define ENABLE_STENCIL_PARMS (1<<23) +#define STENCIL_OPS_MASK (0xffc000) +#define STENCIL_FAIL_OP(x) ((x)<<20) +#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) +#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) + +#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) +#define ENABLE_STENCIL_TEST_FUNC (1<<13) +/* Uses COMPAREFUNC */ +#define STENCIL_TEST_FUNC(x) ((x)<<9) +#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) +#define ENABLE_STENCIL_REF_VALUE (1<<8) +#define STENCIL_REF_VALUE(x) (x) + +/* _3DSTATE_VERTEX_FORMAT, p204 */ +#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) +#define VFT0_POINT_WIDTH (1<<12) +#define VFT0_TEX_COUNT_MASK (7<<8) +#define VFT0_TEX_COUNT_SHIFT 8 +#define VFT0_TEX_COUNT(x) ((x)<<8) +#define VFT0_SPEC (1<<7) +#define VFT0_DIFFUSE (1<<6) +#define VFT0_DEPTH_OFFSET (1<<5) +#define VFT0_XYZ (1<<1) +#define VFT0_XYZW (2<<1) +#define VFT0_XY (3<<1) +#define VFT0_XYW (4<<1) +#define VFT0_XYZW_MASK (7<<1) + +/* _3DSTATE_VERTEX_FORMAT_2, p206 */ +#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24)) +#define VFT1_TEX7_FMT(x) ((x)<<14) +#define VFT1_TEX6_FMT(x) ((x)<<12) +#define VFT1_TEX5_FMT(x) ((x)<<10) +#define VFT1_TEX4_FMT(x) ((x)<<8) +#define VFT1_TEX3_FMT(x) ((x)<<6) +#define VFT1_TEX2_FMT(x) ((x)<<4) +#define VFT1_TEX1_FMT(x) ((x)<<2) +#define VFT1_TEX0_FMT(x) (x) +#define VFT1_TEX0_MASK 3 +#define VFT1_TEX1_SHIFT 2 +#define TEXCOORDFMT_2D 0 +#define TEXCOORDFMT_3D 1 +#define TEXCOORDFMT_4D 2 +#define TEXCOORDFMT_1D 3 + +/*New stuff picked up along the way */ + +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + + +/* _3DSTATE_VERTEX_TRANSFORM, p207 */ +#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) +#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) +/* Dword 1 */ +#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) +#define DISABLE_PERSP_DIVIDE (1<<29) +#define VRTX_TRANS_LOAD_MATRICES 0x7421 +#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 +/* Dword 2 -> 7 are matrix elements */ + +/* _3DSTATE_W_STATE, p209 */ +#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) +/* Dword 1 */ +#define MAGIC_W_STATE_DWORD1 0x00000008 +/* Dword 2 */ +#define WFAR_VALUE(x) (x) + + +/* Stipple command, carried over from the i810, apparently: + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + + +#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) +#define LOAD_GLOBAL_COLOR_FACTOR (1<<6) + +#define TM0S0_ADDRESS_MASK 0xfffffffc +#define TM0S0_USE_FENCE (1<<1) + +#define TM0S1_HEIGHT_SHIFT 21 +#define TM0S1_WIDTH_SHIFT 10 +#define TM0S1_PALETTE_SELECT (1<<9) +#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) +#define TM0S1_MAPSURF_FORMAT_SHIFT 6 +#define MAPSURF_8BIT_INDEXED (0<<6) +#define MAPSURF_8BIT (1<<6) +#define MAPSURF_16BIT (2<<6) +#define MAPSURF_32BIT (3<<6) +#define MAPSURF_411 (4<<6) +#define MAPSURF_422 (5<<6) +#define MAPSURF_COMPRESSED (6<<6) +#define MAPSURF_4BIT_INDEXED (7<<6) +#define TM0S1_MT_FORMAT_MASK (0x7 << 3) +#define TM0S1_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ +#define MT_8BIT_IDX_ARGB1555 (1<<3) +#define MT_8BIT_IDX_ARGB4444 (2<<3) +#define MT_8BIT_IDX_AY88 (3<<3) +#define MT_8BIT_IDX_ABGR8888 (4<<3) +#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) +#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) +#define MT_8BIT_IDX_ARGB8888 (7<<3) +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) +#define MT_16BIT_BUMP_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_DIB_RGB565_8888 (7<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) +#define MT_32BIT_DIB_8888 (7<<3) +#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define TM0S1_COLORSPACE_CONVERSION (1 << 2) +#define TM0S1_TILED_SURFACE (1 << 1) +#define TM0S1_TILE_WALK (1 << 0) + +#define TM0S2_PITCH_SHIFT 21 +#define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) +#define TM0S2_MAP_FORMAT (1<<14) +#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) +#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) +#define TM0S2_OUTPUT_CHAN_SHIFT 10 +#define TM0S2_OUTPUT_CHAN_MASK (3<<10) + +#define TM0S3_MIP_FILTER_MASK (0x3<<30) +#define TM0S3_MIP_FILTER_SHIFT 30 +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define TM0S3_MAG_FILTER_MASK (0x3<<28) +#define TM0S3_MAG_FILTER_SHIFT 28 +#define TM0S3_MIN_FILTER_MASK (0x3<<26) +#define TM0S3_MIN_FILTER_SHIFT 26 +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 + +#define TM0S3_LOD_BIAS_SHIFT 17 +#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) +#define TM0S3_MAX_MIP_SHIFT 9 +#define TM0S3_MAX_MIP_MASK (0xff<<9) +#define TM0S3_MIN_MIP_SHIFT 3 +#define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_KILL_PIXEL (1<<2) +#define TM0S3_KEYED_FILTER (1<<1) +#define TM0S3_CHROMA_KEY (1<<0) + + +/* _3DSTATE_MAP_TEXEL_STREAM, p188 */ +#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) +#define DISABLE_TEX_STREAM_BUMP (1<<12) +#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) +#define TEX_MODIFY_UNIT_0 0 +#define TEX_MODIFY_UNIT_1 (1<<8) +#define ENABLE_TEX_STREAM_COORD_SET (1<<7) +#define TEX_STREAM_COORD_SET(x) ((x)<<4) +#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) +#define TEX_STREAM_MAP_IDX(x) (x) + + +#define FLUSH_MAP_CACHE (1<<0) + +#endif diff --git a/src/i830_rotate.c b/src/i830_rotate.c new file mode 100644 index 00000000..5d290596 --- /dev/null +++ b/src/i830_rotate.c @@ -0,0 +1,1239 @@ +/* -*- c-basic-offset: 3 -*- */ +/************************************************************************** + +Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. + +All Rights Reserved. + +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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. + +**************************************************************************/ + +/* + * Reformatted with GNU indent (2.2.8), using the following options: + * + * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78 + * -lp -npcs -psl -sob -ss -br -ce -sc -hnl + * + * This provides a good match with the original i810 code and preferred + * XFree86 formatting conventions. + * + * When editing this driver, please follow the existing formatting, and edit + * with <TAB> characters expanded at 8-column intervals. + */ + +/* + * Authors: + * Alan Hourihane <alanh@tungstengraphics.com> + * Brian Paul <brian.paul@tungstengraphics.com> + * Keith Whitwell <keith@tungstengraphics.com> + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "servermd.h" +#include "shadow.h" + +#include "i830.h" +#include "i915_reg.h" +#include "i915_3d.h" + +#ifdef XF86DRI +#include "dri.h" +#endif + +static void * +I830WindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + CARD8 *ptr; + + *size = (pScrn->bitsPerPixel * pI830->displayWidth >> 3); + if (I830IsPrimary(pScrn)) + ptr = (CARD8 *) (pI830->FbBase + pI830->FrontBuffer.Start) + row * (*size) + offset; + else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + ptr = (CARD8 *) (pI830->FbBase + pI8301->FrontBuffer2.Start) + row * (*size) + offset; + } + return (void *)ptr; +} + +struct matrix23 +{ + int m00, m01, m02; + int m10, m11, m12; +}; + +static void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, + int m10, int m11, int m12) +{ + m->m00 = m00; m->m01 = m01; m->m02 = m02; + m->m10 = m10; m->m11 = m11; m->m12 = m12; +} + + +/* + * Transform (x,y) coordinate by the given matrix. + */ +static void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y) +{ + const float x0 = *x; + const float y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + +/* + * Make rotation matrix for width X height screen. + */ +static void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle) +{ + switch (angle) { + case 0: + matrix23Set(m, 1, 0, 0, 0, 1, 0); + break; + case 90: + matrix23Set(m, 0, 1, 0, -1, 0, width); + break; + case 180: + matrix23Set(m, -1, 0, width, 0, -1, height); + break; + case 270: + matrix23Set(m, 0, -1, height, 1, 0, 0); + break; + default: + break; + } +} + +/* Doesn't matter on the order for our purposes */ +typedef struct { + unsigned char red, green, blue, alpha; +} intel_color_t; + +/* Vertex format */ +typedef union { + struct { + float x, y, z, w; + intel_color_t color; + intel_color_t specular; + float u0, v0; + float u1, v1; + float u2, v2; + float u3, v3; + } v; + float f[24]; + unsigned int ui[24]; + unsigned char ub4[24][4]; +} intelVertex, *intelVertexPtr; + +static void draw_poly(CARD32 *vb, + float verts[][2], + float texcoords[][2]) +{ + int vertex_size = 8; + intelVertex tmp; + int i, k; + + /* initial constant vertex fields */ + tmp.v.z = 1.0; + tmp.v.w = 1.0; + tmp.v.color.red = 255; + tmp.v.color.green = 255; + tmp.v.color.blue = 255; + tmp.v.color.alpha = 255; + tmp.v.specular.red = 0; + tmp.v.specular.green = 0; + tmp.v.specular.blue = 0; + tmp.v.specular.alpha = 0; + + for (k = 0; k < 4; k++) { + tmp.v.x = verts[k][0]; + tmp.v.y = verts[k][1]; + tmp.v.u0 = texcoords[k][0]; + tmp.v.v0 = texcoords[k][1]; + + for (i = 0 ; i < vertex_size ; i++) + vb[i] = tmp.ui[i]; + + vb += vertex_size; + } +} + +static void +I915UpdateRotate (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + ScrnInfoPtr pScrn1 = pScrn; + I830Ptr pI8301 = NULL; + RegionPtr damage = shadowDamage(pBuf); + int nbox = REGION_NUM_RECTS (damage); + BoxPtr pbox = REGION_RECTS (damage); + int box_x1, box_x2, box_y1, box_y2; + CARD32 vb[32]; /* 32 dword vertex buffer */ + float verts[4][2], tex[4][2]; + struct matrix23 rotMatrix; + int j; + int use_fence; + Bool updateInvarient = FALSE; +#ifdef XF86DRI + drmI830Sarea *sarea = NULL; + drm_context_t myContext = 0; +#endif + Bool didLock = FALSE; + + if (I830IsPrimary(pScrn)) { + pI8301 = pI830; + } else { + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pScrn1 = pI830->entityPrivate->pScrn_1; + } + + switch (pI830->rotation) { + case RR_Rotate_90: + matrix23Rotate(&rotMatrix, + pScreen->width, pScreen->height, + 90); + break; + case RR_Rotate_180: + matrix23Rotate(&rotMatrix, + pScreen->width, pScreen->height, + 180); + break; + case RR_Rotate_270: + matrix23Rotate(&rotMatrix, + pScreen->width, pScreen->height, + 270); + break; + default: + break; + } + +#ifdef XF86DRI + if (pI8301->directRenderingEnabled) { + sarea = DRIGetSAREAPrivate(pScrn1->pScreen); + myContext = DRIGetContext(pScrn1->pScreen); + didLock = I830DRILock(pScrn1); + } +#endif + + if (pScrn->scrnIndex != *pI830->used3D) + updateInvarient = TRUE; + +#ifdef XF86DRI + if (sarea && sarea->ctxOwner != myContext) + updateInvarient = TRUE; +#endif + + if (updateInvarient) { + FS_LOCALS(3); + *pI830->used3D = pScrn->scrnIndex; +#ifdef XF86DRI + if (sarea) + sarea->ctxOwner = myContext; +#endif + BEGIN_LP_RING(54); + /* invarient state */ + OUT_RING(MI_NOOP); + OUT_RING(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); + + OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_RING(0x00000000); + + OUT_RING(_3DSTATE_DFLT_SPEC_CMD); + OUT_RING(0x00000000); + + OUT_RING(_3DSTATE_DFLT_Z_CMD); + OUT_RING(0x00000000); + + OUT_RING(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | CSB_TCB(1, 1) | + CSB_TCB(2, 2) | CSB_TCB(3, 3) | + CSB_TCB(4, 4) | CSB_TCB(5, 5) | + CSB_TCB(6, 6) | CSB_TCB(7, 7)); + + OUT_RING(_3DSTATE_RASTER_RULES_CMD | + ENABLE_TRI_FAN_PROVOKE_VRTX | TRI_FAN_PROVOKE_VRTX(2) | + ENABLE_LINE_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) | + ENABLE_TEXKILL_3D_4D | TEXKILL_4D | + ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE); + + OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 1); + OUT_RING(0x00000000); + + /* flush map & render cache */ + OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); + OUT_RING(0x00000000); + + /* draw rect */ + OUT_RING(_3DSTATE_DRAW_RECT_CMD); + OUT_RING(DRAW_DITHER_OFS_X(0) | DRAW_DITHER_OFS_Y(0)); + OUT_RING(DRAW_XMIN(0) | DRAW_YMIN(0)); + OUT_RING(DRAW_XMAX(pScrn->virtualX - 1) | + DRAW_YMAX(pScrn->virtualY - 1)); + OUT_RING(DRAW_XORG(0) | DRAW_YORG(0)); + + OUT_RING(MI_NOOP); + + OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_RING(0x00000000); /* ymin, xmin */ + OUT_RING(0x00000000); /* ymax, xmax */ + + OUT_RING(0x7c000003); /* XXX: magic numbers */ + OUT_RING(0x7d070000); + OUT_RING(0x00000000); + OUT_RING(0x68000002); + + /* context setup */ + OUT_RING(_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | + MODE4_ENABLE_STENCIL_WRITE_MASK | + MODE4_ENABLE_STENCIL_TEST_MASK); + + OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 4); + + OUT_RING(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | + S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); + OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE | + S4_CULLMODE_NONE | S4_VFMT_SPEC_FOG | S4_VFMT_COLOR | + S4_VFMT_XYZW); + OUT_RING(0x00000000); /* S5 -- enable bits */ + OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) | + (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) | + (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE | + (2 << S6_TRISTRIP_PV_SHIFT)); + + OUT_RING(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + IAB_MODIFY_ENABLE | + IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | + IAB_MODIFY_SRC_FACTOR | + (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) | + IAB_MODIFY_DST_FACTOR | + (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT)); + + OUT_RING(_3DSTATE_CONST_BLEND_COLOR_CMD); + OUT_RING(0x00000000); + + OUT_RING(_3DSTATE_DST_BUF_VARS_CMD); + if (pI830->cpp == 1) { + OUT_RING(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) | + DSTORG_VERT_BIAS(0x8) | COLR_BUF_8BIT); + } else if (pI830->cpp == 2) { + OUT_RING(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) | + DSTORG_VERT_BIAS(0x8) | COLR_BUF_RGB565); + } else { + OUT_RING(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) | + DSTORG_VERT_BIAS(0x8) | COLR_BUF_ARGB8888 | + DEPTH_FRMT_24_FIXED_8_OTHER); + } + + OUT_RING(_3DSTATE_STIPPLE); + OUT_RING(0x00000000); + + /* texture sampler state */ + OUT_RING(_3DSTATE_SAMPLER_STATE | 3); + OUT_RING(0x00000001); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + + /* front buffer, pitch, offset */ + OUT_RING(_3DSTATE_BUF_INFO_CMD); + OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE | + BUF_3D_PITCH(pI830->displayWidth * pI830->cpp)); + if (I830IsPrimary(pScrn)) + OUT_RING(pI830->FrontBuffer.Start); + else + OUT_RING(pI8301->FrontBuffer2.Start); + + /* Set the entire frontbuffer up as a texture */ + OUT_RING(_3DSTATE_MAP_STATE | 3); + OUT_RING(0x00000001); + + if (I830IsPrimary(pScrn)) + OUT_RING(pI830->RotatedMem.Start); + else + OUT_RING(pI8301->RotatedMem2.Start); + + if (pI830->disableTiling) + use_fence = 0; + else + use_fence = 4; + + if (pI830->cpp == 1) + use_fence |= MAPSURF_8BIT; + else + if (pI830->cpp == 2) + use_fence |= MAPSURF_16BIT; + else + use_fence |= MAPSURF_32BIT; + OUT_RING(use_fence | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10); + OUT_RING(((((pScrn->displayWidth * pI830->cpp) / 4) - 1) << 21)); + ADVANCE_LP_RING(); + + /* fragment program - texture blend replace*/ + FS_BEGIN(); + i915_fs_dcl(FS_S0); + i915_fs_dcl(FS_T0); + i915_fs_texld(FS_OC, FS_S0, FS_T0); + FS_END(); + } + + { + BEGIN_LP_RING(2); + OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); + OUT_RING(0x00000000); + ADVANCE_LP_RING(); + } + + while (nbox--) + { + box_x1 = pbox->x1; + box_y1 = pbox->y1; + box_x2 = pbox->x2; + box_y2 = pbox->y2; + pbox++; + + BEGIN_LP_RING(40); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + + /* vertex data */ + OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (32 - 1)); + verts[0][0] = box_x1; verts[0][1] = box_y1; + verts[1][0] = box_x2; verts[1][1] = box_y1; + verts[2][0] = box_x2; verts[2][1] = box_y2; + verts[3][0] = box_x1; verts[3][1] = box_y2; + tex[0][0] = box_x1; tex[0][1] = box_y1; + tex[1][0] = box_x2; tex[1][1] = box_y1; + tex[2][0] = box_x2; tex[2][1] = box_y2; + tex[3][0] = box_x1; tex[3][1] = box_y2; + + /* transform coordinates to rotated versions, but leave texcoords unchanged */ + for (j = 0; j < 4; j++) + matrix23TransformCoordf(&rotMatrix, &verts[j][0], &verts[j][1]); + + /* emit vertex buffer */ + draw_poly(vb, verts, tex); + for (j = 0; j < 32; j++) + OUT_RING(vb[j]); + + ADVANCE_LP_RING(); + } + +#ifdef XF86DRI + if (didLock) + I830DRIUnlock(pScrn1); +#endif +} + +static void +I830UpdateRotate (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI8301 = NULL; + ScrnInfoPtr pScrn1 = pScrn; + RegionPtr damage = shadowDamage(pBuf); + int nbox = REGION_NUM_RECTS (damage); + BoxPtr pbox = REGION_RECTS (damage); + int box_x1, box_x2, box_y1, box_y2; + CARD32 vb[32]; /* 32 dword vertex buffer */ + float verts[4][2], tex[4][2]; + struct matrix23 rotMatrix; + Bool updateInvarient = FALSE; + int use_fence; + int j; +#ifdef XF86DRI + drmI830Sarea *sarea = NULL; + drm_context_t myContext = 0; +#endif + Bool didLock = FALSE; + + if (I830IsPrimary(pScrn)) { + pI8301 = pI830; + } else { + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pScrn1 = pI830->entityPrivate->pScrn_1; + } + + switch (pI830->rotation) { + case RR_Rotate_90: + matrix23Rotate(&rotMatrix, + pScreen->width, pScreen->height, + 90); + break; + case RR_Rotate_180: + matrix23Rotate(&rotMatrix, + pScreen->width, pScreen->height, + 180); + break; + case RR_Rotate_270: + matrix23Rotate(&rotMatrix, + pScreen->width, pScreen->height, + 270); + break; + default: + break; + } + +#ifdef XF86DRI + if (pI8301->directRenderingEnabled) { + sarea = DRIGetSAREAPrivate(pScrn1->pScreen); + myContext = DRIGetContext(pScrn1->pScreen); + didLock = I830DRILock(pScrn1); + } +#endif + + if (pScrn->scrnIndex != *pI830->used3D) + updateInvarient = TRUE; + +#ifdef XF86DRI + if (sarea && sarea->ctxOwner != myContext) + updateInvarient = TRUE; +#endif + + if (updateInvarient) { + *pI830->used3D = pScrn->scrnIndex; +#ifdef XF86DRI + if (sarea) + sarea->ctxOwner = myContext; +#endif + + BEGIN_LP_RING(48); + OUT_RING(0x682008a1); + OUT_RING(0x6f402100); + OUT_RING(0x62120aa9); + OUT_RING(0x76b3ffff); + OUT_RING(0x6c818a01); + OUT_RING(0x6ba008a1); + OUT_RING(0x69802100); + OUT_RING(0x63a00aaa); + OUT_RING(0x6423070e); + OUT_RING(0x66014142); + OUT_RING(0x75000000); + OUT_RING(0x7d880000); + OUT_RING(0x00000000); + OUT_RING(0x650001c4); + OUT_RING(0x6a000000); + OUT_RING(0x7d020000); + OUT_RING(0x0000ba98); + + /* flush map & render cache */ + OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); + OUT_RING(0x00000000); + /* draw rect */ + OUT_RING(0x7d800003); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + OUT_RING((pScrn->virtualX - 1) | (pScrn->virtualY - 1) << 16); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + + /* front buffer */ + OUT_RING(0x7d8e0001); + OUT_RING(0x03800000 | (((pI830->displayWidth * pI830->cpp) / 4) << 2)); + if (I830IsPrimary(pScrn)) + OUT_RING(pI830->FrontBuffer.Start); + else + OUT_RING(pI8301->FrontBuffer2.Start); + OUT_RING(0x7d850000); + if (pI830->cpp == 1) + OUT_RING(0x00880000); + else + if (pI830->cpp == 2) + OUT_RING(0x00880200); + else + OUT_RING(0x00880308); + /* scissor */ + OUT_RING(0x7c800002); + OUT_RING(0x7d810001); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + /* stipple */ + OUT_RING(0x7d830000); + OUT_RING(0x00000000); + + /* texture blend replace */ + OUT_RING(0x7c088088); + OUT_RING(0x00000000); + OUT_RING(0x6d021181); + OUT_RING(0x6d060101); + OUT_RING(0x6e008046); + OUT_RING(0x6e048046); + + + /* Set the entire frontbuffer up as a texture */ + OUT_RING(0x7d030804); + + if (pI830->disableTiling) + use_fence = 0; + else + use_fence = 2; + + if (I830IsPrimary(pScrn)) + OUT_RING(pI830->RotatedMem.Start | use_fence); + else + OUT_RING(pI8301->RotatedMem2.Start | use_fence); + + if (pI830->cpp == 1) + OUT_RING(0x40 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10); + else if (pI830->cpp == 2) + OUT_RING(0x80 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10); + else + OUT_RING(0xc0 | (pScreen->height - 1) << 21 | (pScreen->width - 1) << 10); + + OUT_RING((((pScrn->displayWidth * pI830->cpp / 4) - 1) << 21)); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + + + ADVANCE_LP_RING(); + } + + { + BEGIN_LP_RING(2); + /* flush map & render cache */ + OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); + OUT_RING(0x00000000); + ADVANCE_LP_RING(); + } + + while (nbox--) + { + box_x1 = pbox->x1; + box_y1 = pbox->y1; + box_x2 = pbox->x2; + box_y2 = pbox->y2; + pbox++; + + BEGIN_LP_RING(40); + + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); + + /* vertex data */ + OUT_RING(0x7f0c001f); + verts[0][0] = box_x1; verts[0][1] = box_y1; + verts[1][0] = box_x2; verts[1][1] = box_y1; + verts[2][0] = box_x2; verts[2][1] = box_y2; + verts[3][0] = box_x1; verts[3][1] = box_y2; + tex[0][0] = box_x1; tex[0][1] = box_y1; + tex[1][0] = box_x2; tex[1][1] = box_y1; + tex[2][0] = box_x2; tex[2][1] = box_y2; + tex[3][0] = box_x1; tex[3][1] = box_y2; + + /* transform coordinates to rotated versions, but leave texcoords unchanged */ + for (j = 0; j < 4; j++) + matrix23TransformCoordf(&rotMatrix, &verts[j][0], &verts[j][1]); + + /* emit vertex buffer */ + draw_poly(vb, verts, tex); + for (j = 0; j < 32; j++) + OUT_RING(vb[j]); + + OUT_RING(0x05000000); + OUT_RING(0x00000000); + + ADVANCE_LP_RING(); + } + + { + BEGIN_LP_RING(2); + /* flush map & render cache */ + OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); + OUT_RING(0x00000000); + ADVANCE_LP_RING(); + } + +#ifdef XF86DRI + if (didLock) + I830DRIUnlock(pScrn1); +#endif +} + +Bool +I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI8301 = NULL; + I830Ptr pI8302 = NULL; + ScrnInfoPtr pScrn1 = NULL; + ScrnInfoPtr pScrn2 = NULL; + int i; + ShadowUpdateProc func = NULL; + Rotation oldRotation = pI830->rotation; /* save old state */ + int displayWidth = pScrn->displayWidth; /* save displayWidth */ + Bool reAllocate = TRUE; + Bool didLock = FALSE; + + /* Good pitches to allow tiling. Don't care about pitches < 1024. */ + static const int pitches[] = { +/* + 128 * 2, + 128 * 4, +*/ + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 + }; + + if (pI830->noAccel) + func = LoaderSymbol("shadowUpdateRotatePacked"); + else + if (IS_I9XX(pI830)) + func = I915UpdateRotate; + else + func = I830UpdateRotate; + + if (I830IsPrimary(pScrn)) { + pI8301 = pI830; + pScrn1 = pScrn; + if (pI830->entityPrivate) { + pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); + pScrn2 = pI830->entityPrivate->pScrn_2; + } + } else { + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pScrn1 = pI830->entityPrivate->pScrn_1; + pI8302 = pI830; + pScrn2 = pScrn; + } + + pI830->rotation = I830GetRotation(pScrn->pScreen); + + /* Check if we've still got the same orientation, or same mode */ + if (pI830->rotation == oldRotation && pI830->currentMode == mode) +#if 0 + reAllocate = FALSE; +#else + return TRUE; +#endif + + /* + * We grab the DRI lock when reallocating buffers to avoid DRI clients + * getting bogus information. + */ +#ifdef XF86DRI + if (pI8301->directRenderingEnabled && reAllocate) { + didLock = I830DRILock(pScrn1); + +#ifdef NO_TTM + /* Do heap teardown here + */ + { + drmI830MemDestroyHeap destroy; + destroy.region = I830_MEM_REGION_AGP; + + if (drmCommandWrite(pI8301->drmSubFD, + DRM_I830_DESTROY_HEAP, + &destroy, sizeof(destroy))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[dri] I830 destroy heap failed\n"); + } + } +#endif + + if (pI8301->TexMem.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key); + I830FreeVidMem(pScrn1, &(pI8301->TexMem)); + if (pI8301->StolenPool.Allocated.Key != -1) { + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key); + xf86DeallocateGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key); + } + if (pI8301->DepthBuffer.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key); + I830FreeVidMem(pScrn1, &(pI8301->DepthBuffer)); + if (pI8301->BackBuffer.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key); + I830FreeVidMem(pScrn1, &(pI8301->BackBuffer)); + } +#endif + + if (reAllocate) { + *pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */ + + if (pI8301->RotatedMem.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key); + + I830FreeVidMem(pScrn1, &(pI8301->RotatedMem)); + memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem)); + pI8301->RotatedMem.Key = -1; + + if (pI830->entityPrivate) { + if (pI8301->RotatedMem2.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key); + + I830FreeVidMem(pScrn1, &(pI8301->RotatedMem2)); + memset(&(pI8301->RotatedMem2), 0, sizeof(pI8301->RotatedMem2)); + pI8301->RotatedMem2.Key = -1; + } + } + + switch (pI830->rotation) { + case RR_Rotate_0: + if (reAllocate) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen to 0 degrees\n"); + pScrn->displayWidth = pI830->displayWidth; + break; + case RR_Rotate_90: + if (reAllocate) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen to 90 degrees\n"); + pScrn->displayWidth = pScrn->pScreen->width; + break; + case RR_Rotate_180: + if (reAllocate) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen to 180 degrees\n"); + pScrn->displayWidth = pI830->displayWidth; + break; + case RR_Rotate_270: + if (reAllocate) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen to 270 degrees\n"); + pScrn->displayWidth = pScrn->pScreen->width; + break; + } + + /* As DRI doesn't run on the secondary head, we know that disableTiling + * is always TRUE. + */ + if (I830IsPrimary(pScrn) && !pI830->disableTiling) { +#if 0 + int dWidth = pScrn->displayWidth; /* save current displayWidth */ +#endif + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + break; + } + } + + /* + * If the displayWidth is a tilable pitch, test if there's enough + * memory available to enable tiling. + */ + if (pScrn->displayWidth == pitches[i]) { + /* TODO */ + } + } + + if (reAllocate) { + if (pI830->entityPrivate) { + if (pI8302->rotation != RR_Rotate_0) { + if (!I830AllocateRotated2Buffer(pScrn1, + pI8302->disableTiling ? ALLOC_NO_TILING : 0)) + goto BAIL0; + + I830FixOffset(pScrn1, &(pI8301->RotatedMem2)); + if (pI8301->RotatedMem2.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset); + } + } + + if (pI8301->rotation != RR_Rotate_0) { + if (!I830AllocateRotatedBuffer(pScrn1, + (pI8301->disableTiling ? ALLOC_NO_TILING : 0))) + goto BAIL1; + + I830FixOffset(pScrn1, &(pI8301->RotatedMem)); + if (pI8301->RotatedMem.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset); + } + } + + shadowRemove (pScrn->pScreen, NULL); + if (pI830->rotation != RR_Rotate_0) + shadowAdd (pScrn->pScreen, + (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen), + func, I830WindowLinear, pI830->rotation, 0); + + if (I830IsPrimary(pScrn)) { + if (pI830->rotation != RR_Rotate_0) + pScrn->fbOffset = pI830->RotatedMem.Start; + else + pScrn->fbOffset = pI830->FrontBuffer.Start; + if (pI830->entityPrivate) { + if (pI8302->rotation != RR_Rotate_0) + pScrn2->fbOffset = pI8301->RotatedMem2.Start; + else + pScrn2->fbOffset = pI8301->FrontBuffer2.Start; + I830SelectBuffer(pScrn2, I830_SELECT_FRONT); + } + } else { + if (pI830->rotation != RR_Rotate_0) + pScrn->fbOffset = pI8301->RotatedMem2.Start; + else + pScrn->fbOffset = pI8301->FrontBuffer2.Start; + if (pI8301->rotation != RR_Rotate_0) + pScrn1->fbOffset = pI8301->RotatedMem.Start; + else + pScrn1->fbOffset = pI8301->FrontBuffer.Start; + I830SelectBuffer(pScrn1, I830_SELECT_FRONT); + } + I830SelectBuffer(pScrn, I830_SELECT_FRONT); + +#ifdef XF86DRI + if (pI8301->directRenderingEnabled && reAllocate) { + if (!I830AllocateBackBuffer(pScrn1, + pI8301->disableTiling ? ALLOC_NO_TILING : 0)) + goto BAIL2; + + if (!I830AllocateDepthBuffer(pScrn1, + pI8301->disableTiling ? ALLOC_NO_TILING : 0)) + goto BAIL3; + + if (!I830AllocateTextureMemory(pScrn1, + pI8301->disableTiling ? ALLOC_NO_TILING : 0)) + goto BAIL4; + + I830DoPoolAllocation(pScrn1, &(pI8301->StolenPool)); + + I830FixOffset(pScrn1, &(pI8301->BackBuffer)); + I830FixOffset(pScrn1, &(pI8301->DepthBuffer)); + + if (pI8301->BackBuffer.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset); + if (pI8301->DepthBuffer.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset); + if (pI8301->StolenPool.Allocated.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset); + if (pI8301->TexMem.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset); + I830SetupMemoryTiling(pScrn1); + /* update fence registers */ + for (i = 0; i < 8; i++) + OUTREG(FENCE + i * 4, pI8301->ModeReg.Fence[i]); + { + drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn1->pScreen); + I830UpdateDRIBuffers(pScrn1, sarea ); + } + + if (didLock) + I830DRIUnlock(pScrn1); + } +#endif + +#if 0 + if (I830IsPrimary(pScrn)) { + pI830->xoffset = (pI830->FrontBuffer.Start / pI830->cpp) % pI830->displayWidth; + pI830->yoffset = (pI830->FrontBuffer.Start / pI830->cpp) / pI830->displayWidth; + } else { + I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->xoffset = (pI8301->FrontBuffer2.Start / pI830->cpp) % pI830->displayWidth; + pI830->yoffset = (pI8301->FrontBuffer2.Start / pI830->cpp) / pI830->displayWidth; + } +#endif + + pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), pScrn->pScreen->width, + pScrn->pScreen->height, pScrn->pScreen->rootDepth, pScrn->bitsPerPixel, + PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth), + (pointer)(pI8301->FbBase + pScrn->fbOffset)); + + if (pI830->entityPrivate) { + if (I830IsPrimary(pScrn)) { + if (!pI830->starting) { + pScrn2->pScreen->ModifyPixmapHeader((*pScrn2->pScreen->GetScreenPixmap)(pScrn2->pScreen), pScrn2->pScreen->width, + pScrn2->pScreen->height, pScrn2->pScreen->rootDepth, pScrn2->bitsPerPixel, + PixmapBytePad(pScrn2->displayWidth, pScrn2->pScreen->rootDepth), + (pointer)(pI8301->FbBase + pScrn2->fbOffset)); + + /* Repaint the second head */ + (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE); + (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE); + } + } else { + if (!pI830->starting) { + pScrn1->pScreen->ModifyPixmapHeader((*pScrn1->pScreen->GetScreenPixmap)(pScrn1->pScreen), pScrn1->pScreen->width, + pScrn1->pScreen->height, pScrn1->pScreen->rootDepth, pScrn1->bitsPerPixel, + PixmapBytePad(pScrn1->displayWidth, pScrn1->pScreen->rootDepth), + (pointer)(pI8301->FbBase + pScrn1->fbOffset)); + + /* Repaint the first head */ + (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, FALSE); + (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, TRUE); + } + } + } + + /* Don't allow pixmap cache or offscreen pixmaps when rotated */ + /* XAA needs some serious fixing for this to happen */ + if (pI830->rotation == RR_Rotate_0) { + pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; + pI830->AccelInfoRec->UsingPixmapCache = TRUE; + /* funny as it seems this will enable XAA's createpixmap */ + pI830->AccelInfoRec->maxOffPixWidth = 0; + pI830->AccelInfoRec->maxOffPixHeight = 0; + } else { + pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; + pI830->AccelInfoRec->UsingPixmapCache = FALSE; + /* funny as it seems this will disable XAA's createpixmap */ + pI830->AccelInfoRec->maxOffPixWidth = 1; + pI830->AccelInfoRec->maxOffPixHeight = 1; + } + + return TRUE; + +BAIL4: +#ifdef XF86DRI + if (pI8301->directRenderingEnabled) + I830FreeVidMem(pScrn1, &(pI8301->DepthBuffer)); +#endif +BAIL3: +#ifdef XF86DRI + if (pI8301->directRenderingEnabled) + I830FreeVidMem(pScrn1, &(pI8301->BackBuffer)); +#endif +BAIL2: + if (pI8301->rotation != RR_Rotate_0) { + if (pI8301->RotatedMem.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key); + + I830FreeVidMem(pScrn1, &(pI8301->RotatedMem)); + memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem)); + pI8301->RotatedMem.Key = -1; + } +BAIL1: + if (pI830->entityPrivate) { + if (pI8302->rotation != RR_Rotate_0) { + if (pI8301->RotatedMem.Key != -1) + xf86UnbindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key); + + I830FreeVidMem(pScrn1, &(pI8301->RotatedMem)); + memset(&(pI8301->RotatedMem), 0, sizeof(pI8301->RotatedMem)); + pI8301->RotatedMem.Key = -1; + } + } +BAIL0: + pScrn->displayWidth = displayWidth; + + /* must flip mmWidth & mmHeight */ + if ( ((oldRotation & (RR_Rotate_90 | RR_Rotate_270)) && + (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))) || + ((oldRotation & (RR_Rotate_0 | RR_Rotate_180)) && + (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270))) ) { + int tmp = pScrn->pScreen->mmWidth; + pScrn->pScreen->mmWidth = pScrn->pScreen->mmHeight; + pScrn->pScreen->mmHeight = tmp; + } + + if (oldRotation & (RR_Rotate_0 | RR_Rotate_180)) { + pScrn->pScreen->width = pScrn->virtualX; + pScrn->pScreen->height = pScrn->virtualY; + } else { + pScrn->pScreen->width = pScrn->virtualY; + pScrn->pScreen->height = pScrn->virtualX; + } + + pI830->rotation = oldRotation; + + if (pI830->entityPrivate) { + if (pI8302->rotation != RR_Rotate_0) { + if (!I830AllocateRotated2Buffer(pScrn1, + pI8302->disableTiling ? ALLOC_NO_TILING : 0)) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Oh dear, the rotated2 buffer failed - badness\n"); + + I830FixOffset(pScrn1, &(pI8301->RotatedMem2)); + if (pI8301->RotatedMem2.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem2.Key, pI8301->RotatedMem2.Offset); + } + } + + if (pI8301->rotation != RR_Rotate_0) { + if (!I830AllocateRotatedBuffer(pScrn1, + (pI8301->disableTiling ? ALLOC_NO_TILING : 0))) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Oh dear, the rotated buffer failed - badness\n"); + + I830FixOffset(pScrn1, &(pI8301->RotatedMem)); + if (pI8301->RotatedMem.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->RotatedMem.Key, pI8301->RotatedMem.Offset); + } + + shadowRemove (pScrn->pScreen, NULL); + if (pI830->rotation != RR_Rotate_0) + shadowAdd (pScrn->pScreen, + (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen), + func, I830WindowLinear, pI830->rotation, 0); + + if (I830IsPrimary(pScrn)) { + if (pI830->rotation != RR_Rotate_0) + pScrn->fbOffset = pI830->RotatedMem.Start; + else + pScrn->fbOffset = pI830->FrontBuffer.Start; + if (pI830->entityPrivate) { + if (pI8302->rotation != RR_Rotate_0) + pScrn2->fbOffset = pI8301->RotatedMem2.Start; + else + pScrn2->fbOffset = pI8301->FrontBuffer2.Start; + I830SelectBuffer(pScrn2, I830_SELECT_FRONT); + } + } else { + if (pI830->rotation != RR_Rotate_0) + pScrn->fbOffset = pI8301->RotatedMem2.Start; + else + pScrn->fbOffset = pI8301->FrontBuffer2.Start; + if (pI8301->rotation != RR_Rotate_0) + pScrn1->fbOffset = pI8301->RotatedMem.Start; + else + pScrn1->fbOffset = pI8301->FrontBuffer.Start; + I830SelectBuffer(pScrn1, I830_SELECT_FRONT); + } + I830SelectBuffer(pScrn, I830_SELECT_FRONT); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Reverting to previous configured mode\n"); + + switch (oldRotation) { + case RR_Rotate_0: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen back to 0 degrees\n"); + break; + case RR_Rotate_90: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen back to 90 degrees\n"); + break; + case RR_Rotate_180: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen back to 180 degrees\n"); + break; + case RR_Rotate_270: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Rotating Screen back to 270 degrees\n"); + break; + } + +#ifdef XF86DRI + if (pI8301->directRenderingEnabled) { + if (!I830AllocateBackBuffer(pScrn1, + pI8301->disableTiling ? ALLOC_NO_TILING : 0)) + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Oh dear, the back buffer failed - badness\n"); + + if (!I830AllocateDepthBuffer(pScrn1, + pI8301->disableTiling ? ALLOC_NO_TILING : 0)) + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Oh dear, the depth buffer failed - badness\n"); + + if (!I830AllocateTextureMemory(pScrn1, + pI8301->disableTiling ? ALLOC_NO_TILING : 0)) + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Oh dear, the texture cache failed - badness\n"); + + I830DoPoolAllocation(pScrn1, &(pI8301->StolenPool)); + + I830FixOffset(pScrn1, &(pI8301->BackBuffer)); + I830FixOffset(pScrn1, &(pI8301->DepthBuffer)); + + if (pI8301->BackBuffer.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->BackBuffer.Key, pI8301->BackBuffer.Offset); + if (pI8301->DepthBuffer.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->DepthBuffer.Key, pI8301->DepthBuffer.Offset); + if (pI8301->StolenPool.Allocated.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->StolenPool.Allocated.Key, pI8301->StolenPool.Allocated.Offset); + if (pI8301->TexMem.Key != -1) + xf86BindGARTMemory(pScrn1->scrnIndex, pI8301->TexMem.Key, pI8301->TexMem.Offset); + I830SetupMemoryTiling(pScrn1); + /* update fence registers */ + for (i = 0; i < 8; i++) + OUTREG(FENCE + i * 4, pI8301->ModeReg.Fence[i]); + { + drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn1->pScreen); + I830UpdateDRIBuffers(pScrn1, sarea ); + } + + if (didLock) + I830DRIUnlock(pScrn1); + } +#endif + + pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen), pScrn->pScreen->width, + pScrn->pScreen->height, pScrn->pScreen->rootDepth, pScrn->bitsPerPixel, + PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth), + (pointer)(pI8301->FbBase + pScrn->fbOffset)); + + if (pI830->entityPrivate) { + if (I830IsPrimary(pScrn)) { + pScrn2->pScreen->ModifyPixmapHeader((*pScrn2->pScreen->GetScreenPixmap)(pScrn2->pScreen), pScrn2->pScreen->width, + pScrn2->pScreen->height, pScrn2->pScreen->rootDepth, pScrn2->bitsPerPixel, + PixmapBytePad(pScrn2->displayWidth, pScrn2->pScreen->rootDepth), + (pointer)(pI8301->FbBase + pScrn2->fbOffset)); + + /* Repaint the second head */ + (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, FALSE); + (*pScrn2->EnableDisableFBAccess) (pScrn2->pScreen->myNum, TRUE); + } else { + pScrn1->pScreen->ModifyPixmapHeader((*pScrn1->pScreen->GetScreenPixmap)(pScrn1->pScreen), pScrn1->pScreen->width, + pScrn1->pScreen->height, pScrn1->pScreen->rootDepth, pScrn1->bitsPerPixel, + PixmapBytePad(pScrn1->displayWidth, pScrn1->pScreen->rootDepth), + (pointer)(pI8301->FbBase + pScrn1->fbOffset)); + + /* Repaint the first head */ + (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, FALSE); + (*pScrn1->EnableDisableFBAccess) (pScrn1->pScreen->myNum, TRUE); + } + } + + return FALSE; +} diff --git a/src/i830_shadow.c b/src/i830_shadow.c deleted file mode 100644 index 93c72c59..00000000 --- a/src/i830_shadow.c +++ /dev/null @@ -1,253 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_shadow.c,v 1.3 2000/03/31 20:13:33 dawes Exp $ */ - -/* - Copyright (c) 1999,2000 The XFree86 Project Inc. - based on code written by Mark Vojkovich <markv@valinux.com> -*/ - -/* - * Ported from the savage driver to the I830 by - * Helmar Spangenberg <hspangenberg@frey.de> and Dima Dorfman - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "i830.h" -#include "shadowfb.h" -#include "servermd.h" - - -void -I830RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) -{ - I830Ptr pI830 = I830PTR(pScrn); - int width, height, Bpp, FBPitch; - unsigned char *src, *dst; - - Bpp = pScrn->bitsPerPixel >> 3; - FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); - - while(num--) { - width = (pbox->x2 - pbox->x1) * Bpp; - height = pbox->y2 - pbox->y1; - src = pI830->shadowPtr + (pbox->y1 * pI830->shadowPitch) + - (pbox->x1 * Bpp); - dst = pI830->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); - - while(height--) { - memcpy(dst, src, width); - dst += FBPitch; - src += pI830->shadowPitch; - } - - pbox++; - } -} - - -void -I830PointerMoved(int index, int x, int y) -{ - ScrnInfoPtr pScrn = xf86Screens[index]; - I830Ptr pI830 = I830PTR(pScrn); - int newX, newY; - - if(pI830->rotate == 1) { - newX = pScrn->pScreen->height - y - 1; - newY = x; - } else { - newX = y; - newY = pScrn->pScreen->width - x - 1; - } - - (*pI830->PointerMoved)(index, newX, newY); -} - -void -I830RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) -{ - I830Ptr pI830 = I830PTR(pScrn); - int count, width, height, y1, y2, dstPitch, srcPitch; - CARD8 *dstPtr, *srcPtr, *src; - CARD32 *dst; - - dstPitch = pScrn->displayWidth; - srcPitch = -pI830->rotate * pI830->shadowPitch; - - while(num--) { - width = pbox->x2 - pbox->x1; - y1 = pbox->y1 & ~3; - y2 = (pbox->y2 + 3) & ~3; - height = (y2 - y1) >> 2; /* in dwords */ - - if(pI830->rotate == 1) { - dstPtr = pI830->FbBase + - (pbox->x1 * dstPitch) + pScrn->virtualX - y2; - srcPtr = pI830->shadowPtr + ((1 - y2) * srcPitch) + pbox->x1; - } else { - dstPtr = pI830->FbBase + - ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; - srcPtr = pI830->shadowPtr + (y1 * srcPitch) + pbox->x2 - 1; - } - - while(width--) { - src = srcPtr; - dst = (CARD32*)dstPtr; - count = height; - while(count--) { - *(dst++) = src[0] | (src[srcPitch] << 8) | - (src[srcPitch * 2] << 16) | - (src[srcPitch * 3] << 24); - src += srcPitch * 4; - } - srcPtr += pI830->rotate; - dstPtr += dstPitch; - } - - pbox++; - } -} - - -void -I830RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) -{ - I830Ptr pI830 = I830PTR(pScrn); - int count, width, height, y1, y2, dstPitch, srcPitch; - CARD16 *dstPtr, *srcPtr, *src; - CARD32 *dst; - - dstPitch = pScrn->displayWidth; - srcPitch = -pI830->rotate * pI830->shadowPitch >> 1; - - while(num--) { - width = pbox->x2 - pbox->x1; - y1 = pbox->y1 & ~1; - y2 = (pbox->y2 + 1) & ~1; - height = (y2 - y1) >> 1; /* in dwords */ - - if(pI830->rotate == 1) { - dstPtr = (CARD16*)pI830->FbBase + - (pbox->x1 * dstPitch) + pScrn->virtualX - y2; - srcPtr = (CARD16*)pI830->shadowPtr + - ((1 - y2) * srcPitch) + pbox->x1; - } else { - dstPtr = (CARD16*)pI830->FbBase + - ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; - srcPtr = (CARD16*)pI830->shadowPtr + - (y1 * srcPitch) + pbox->x2 - 1; - } - - while(width--) { - src = srcPtr; - dst = (CARD32*)dstPtr; - count = height; - while(count--) { - *(dst++) = src[0] | (src[srcPitch] << 16); - src += srcPitch * 2; - } - srcPtr += pI830->rotate; - dstPtr += dstPitch; - } - - pbox++; - } -} - - -/* this one could be faster */ -void -I830RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) -{ - I830Ptr pI830 = I830PTR(pScrn); - int count, width, height, y1, y2, dstPitch, srcPitch; - CARD8 *dstPtr, *srcPtr, *src; - CARD32 *dst; - - dstPitch = BitmapBytePad(pScrn->displayWidth * 24); - srcPitch = -pI830->rotate * pI830->shadowPitch; - - while(num--) { - width = pbox->x2 - pbox->x1; - y1 = pbox->y1 & ~3; - y2 = (pbox->y2 + 3) & ~3; - height = (y2 - y1) >> 2; /* blocks of 3 dwords */ - - if(pI830->rotate == 1) { - dstPtr = pI830->FbBase + - (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); - srcPtr = pI830->shadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); - } else { - dstPtr = pI830->FbBase + - ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); - srcPtr = pI830->shadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; - } - - while(width--) { - src = srcPtr; - dst = (CARD32*)dstPtr; - count = height; - while(count--) { - dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | - (src[srcPitch] << 24); - dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | - (src[srcPitch * 2] << 16) | - (src[(srcPitch * 2) + 1] << 24); - dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | - (src[(srcPitch * 3) + 1] << 16) | - (src[(srcPitch * 3) + 2] << 24); - dst += 3; - src += srcPitch * 4; - } - srcPtr += pI830->rotate * 3; - dstPtr += dstPitch; - } - - pbox++; - } -} - -void -I830RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) -{ - I830Ptr pI830 = I830PTR(pScrn); - int count, width, height, dstPitch, srcPitch; - CARD32 *dstPtr, *srcPtr, *src, *dst; - - dstPitch = pScrn->displayWidth; - srcPitch = -pI830->rotate * pI830->shadowPitch >> 2; - - while(num--) { - width = pbox->x2 - pbox->x1; - height = pbox->y2 - pbox->y1; - - if(pI830->rotate == 1) { - dstPtr = (CARD32*)pI830->FbBase + - (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; - srcPtr = (CARD32*)pI830->shadowPtr + - ((1 - pbox->y2) * srcPitch) + pbox->x1; - } else { - dstPtr = (CARD32*)pI830->FbBase + - ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; - srcPtr = (CARD32*)pI830->shadowPtr + - (pbox->y1 * srcPitch) + pbox->x2 - 1; - } - - while(width--) { - src = srcPtr; - dst = dstPtr; - count = height; - while(count--) { - *(dst++) = *src; - src += srcPitch; - } - srcPtr += pI830->rotate; - dstPtr += dstPitch; - } - - pbox++; - } -} diff --git a/src/i830_video.c b/src/i830_video.c index 12c25e05..a608a7e3 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -64,16 +64,18 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <math.h> +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "regionstr.h" - +#include "randrstr.h" #include "i830.h" #include "xf86xv.h" #include <X11/extensions/Xv.h> @@ -106,7 +108,7 @@ static void I830QueryBestSize(ScrnInfoPtr, Bool, unsigned int *, pointer); static int I830PutImage(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char *, short, short, - Bool, RegionPtr, pointer); + Bool, RegionPtr, pointer, DrawablePtr); static int I830QueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); @@ -114,12 +116,13 @@ static void I830BlockHandler(int, pointer, pointer, pointer); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) -static Atom xvBrightness, xvContrast, xvColorKey, xvPipe; +static Atom xvBrightness, xvContrast, xvColorKey, xvPipe, xvDoubleBuffer; static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5; -#define IMAGE_MAX_WIDTH 1440 -#define IMAGE_MAX_HEIGHT 1080 -#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) +#define IMAGE_MAX_WIDTH 1920 +#define IMAGE_MAX_HEIGHT 1088 +#define IMAGE_MAX_WIDTH_LEGACY 1024 +#define IMAGE_MAX_HEIGHT_LEGACY 1088 #if !VIDEO_DEBUG #define ErrorF Edummy @@ -138,13 +141,13 @@ Edummy(const char *dummy, ...) * all modes of server exit. */ -#define OVERLAY_UPDATE \ +#define OVERLAY_UPDATE \ do { \ BEGIN_LP_RING(6); \ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \ OUT_RING(MI_NOOP); \ if (!*pI830->overlayOn) { \ - OUT_RING(MI_NOOP); \ + OUT_RING(MI_NOOP); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON); \ ErrorF("Overlay goes from off to on\n"); \ @@ -154,7 +157,7 @@ Edummy(const char *dummy, ...) OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \ } \ - OUT_RING(pI830->OverlayMem->Physical | 1); \ + OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ ADVANCE_LP_RING(); \ ErrorF("OVERLAY_UPDATE\n"); \ } while(0) @@ -162,18 +165,28 @@ Edummy(const char *dummy, ...) #define OVERLAY_OFF \ do { \ if (*pI830->overlayOn) { \ - BEGIN_LP_RING(8); \ + int spin = 1000000; \ + BEGIN_LP_RING(12); \ OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \ OUT_RING(MI_NOOP); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ + OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \ + OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ + OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ + OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \ - OUT_RING(pI830->OverlayMem->Physical); \ + OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ ADVANCE_LP_RING(); \ *pI830->overlayOn = FALSE; \ ErrorF("Overlay goes from on to off\n"); \ + while (spin != 0 && (INREG(OCMD_REGISTER) & OVERLAY_ENABLE)){ \ + ErrorF("SPIN %d\n",spin); \ + spin--; \ + } \ + if (spin == 0) ErrorF("OVERLAY FAILED TO GO OFF\n"); \ ErrorF("OVERLAY_OFF\n"); \ } \ } while(0) @@ -181,6 +194,7 @@ Edummy(const char *dummy, ...) /* * OCMD - Overlay Command Register */ +#define OCMD_REGISTER 0x30168 #define MIRROR_MODE (0x3<<17) #define MIRROR_HORIZONTAL (0x1<<17) #define MIRROR_VERTICAL (0x2<<17) @@ -212,11 +226,15 @@ Edummy(const char *dummy, ...) #define FIELD1 (0x1<<1) #define OVERLAY_ENABLE 0x1 +#define OFC_UPDATE 0x1 + /* OCONFIG register */ #define CC_OUT_8BIT (0x1<<3) #define OVERLAY_PIPE_MASK (0x1<<18) #define OVERLAY_PIPE_A (0x0<<18) #define OVERLAY_PIPE_B (0x1<<18) +#define THREE_LINE_BUFFERS (0x1<<0) +#define TWO_LINE_BUFFERS (0x0<<0) /* DCLRKM register */ #define DEST_KEY_ENABLE (0x1<<31) @@ -260,11 +278,12 @@ static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 1, "XV_PIPE"} }; -#define NUM_ATTRIBUTES 3 +#define NUM_ATTRIBUTES 4 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, - {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} + {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}, + {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"} }; #define GAMMA_ATTRIBUTES 6 @@ -355,6 +374,7 @@ typedef struct { int brightness; int contrast; int pipe; + int doubleBuffer; RegionRec clip; CARD32 colorKey; @@ -390,7 +410,7 @@ CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size) for (i = 0; i < size; i += 4) { val = INREG(0x30100 + i); if (val != overlay[i / 4]) { - ErrorF("0x%05x value doesn't match (0x%08x != 0x%08x)\n", + ErrorF("0x%05x value doesn't match (0x%lx != 0x%lx)\n", 0x30100 + i, val, overlay[i / 4]); bad++; } @@ -463,7 +483,7 @@ I830ResetVideo(ScrnInfoPtr pScrn) I830OverlayRegPtr overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); - DPRINTF(PFX, "I830ResetVideo: base: %p, offset: 0x%08x, obase: %p\n", + DPRINTF(PFX, "I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n", pI830->FbBase, pI830->OverlayMem->Start, overlay); /* * Default to maximum image size in YV12 @@ -475,10 +495,10 @@ I830ResetVideo(ScrnInfoPtr pScrn) overlay->HORZ_PH = 0; overlay->INIT_PHS = 0; overlay->DWINPOS = 0; - overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH; - overlay->SWIDTH = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 16); - overlay->SWIDTHSW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12); - overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15); + overlay->DWINSZ = 0; + overlay->SWIDTH = 0; + overlay->SWIDTHSW = 0; + overlay->SHEIGHT = 0; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); overlay->OCLRC1 = 0x00000080; /* saturation: bypass */ overlay->AWINPOS = 0; @@ -532,7 +552,7 @@ I830ResetVideo(ScrnInfoPtr pScrn) { int i; for (i = 0x30000; i < 0x31000; i += 4) - ErrorF("0x%x 0x%08x\n", i, INREG(i)); + ErrorF("0x%x 0x%lx\n", i, INREG(i)); } #endif } @@ -572,18 +592,53 @@ I830SetOneLineModeRatio(ScrnInfoPtr pScrn) pPriv->oneLineMode = FALSE; } +static CARD32 I830BoundGammaElt (CARD32 elt, CARD32 eltPrev) +{ + elt &= 0xff; + eltPrev &= 0xff; + if (elt < eltPrev) + elt = eltPrev; + else if ((elt - eltPrev) > 0x7e) + elt = eltPrev + 0x7e; + return elt; +} + +static CARD32 I830BoundGamma (CARD32 gamma, CARD32 gammaPrev) +{ + return (I830BoundGammaElt (gamma >> 24, gammaPrev >> 24) << 24 | + I830BoundGammaElt (gamma >> 16, gammaPrev >> 16) << 16 | + I830BoundGammaElt (gamma >> 8, gammaPrev >> 8) << 8 | + I830BoundGammaElt (gamma , gammaPrev )); +} + static void I830UpdateGamma(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; - - OUTREG(OGAMC5, pPriv->gamma5); - OUTREG(OGAMC4, pPriv->gamma4); - OUTREG(OGAMC3, pPriv->gamma3); - OUTREG(OGAMC2, pPriv->gamma2); - OUTREG(OGAMC1, pPriv->gamma1); - OUTREG(OGAMC0, pPriv->gamma0); + CARD32 gamma0 = pPriv->gamma0; + CARD32 gamma1 = pPriv->gamma1; + CARD32 gamma2 = pPriv->gamma2; + CARD32 gamma3 = pPriv->gamma3; + CARD32 gamma4 = pPriv->gamma4; + CARD32 gamma5 = pPriv->gamma5; + + ErrorF ("Original gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + gamma0, gamma1, gamma2, gamma3, gamma4, gamma5); + gamma1 = I830BoundGamma (gamma1, gamma0); + gamma2 = I830BoundGamma (gamma2, gamma1); + gamma3 = I830BoundGamma (gamma3, gamma2); + gamma4 = I830BoundGamma (gamma4, gamma3); + gamma5 = I830BoundGamma (gamma5, gamma4); + ErrorF ("Bounded gamma: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + gamma0, gamma1, gamma2, gamma3, gamma4, gamma5); + + OUTREG(OGAMC5, gamma5); + OUTREG(OGAMC4, gamma4); + OUTREG(OGAMC3, gamma3); + OUTREG(OGAMC2, gamma2); + OUTREG(OGAMC1, gamma1); + OUTREG(OGAMC0, gamma0); } static XF86VideoAdaptorPtr @@ -602,10 +657,15 @@ I830SetupImageVideo(ScreenPtr pScreen) return NULL; adapt->type = XvWindowMask | XvInputMask | XvImageMask; - adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/; adapt->name = "Intel(R) Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = DummyEncoding; + /* update the DummyEncoding for these two chipsets */ + if (IS_845G(pI830) || IS_I830(pI830)) { + adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY; + adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY; + } adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = 1; @@ -617,7 +677,7 @@ I830SetupImageVideo(ScreenPtr pScreen) adapt->nAttributes = NUM_ATTRIBUTES; if (pI830->Clone) adapt->nAttributes += CLONE_ATTRIBUTES; - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) + if (IS_I9XX(pI830)) adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */ adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes); /* Now copy the attributes */ @@ -628,7 +688,7 @@ I830SetupImageVideo(ScreenPtr pScreen) memcpy((char*)att, (char*)CloneAttributes, sizeof(XF86AttributeRec) * CLONE_ATTRIBUTES); att+=CLONE_ATTRIBUTES; } - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + if (IS_I9XX(pI830)) { memcpy((char*)att, (char*)GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES); att+=GAMMA_ATTRIBUTES; } @@ -658,6 +718,7 @@ I830SetupImageVideo(ScreenPtr pScreen) pPriv->gamma2 = 0x202020; pPriv->gamma1 = 0x101010; pPriv->gamma0 = 0x080808; + pPriv->doubleBuffer = 1; /* gotta uninit this someplace */ REGION_NULL(pScreen, &pPriv->clip); @@ -680,15 +741,16 @@ I830SetupImageVideo(ScreenPtr pScreen) pI830->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = I830BlockHandler; + xvColorKey = MAKE_ATOM("XV_COLORKEY"); xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); xvContrast = MAKE_ATOM("XV_CONTRAST"); - xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); /* Allow the pipe to be switched from pipe A to B when in clone mode */ if (pI830->Clone) xvPipe = MAKE_ATOM("XV_PIPE"); - - if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) { + + if (IS_I9XX(pI830)) { xvGamma0 = MAKE_ATOM("XV_GAMMA0"); xvGamma1 = MAKE_ATOM("XV_GAMMA1"); xvGamma2 = MAKE_ATOM("XV_GAMMA2"); @@ -747,10 +809,12 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if (shutdown) { if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + overlay->OCMD &= ~OVERLAY_ENABLE; OVERLAY_UPDATE; - +#if 1 OVERLAY_OFF; +#endif if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; @@ -783,15 +847,23 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, return BadValue; pPriv->brightness = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); - if (pPriv->overlayOK) - OVERLAY_UPDATE; + ErrorF("BRIGHTNESS\n"); + overlay->OCMD &= ~OVERLAY_ENABLE; + OVERLAY_UPDATE; +#if 1 + OVERLAY_OFF; +#endif } else if (attribute == xvContrast) { if ((value < 0) || (value > 255)) return BadValue; pPriv->contrast = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); - if (pPriv->overlayOK) - OVERLAY_UPDATE; + ErrorF("CONTRAST\n"); + overlay->OCMD &= ~OVERLAY_ENABLE; + OVERLAY_UPDATE; +#if 1 + OVERLAY_OFF; +#endif } else if (pI830->Clone && attribute == xvPipe) { if ((value < 0) || (value > 1)) return BadValue; @@ -804,52 +876,24 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, overlay->OCONFIG |= OVERLAY_PIPE_A; else overlay->OCONFIG |= OVERLAY_PIPE_B; - if (pPriv->overlayOK) - OVERLAY_UPDATE; - } else if (attribute == xvGamma0 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { - /* Avoid video anomalies, so set gamma registers when overlay is off */ - /* We also clamp the values if they are outside the ranges */ - if (!*pI830->overlayOn) { - pPriv->gamma0 = value; - if (pPriv->gamma1 - pPriv->gamma0 > 0x7d) - pPriv->gamma1 = pPriv->gamma0 + 0x7d; - } else - return BadRequest; - } else if (attribute == xvGamma1 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { - if (!*pI830->overlayOn) { - pPriv->gamma1 = value; - if (pPriv->gamma1 - pPriv->gamma0 > 0x7d) - pPriv->gamma0 = pPriv->gamma1 - 0x7d; - } else - return BadRequest; - } else if (attribute == xvGamma2 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { - if (!*pI830->overlayOn) { - pPriv->gamma2 = value; - if (pPriv->gamma3 - pPriv->gamma2 > 0x7d) - pPriv->gamma3 = pPriv->gamma2 + 0x7d; - } else - return BadRequest; - } else if (attribute == xvGamma3 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { - if (!*pI830->overlayOn) { - pPriv->gamma3 = value; - if (pPriv->gamma3 - pPriv->gamma2 > 0x7d) - pPriv->gamma2 = pPriv->gamma3 - 0x7d; - } else - return BadRequest; - } else if (attribute == xvGamma4 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { - if (!*pI830->overlayOn) { - pPriv->gamma4 = value; - if (pPriv->gamma5 - pPriv->gamma4 > 0x7d) - pPriv->gamma5 = pPriv->gamma4 + 0x7d; - } else - return BadRequest; - } else if (attribute == xvGamma5 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { - if (!*pI830->overlayOn) { - pPriv->gamma5 = value; - if (pPriv->gamma5 - pPriv->gamma4 > 0x7d) - pPriv->gamma4 = pPriv->gamma5 - 0x7d; - } else - return BadRequest; + ErrorF("PIPE CHANGE\n"); + overlay->OCMD &= ~OVERLAY_ENABLE; + OVERLAY_UPDATE; +#if 1 + OVERLAY_OFF; +#endif + } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) { + pPriv->gamma0 = value; + } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) { + pPriv->gamma1 = value; + } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) { + pPriv->gamma2 = value; + } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) { + pPriv->gamma3 = value; + } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) { + pPriv->gamma4 = value; + } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) { + pPriv->gamma5 = value; } else if (attribute == xvColorKey) { pPriv->colorKey = value; switch (pScrn->depth) { @@ -863,9 +907,19 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, overlay->DCLRKV = pPriv->colorKey; break; } - if (pPriv->overlayOK) - OVERLAY_UPDATE; + ErrorF("COLORKEY\n"); + overlay->OCMD &= ~OVERLAY_ENABLE; + OVERLAY_UPDATE; +#if 1 + OVERLAY_OFF; +#endif REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + } else if(attribute == xvDoubleBuffer) { + if ((value < 0) || (value > 1)) + return BadValue; + /* Do not allow buffer change while playing video */ + if(!*pI830->overlayOn) + pPriv->doubleBuffer = value; } else return BadMatch; @@ -875,7 +929,13 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, attribute == xvGamma2 || attribute == xvGamma3 || attribute == xvGamma4 || - attribute == xvGamma5) && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + attribute == xvGamma5) && (IS_I9XX(pI830))) { + ErrorF("GAMMA\n"); + overlay->OCMD &= ~OVERLAY_ENABLE; + OVERLAY_UPDATE; +#if 1 + OVERLAY_OFF; +#endif I830UpdateGamma(pScrn); } @@ -895,21 +955,23 @@ I830GetPortAttribute(ScrnInfoPtr pScrn, *value = pPriv->contrast; } else if (pI830->Clone && attribute == xvPipe) { *value = pPriv->pipe; - } else if (attribute == xvGamma0 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) { *value = pPriv->gamma0; - } else if (attribute == xvGamma1 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) { *value = pPriv->gamma1; - } else if (attribute == xvGamma2 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) { *value = pPriv->gamma2; - } else if (attribute == xvGamma3 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + } else if (attribute == xvGamma3 && (IS_I9XX(pI830))) { *value = pPriv->gamma3; - } else if (attribute == xvGamma4 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + } else if (attribute == xvGamma4 && (IS_I9XX(pI830))) { *value = pPriv->gamma4; - } else if (attribute == xvGamma5 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) { + } else if (attribute == xvGamma5 && (IS_I9XX(pI830))) { *value = pPriv->gamma5; } else if (attribute == xvColorKey) { *value = pPriv->colorKey; - } else + } else if (attribute == xvDoubleBuffer) { + *value = pPriv->doubleBuffer; + } else return BadMatch; return Success; @@ -940,8 +1002,10 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; unsigned char *src, *dst; + int i,j; + unsigned char *s; - DPRINTF(PFX, "I830CopyPackedData: (%d,%d) (%d,%d)\n" + ErrorF("I830CopyPackedData: (%d,%d) (%d,%d)\n" "srcPitch: %d, dstPitch: %d\n", top, left, h, w, srcPitch, dstPitch); src = buf + (top * srcPitch) + (left << 1); @@ -951,11 +1015,76 @@ I830CopyPackedData(ScrnInfoPtr pScrn, else dst = pI830->FbBase + pPriv->YBuf1offset; - w <<= 1; - while (h--) { - memcpy(dst, src, w); - src += srcPitch; - dst += dstPitch; + switch (pI830->rotation) { + case RR_Rotate_0: + w <<= 1; + for (i = 0; i < h; i++) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } + break; + case RR_Rotate_90: + h <<= 1; + for (i = 0; i < h; i+=2) { + s = src; + for (j = 0; j < w; j++) { + /* Copy Y */ + dst[(i + 0) + ((w - j - 1) * dstPitch)] = *s++; + (void)*s++; + } + src += srcPitch; + } + h >>= 1; + src = buf + (top * srcPitch) + (left << 1); + for (i = 0; i < h; i+=2) { + for (j = 0; j < w; j+=2) { + /* Copy U */ + dst[((i*2) + 1) + ((w - j - 1) * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)]; + dst[((i*2) + 1) + ((w - j - 2) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)]; + /* Copy V */ + dst[((i*2) + 3) + ((w - j - 1) * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)]; + dst[((i*2) + 3) + ((w - j - 2) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)]; + } + } + break; + case RR_Rotate_180: + w <<= 1; + for (i = 0; i < h; i++) { + s = src; + for (j = 0; j < w; j+=4) { + dst[(w - j - 4) + ((h - i - 1) * dstPitch)] = *s++; + dst[(w - j - 3) + ((h - i - 1) * dstPitch)] = *s++; + dst[(w - j - 2) + ((h - i - 1) * dstPitch)] = *s++; + dst[(w - j - 1) + ((h - i - 1) * dstPitch)] = *s++; + } + src += srcPitch; + } + break; + case RR_Rotate_270: + h <<= 1; + for (i = 0; i < h; i+=2) { + s = src; + for (j = 0; j < w; j++) { + /* Copy Y */ + dst[(h - i - 2) + (j * dstPitch)] = *s++; + (void)*s++; + } + src += srcPitch; + } + h >>= 1; + src = buf + (top * srcPitch) + (left << 1); + for (i = 0; i < h; i+=2) { + for (j = 0; j < w; j+=2) { + /* Copy U */ + dst[(((h - i)*2) - 3) + (j * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)]; + dst[(((h - i)*2) - 3) + ((j - 1) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)]; + /* Copy V */ + dst[(((h - i)*2) - 1) + (j * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)]; + dst[(((h - i)*2) - 1) + ((j - 1) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)]; + } + } + break; } } @@ -966,8 +1095,10 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch, { I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; - int i; + int i, j = 0; unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3; + unsigned char *s; + int dstPitch2 = dstPitch << 1; ErrorF("I830CopyPlanarData: srcPitch %d, srcPitch %d, dstPitch %d\n" "nlines %d, npixels %d, top %d, left %d\n", srcPitch, srcPitch2, dstPitch, @@ -975,22 +1106,53 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch, /* Copy Y data */ src1 = buf + (top * srcPitch) + left; - ErrorF("src1 is %p, offset is %d\n", src1, + ErrorF("src1 is %p, offset is %ld\n", src1, (unsigned long)src1 - (unsigned long)buf); if (pPriv->currentBuf == 0) dst1 = pI830->FbBase + pPriv->YBuf0offset; else dst1 = pI830->FbBase + pPriv->YBuf1offset; - for (i = 0; i < h; i++) { - memcpy(dst1, src1, w); - src1 += srcPitch; - dst1 += dstPitch << 1; + switch (pI830->rotation) { + case RR_Rotate_0: + for (i = 0; i < h; i++) { + memcpy(dst1, src1, w); + src1 += srcPitch; + dst1 += dstPitch2; + } + break; + case RR_Rotate_90: + for (i = 0; i < h; i++) { + s = src1; + for (j = 0; j < w; j++) { + dst1[(i) + ((w - j - 1) * dstPitch2)] = *s++; + } + src1 += srcPitch; + } + break; + case RR_Rotate_180: + for (i = 0; i < h; i++) { + s = src1; + for (j = 0; j < w; j++) { + dst1[(w - j - 1) + ((h - i - 1) * dstPitch2)] = *s++; + } + src1 += srcPitch; + } + break; + case RR_Rotate_270: + for (i = 0; i < h; i++) { + s = src1; + for (j = 0; j < w; j++) { + dst1[(h - i - 1) + (j * dstPitch2)] = *s++; + } + src1 += srcPitch; + } + break; } /* Copy V data for YV12, or U data for I420 */ src2 = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1); - ErrorF("src2 is %p, offset is %d\n", src2, + ErrorF("src2 is %p, offset is %ld\n", src2, (unsigned long)src2 - (unsigned long)buf); if (pPriv->currentBuf == 0) { if (id == FOURCC_I420) @@ -1004,16 +1166,47 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch, dst2 = pI830->FbBase + pPriv->VBuf1offset; } - for (i = 0; i < h / 2; i++) { - memcpy(dst2, src2, w / 2); - src2 += srcPitch2; - dst2 += dstPitch; + switch (pI830->rotation) { + case RR_Rotate_0: + for (i = 0; i < h / 2; i++) { + memcpy(dst2, src2, w / 2); + src2 += srcPitch2; + dst2 += dstPitch; + } + break; + case RR_Rotate_90: + for (i = 0; i < (h/2); i++) { + s = src2; + for (j = 0; j < (w/2); j++) { + dst2[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++; + } + src2 += srcPitch2; + } + break; + case RR_Rotate_180: + for (i = 0; i < (h/2); i++) { + s = src2; + for (j = 0; j < (w/2); j++) { + dst2[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++; + } + src2 += srcPitch2; + } + break; + case RR_Rotate_270: + for (i = 0; i < (h/2); i++) { + s = src2; + for (j = 0; j < (w/2); j++) { + dst2[((h/2) - i - 1) + (j * dstPitch)] = *s++; + } + src2 += srcPitch2; + } + break; } /* Copy U data for YV12, or V data for I420 */ src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) + ((top * srcPitch) >> 2) + (left >> 1); - ErrorF("src3 is %p, offset is %d\n", src3, + ErrorF("src3 is %p, offset is %ld\n", src3, (unsigned long)src3 - (unsigned long)buf); if (pPriv->currentBuf == 0) { if (id == FOURCC_I420) @@ -1027,10 +1220,41 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch, dst3 = pI830->FbBase + pPriv->UBuf1offset; } - for (i = 0; i < h / 2; i++) { - memcpy(dst3, src3, w / 2); - src3 += srcPitch2; - dst3 += dstPitch; + switch (pI830->rotation) { + case RR_Rotate_0: + for (i = 0; i < h / 2; i++) { + memcpy(dst3, src3, w / 2); + src3 += srcPitch2; + dst3 += dstPitch; + } + break; + case RR_Rotate_90: + for (i = 0; i < (h/2); i++) { + s = src3; + for (j = 0; j < (w/2); j++) { + dst3[(i) + (((w/2) - j - 1) * (dstPitch))] = *s++; + } + src3 += srcPitch2; + } + break; + case RR_Rotate_180: + for (i = 0; i < (h/2); i++) { + s = src3; + for (j = 0; j < (w/2); j++) { + dst3[((w/2) - j - 1) + (((h/2) - i - 1) * dstPitch)] = *s++; + } + src3 += srcPitch2; + } + break; + case RR_Rotate_270: + for (i = 0; i < (h/2); i++) { + s = src3; + for (j = 0; j < (w/2); j++) { + dst3[((h/2) - i - 1) + (j * dstPitch)] = *s++; + } + src3 += srcPitch2; + } + break; } } @@ -1175,6 +1399,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); unsigned int swidth; unsigned int mask, shift, offsety, offsetu; + int tmp; ErrorF("I830DisplayVideo: %dx%d (pitch %d)\n", width, height, dstPitch); @@ -1182,7 +1407,157 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, if (!pPriv->overlayOK) return; - if (IS_I915G(pI830) || IS_I915GM(pI830)) { +#if VIDEO_DEBUG + CompareOverlay(pI830, (CARD32 *) overlay, 0x100); +#endif + + /* When in dual head with different bpp setups we need to refresh the + * color key, so let's reset the video parameters and refresh here */ + if (pI830->entityPrivate) + I830ResetVideo(pScrn); + + /* Ensure overlay is turned on with OVERLAY_ENABLE at 0 */ + if (!*pI830->overlayOn) + OVERLAY_UPDATE; + + switch (pI830->rotation) { + case RR_Rotate_0: + dstBox->x1 -= pScrn->frameX0; + dstBox->x2 -= pScrn->frameX0; + dstBox->y1 -= pScrn->frameY0; + dstBox->y2 -= pScrn->frameY0; + break; + case RR_Rotate_90: + tmp = dstBox->x1; + dstBox->x1 = dstBox->y1 - pScrn->frameX0; + dstBox->y1 = pScrn->virtualY - tmp - pScrn->frameY0; + tmp = dstBox->x2; + dstBox->x2 = dstBox->y2 - pScrn->frameX0; + dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0; + tmp = dstBox->y1; + dstBox->y1 = dstBox->y2; + dstBox->y2 = tmp; + break; + case RR_Rotate_180: + tmp = dstBox->x1; + dstBox->x1 = pScrn->virtualX - dstBox->x2 - pScrn->frameX0; + dstBox->x2 = pScrn->virtualX - tmp - pScrn->frameX0; + tmp = dstBox->y1; + dstBox->y1 = pScrn->virtualY - dstBox->y2 - pScrn->frameY0; + dstBox->y2 = pScrn->virtualY - tmp - pScrn->frameY0; + break; + case RR_Rotate_270: + tmp = dstBox->x1; + dstBox->x1 = pScrn->virtualX - dstBox->y1 - pScrn->frameX0; + dstBox->y1 = tmp - pScrn->frameY0; + tmp = dstBox->x2; + dstBox->x2 = pScrn->virtualX - dstBox->y2 - pScrn->frameX0; + dstBox->y2 = tmp - pScrn->frameY0; + tmp = dstBox->x1; + dstBox->x1 = dstBox->x2; + dstBox->x2 = tmp; + break; + } + + /* Fix up the dstBox if outside the visible screen */ + { + int offset_x = (dstBox->x1 < 0) ? -dstBox->x1 : 0; + int offset_y = (dstBox->y1 < 0) ? -dstBox->y1 : 0; + int offset, offset2; + + /* align */ + offset_x = (offset_x + 3) & ~3; + offset_y = (offset_y + 3) & ~3; + + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + height -= offset_x; + width -= offset_y; + } else { + height -= offset_y; + width -= offset_x; + } + + if (id == FOURCC_I420 || id == FOURCC_YV12) { + offset = ((offset_x/2) + (dstPitch * offset_y)) * 2; + offset2 = ((offset_x/2) + ((dstPitch/2) * offset_y)); + } else { + offset = ((offset_x*2) + (dstPitch * offset_y)); + offset2 = ((offset_x*2) + ((dstPitch/2) * offset_y)); + } + + /* buffer locations */ + pPriv->YBuf0offset += offset; + pPriv->UBuf0offset += offset2; + pPriv->VBuf0offset += offset2; + + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset += offset; + pPriv->UBuf1offset += offset2; + pPriv->VBuf1offset += offset2; + } + } + + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + tmp = width; + width = height; + height = tmp; + tmp = drw_w; + drw_w = drw_h; + drw_h = tmp; + tmp = src_w; + src_w = src_h; + src_h = tmp; + } + + if (pPriv->oneLineMode) { + /* change the coordinates with panel fitting active */ + dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1; + dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1; + + /* Now, alter the height, so we scale to the correct size */ + drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1; + } + + { + /* Keep the engine happy and clip to the real vertical size just + * in case an LFP is in use and it's not at it's native resolution. + */ + int vactive = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF); + + vactive += 1; + + if (dstBox->y1 < 0) dstBox->y1 = 0; + if (dstBox->y2 < 0) dstBox->y2 = 0; + if (dstBox->x1 < 0) dstBox->x1 = 0; + if (dstBox->x2 < 0) dstBox->x2 = 0; + if (dstBox->y1 > vactive) dstBox->y1 = vactive; + if (dstBox->y2 > vactive) dstBox->y2 = vactive; + if (dstBox->x1 > pScrn->currentMode->HDisplay) dstBox->x1 = pScrn->currentMode->HDisplay - 1; + if (dstBox->x2 > pScrn->currentMode->HDisplay) dstBox->x2 = pScrn->currentMode->HDisplay - 1; + + /* nothing do to */ + if ((!dstBox->x1 && !dstBox->x2) || (!dstBox->y1 && !dstBox->y2)) { + ErrorF("NOTHING TO DO\n"); + return; + } + if ((dstBox->x1 == (pScrn->currentMode->HDisplay - 1) && + dstBox->x2 == (pScrn->currentMode->HDisplay - 1)) || + (dstBox->y1 == vactive && + dstBox->y2 == vactive)) { + ErrorF("NOTHING TO DO\n"); + return; + } + if ((dstBox->y2 - dstBox->y1) <= N_VERT_Y_TAPS) { + ErrorF("NOTHING TO DO\n"); + return; + } + if ((dstBox->x2 - dstBox->x1) <= 2) { + ErrorF("NOTHING TO DO\n"); + return; + } + } + + if (IS_I9XX(pI830)) { shift = 6; mask = 0x3f; } else { @@ -1198,17 +1573,6 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, offsetu = pPriv->UBuf1offset; } -#if VIDEO_DEBUG - CompareOverlay(pI830, (CARD32 *) overlay, 0x100); -#endif - - /* When in dual head with different bpp setups we need to refresh the - * color key, so let's reset the video parameters and refresh here */ -#if 0 - if (pI830->entityPrivate) -#endif - I830ResetVideo(pScrn); - switch (id) { case FOURCC_YV12: case FOURCC_I420: @@ -1221,7 +1585,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, swidth = ((offsety + width + mask) >> shift) - (offsety >> shift); - if (IS_I915G(pI830) || IS_I915GM(pI830)) + if (IS_I9XX(pI830)) swidth <<= 1; swidth -= 1; @@ -1233,7 +1597,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, swidth = ((offsetu + (width / 2) + mask) >> shift) - (offsetu >> shift); - if (IS_I915G(pI830) || IS_I915GM(pI830)) + if (IS_I9XX(pI830)) swidth <<= 1; swidth -= 1; @@ -1257,7 +1621,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, swidth = ((offsety + (width << 1) + mask) >> shift) - (offsety >> shift); - if (IS_I915G(pI830) || IS_I915GM(pI830)) + if (IS_I9XX(pI830)) swidth <<= 1; swidth -= 1; @@ -1272,19 +1636,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, break; } - if (pPriv->oneLineMode) { - /* change the coordinates with panel fitting active */ - dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1; - dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1; - - /* Now, alter the height, so we scale to the correct size */ - drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1; - - /* Keep the engine happy */ - if (dstBox->y1 < 0) dstBox->y1 = 0; - if (dstBox->y2 < 0) dstBox->y2 = 0; - } - + overlay->OCMD = OVERLAY_ENABLE; overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1; @@ -1299,13 +1651,15 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, overlay->OBUF_0U = pPriv->UBuf0offset; overlay->OBUF_0V = pPriv->VBuf0offset; - overlay->OBUF_1Y = pPriv->YBuf1offset; - overlay->OBUF_1U = pPriv->UBuf1offset; - overlay->OBUF_1V = pPriv->VBuf1offset; + if(pPriv->doubleBuffer) { + overlay->OBUF_1Y = pPriv->YBuf1offset; + overlay->OBUF_1U = pPriv->UBuf1offset; + overlay->OBUF_1V = pPriv->VBuf1offset; + } - ErrorF("Buffers: Y0: 0x%08x, U0: 0x%08x, V0: 0x%08x\n", overlay->OBUF_0Y, + ErrorF("Buffers: Y0: 0x%lx, U0: 0x%lx, V0: 0x%lx\n", overlay->OBUF_0Y, overlay->OBUF_0U, overlay->OBUF_0V); - ErrorF("Buffers: Y1: 0x%08x, U1: 0x%08x, V1: 0x%08x\n", overlay->OBUF_1Y, + ErrorF("Buffers: Y1: 0x%lx, U1: 0x%lx, V1: 0x%lx\n", overlay->OBUF_1Y, overlay->OBUF_1U, overlay->OBUF_1V); #if 0 @@ -1330,11 +1684,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, } #endif -#if 1 - overlay->OCMD = OVERLAY_ENABLE; -#endif - - ErrorF("pos: 0x%08x, size: 0x%08x\n", overlay->DWINPOS, overlay->DWINSZ); + ErrorF("pos: 0x%lx, size: 0x%lx\n", overlay->DWINPOS, overlay->DWINSZ); ErrorF("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h); /* @@ -1383,6 +1733,18 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, ErrorF("UV xscale: %x.%03x, UV yscale: %x.%03x\n", xscaleIntUV, xscaleFractUV & 0xFFF, yscaleIntUV, yscaleFractUV & 0xFFF); + /* shouldn't get here */ + if (xscaleInt > 7) { + ErrorF("xscale: bad scale\n"); + return; + } + + /* shouldn't get here */ + if (xscaleIntUV > 7) { + ErrorF("xscaleUV: bad scale\n"); + return; + } + newval = (xscaleInt << 16) | ((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20); if (newval != overlay->YRGBSCALE) { @@ -1480,7 +1842,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, else overlay->OCMD |= BUFFER1; - ErrorF("OCMD is 0x%08x\n", overlay->OCMD); + ErrorF("OCMD is 0x%lx\n", overlay->OCMD); OVERLAY_UPDATE; } @@ -1489,7 +1851,7 @@ static FBLinearPtr I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) { ScreenPtr pScreen; - FBLinearPtr new_linear; + FBLinearPtr new_linear = NULL; DPRINTF(PFX, "I830AllocateMemory\n"); @@ -1514,8 +1876,10 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, PRIORITY_EXTREME); - if (max_size < size) + if (max_size < size) { + ErrorF("No memory available\n"); return NULL; + } xf86PurgeUnlockedOffscreenAreas(pScreen); new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, @@ -1533,11 +1897,14 @@ I830PutImage(ScrnInfoPtr pScrn, short drw_w, short drw_h, int id, unsigned char *buf, short width, short height, - Bool sync, RegionPtr clipBoxes, pointer data) + Bool sync, RegionPtr clipBoxes, pointer data, + DrawablePtr pDraw) { I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = (I830PortPrivPtr) data; ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + I830OverlayRegPtr overlay = + (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); INT32 x1, x2, y1, y2; int srcPitch, srcPitch2 = 0, dstPitch; int top, left, npixels, nlines, size, loops; @@ -1585,68 +1952,106 @@ I830PutImage(ScrnInfoPtr pScrn, width, height)) return Success; - dstBox.x1 -= pScrn->frameX0; - dstBox.x2 -= pScrn->frameX0; - dstBox.y1 -= pScrn->frameY0; - dstBox.y2 -= pScrn->frameY0; - switch (id) { case FOURCC_YV12: case FOURCC_I420: srcPitch = (width + 3) & ~3; srcPitch2 = ((width >> 1) + 3) & ~3; - dstPitch = ((width / 2) + 63) & ~63; /* of chroma */ - size = dstPitch * height * 3; +#if 1 + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + dstPitch = ((height / 2) + 63) & ~63; + size = dstPitch * width * 3; + } else { + dstPitch = ((width / 2) + 63) & ~63; /* of chroma */ + size = dstPitch * height * 3; + } +#else + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + dstPitch = ((height / 2) + 511) & ~511; + size = dstPitch * width * 3; + } else { + dstPitch = ((width / 2) + 511) & ~511; /* of chroma */ + size = dstPitch * height * 3; + } +#endif break; case FOURCC_UYVY: case FOURCC_YUY2: default: srcPitch = width << 1; - dstPitch = (srcPitch + 63) & ~63; /* of chroma */ - size = dstPitch * height; +#if 1 + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + dstPitch = ((height << 1) + 63) & ~63; + size = dstPitch * width; + } else { + dstPitch = ((width << 1) + 63) & ~63; /* of chroma */ + size = dstPitch * height; + } +#else + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + dstPitch = ((height << 1) + 511) & ~511; + size = dstPitch * width; + } else { + dstPitch = ((width << 1) + 511) & ~511; /* of chroma */ + size = dstPitch * height; + } +#endif break; } ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size); /* size is multiplied by 2 because we have two buffers that are flipping */ - if (!(pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear, size * 2 / pI830->cpp))) + pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear, + (pPriv->doubleBuffer ? size * 2 : size) / pI830->cpp); + + if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY)) return BadAlloc; /* fixup pointers */ - pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear->offset * pI830->cpp; - pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); - pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); - - pPriv->YBuf1offset = pPriv->YBuf0offset + size; - pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); - pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); - - /* XXX We could potentially use MI_WAIT_FOR_OVERLAY here instead - * of this code....*/ + pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp; + if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset = pPriv->YBuf0offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2); + } + } else { + pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); + pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2); + if(pPriv->doubleBuffer) { + pPriv->YBuf1offset = pPriv->YBuf0offset + size; + pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); + pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2); + } + } /* Make sure this buffer isn't in use */ loops = 0; - while (loops < 1000000) { + if (*pI830->overlayOn && pPriv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) { + while (loops < 1000000) { #if USE_USLEEP_FOR_VIDEO - usleep(10); + usleep(10); #endif - if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) { - break; + if (((INREG(DOVSTA) & OC_BUF) >> 20) == pPriv->currentBuf) { + break; + } + loops++; } - loops++; - } - if (loops >= 1000000) { - ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf); + if (loops >= 1000000) { + ErrorF("loops (1) maxed out for buffer %d\n", pPriv->currentBuf); #if 0 - pPriv->currentBuf = !pPriv->currentBuf; + pPriv->currentBuf = !pPriv->currentBuf; #endif - } + } - /* buffer swap */ - if (pPriv->currentBuf == 0) - pPriv->currentBuf = 1; - else - pPriv->currentBuf = 0; + /* buffer swap */ + if (pPriv->currentBuf == 0) + pPriv->currentBuf = 1; + else + pPriv->currentBuf = 0; + } /* copy data */ top = y1 >> 16; @@ -1690,14 +2095,22 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { + I830Ptr pI830 = I830PTR(pScrn); int size, tmp; - DPRINTF(PFX, "I830QueryImageAttributes: w is %d, h is %d\n", *w, *h); + ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h); + if (IS_845G(pI830) || IS_I830(pI830)) { + if (*w > IMAGE_MAX_WIDTH_LEGACY) + *w = IMAGE_MAX_WIDTH_LEGACY; + if (*h > IMAGE_MAX_HEIGHT_LEGACY) + *h = IMAGE_MAX_HEIGHT_LEGACY; + } else { if (*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; if (*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + } *w = (*w + 1) & ~1; if (offsets) @@ -1767,24 +2180,25 @@ I830BlockHandler(int i, pScreen->BlockHandler = I830BlockHandler; if (pPriv->videoStatus & TIMER_MASK) { - UpdateCurrentTime(); + Time now = currentTime.milliseconds; if (pPriv->videoStatus & OFF_TIMER) { - if (pPriv->offTime < currentTime.milliseconds) { + if (pPriv->offTime < now) { /* Turn off the overlay */ + ErrorF("BLOCKHANDLER\n"); overlay->OCMD &= ~OVERLAY_ENABLE; - - OVERLAY_UPDATE; - - OVERLAY_OFF; + OVERLAY_UPDATE; +#if 1 + OVERLAY_OFF; +#endif pPriv->videoStatus = FREE_TIMER; - pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + pPriv->freeTime = now + FREE_DELAY; if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; } } else { /* FREE_TIMER */ - if (pPriv->freeTime < currentTime.milliseconds) { + if (pPriv->freeTime < now) { if (pPriv->linear) { xf86FreeOffscreenLinear(pPriv->linear); pPriv->linear = NULL; @@ -1815,9 +2229,18 @@ I830AllocateSurface(ScrnInfoPtr pScrn, OffscreenPrivPtr pPriv; I830Ptr pI830 = I830PTR(pScrn); - DPRINTF(PFX, "I830AllocateSurface\n"); + ErrorF("I830AllocateSurface\n"); + + if (IS_845G(pI830) || IS_I830(pI830)) { + if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY)) + return BadAlloc; + } else { + if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) + return BadAlloc; + } - if ((w > 1024) || (h > 1024)) + /* What to do when rotated ?? */ + if (pI830->rotation != RR_Rotate_0) return BadAlloc; w = (w + 1) & ~1; @@ -1857,7 +2280,7 @@ I830AllocateSurface(ScrnInfoPtr pScrn, surface->offsets[0] = linear->offset * bpp; surface->devPrivate.ptr = (pointer) pPriv; - memset(pI830->FbBase + pScrn->fbOffset + surface->offsets[0], 0, size); + memset(pI830->FbBase + pI830->FrontBuffer.Start + surface->offsets[0], 0, size); return Success; } @@ -1874,11 +2297,12 @@ I830StopSurface(XF86SurfacePtr surface) I830OverlayRegPtr overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + ErrorF("StopSurface\n"); overlay->OCMD &= ~OVERLAY_ENABLE; - OVERLAY_UPDATE; - +#if 1 OVERLAY_OFF; +#endif if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; @@ -1929,11 +2353,13 @@ I830DisplaySurface(XF86SurfacePtr surface, ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn); + I830OverlayRegPtr overlay = + (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); INT32 x1, y1, x2, y2; INT32 loops = 0; BoxRec dstBox; - DPRINTF(PFX, "I830DisplaySurface\n"); + ErrorF("I830DisplaySurface\n"); if (pI830->entityPrivate) { if (pI830->entityPrivate->XvInUse != -1 && @@ -1965,35 +2391,35 @@ I830DisplaySurface(XF86SurfacePtr surface, surface->width, surface->height)) return Success; - dstBox.x1 -= pScrn->frameX0; - dstBox.x2 -= pScrn->frameX0; - dstBox.y1 -= pScrn->frameY0; - dstBox.y2 -= pScrn->frameY0; - /* fixup pointers */ pI830Priv->YBuf0offset = surface->offsets[0]; pI830Priv->YBuf1offset = pI830Priv->YBuf0offset; - /* XXX We could potentially use MI_WAIT_FOR_OVERLAY here instead - * of this code....*/ - - /* wait for the last rendered buffer to be flipped in */ - while (((INREG(DOVSTA) & OC_BUF) >> 20) != pI830Priv->currentBuf) { + /* Make sure this buffer isn't in use */ + loops = 0; + if (*pI830->overlayOn && pI830Priv->doubleBuffer && (overlay->OCMD & OVERLAY_ENABLE)) { + while (loops < 1000000) { #if USE_USLEEP_FOR_VIDEO - usleep(10); + usleep(10); +#endif + if (((INREG(DOVSTA) & OC_BUF) >> 20) == pI830Priv->currentBuf) { + break; + } + loops++; + } + if (loops >= 1000000) { + ErrorF("loops (1) maxed out for buffer %d\n", pI830Priv->currentBuf); +#if 0 + pI830Priv->currentBuf = !pI830Priv->currentBuf; #endif - if (loops == 200000) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n"); - break; } - loops++; - } - /* buffer swap */ - if (pI830Priv->currentBuf == 0) - pI830Priv->currentBuf = 1; - else - pI830Priv->currentBuf = 0; + /* buffer swap */ + if (pI830Priv->currentBuf == 0) + pI830Priv->currentBuf = 1; + else + pI830Priv->currentBuf = 0; + } I830DisplayVideo(pScrn, surface->id, surface->width, surface->height, surface->pitches[0], x1, y1, x2, y2, &dstBox, @@ -2018,6 +2444,8 @@ static void I830InitOffscreenImages(ScreenPtr pScreen) { XF86OffscreenImagePtr offscreenImages; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); /* need to free this someplace */ if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) { @@ -2025,15 +2453,20 @@ I830InitOffscreenImages(ScreenPtr pScreen) } offscreenImages[0].image = &Images[0]; - offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/; offscreenImages[0].alloc_surface = I830AllocateSurface; offscreenImages[0].free_surface = I830FreeSurface; offscreenImages[0].display = I830DisplaySurface; offscreenImages[0].stop = I830StopSurface; offscreenImages[0].setAttribute = I830SetSurfaceAttribute; offscreenImages[0].getAttribute = I830GetSurfaceAttribute; - offscreenImages[0].max_width = 1024; - offscreenImages[0].max_height = 1024; + if (IS_845G(pI830) || IS_I830(pI830)) { + offscreenImages[0].max_width = IMAGE_MAX_WIDTH_LEGACY; + offscreenImages[0].max_height = IMAGE_MAX_HEIGHT_LEGACY; + } else { + offscreenImages[0].max_width = IMAGE_MAX_WIDTH; + offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; + } offscreenImages[0].num_attributes = 1; offscreenImages[0].attributes = Attributes; @@ -2043,9 +2476,10 @@ I830InitOffscreenImages(ScreenPtr pScreen) void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode) { + I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv; - if (!I830PTR(pScrn)->adaptor) { + if (!pI830->adaptor) { return; } @@ -2062,6 +2496,8 @@ I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode) */ I830StopVideo(pScrn, pPriv, TRUE); + pPriv->overlayOK = FALSE; + pPriv->oneLineMode = FALSE; } @@ -2079,6 +2515,17 @@ I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode) if (!pPriv) return; + pPriv->overlayOK = TRUE; + + /* ensure pipe is updated on mode switch */ + if (!pI830->Clone) { + if (pPriv->pipe != pI830->pipe) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Changing XVideo pipe (%d to %d).\n", pPriv->pipe, pI830->pipe); + pPriv->pipe = pI830->pipe; + } + } + if (pPriv->pipe == 0) { if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, diff --git a/src/i915_3d.c b/src/i915_3d.c new file mode 100644 index 00000000..b1f30ef2 --- /dev/null +++ b/src/i915_3d.c @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "i830.h" + +#include "i915_reg.h" + +void I915EmitInvarientState( ScrnInfoPtr pScrn ) +{ + I830Ptr pI830 = I830PTR(pScrn); + + BEGIN_LP_RING(20); + + OUT_RING(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0); + + OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_RING(0); + + OUT_RING(_3DSTATE_DFLT_SPEC_CMD); + OUT_RING(0); + + OUT_RING(_3DSTATE_DFLT_Z_CMD); + OUT_RING(0); + + /* Don't support texture crossbar yet */ + OUT_RING(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | + CSB_TCB(5, 5) | + CSB_TCB(6, 6) | + CSB_TCB(7, 7)); + + OUT_RING(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | + ENABLE_TEXKILL_3D_4D | + TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(3) | + (1)); + OUT_RING(0); + + /* XXX: Use this */ + OUT_RING(_3DSTATE_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + + OUT_RING(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_RING(0); + OUT_RING(0); + + OUT_RING(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + OUT_RING(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ + OUT_RING(0); + + /* Don't support twosided stencil yet */ + OUT_RING(_3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_TWO_SIDE | + 0 ); + + OUT_RING(0); + + ADVANCE_LP_RING(); +} diff --git a/src/i915_3d.h b/src/i915_3d.h new file mode 100644 index 00000000..fc4ca603 --- /dev/null +++ b/src/i915_3d.h @@ -0,0 +1,431 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2006 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: + * Eric Anholt <eric@anholt.net> + * + */ + +/* MASK_* are the unshifted bitmasks of the destination mask in arithmetic + * operations + */ +#define MASK_X 0x1 +#define MASK_Y 0x2 +#define MASK_Z 0x4 +#define MASK_W 0x8 +#define MASK_XYZ (MASK_X | MASK_Y | MASK_W) +#define MASK_XYZW (MASK_XYZ | MASK_W) +#define MASK_SATURATE 0x10 + +/* Temporary, undeclared regs. Preserved between phases */ +#define FS_R0 ((REG_TYPE_R << 8) | 0) +#define FS_R1 ((REG_TYPE_R << 8) | 1) +#define FS_R2 ((REG_TYPE_R << 8) | 2) +#define FS_R3 ((REG_TYPE_R << 8) | 3) + +/* Texture coordinate regs. Must be declared. */ +#define FS_T0 ((REG_TYPE_T << 8) | 0) +#define FS_T1 ((REG_TYPE_T << 8) | 1) +#define FS_T2 ((REG_TYPE_T << 8) | 2) +#define FS_T3 ((REG_TYPE_T << 8) | 3) +#define FS_T4 ((REG_TYPE_T << 8) | 4) +#define FS_T5 ((REG_TYPE_T << 8) | 5) +#define FS_T6 ((REG_TYPE_T << 8) | 6) +#define FS_T7 ((REG_TYPE_T << 8) | 7) +#define FS_T8 ((REG_TYPE_T << 8) | 8) +#define FS_T9 ((REG_TYPE_T << 8) | 9) +#define FS_T10 ((REG_TYPE_T << 8) | 10) + +/* Constant values */ +#define FS_C0 ((REG_TYPE_CONST << 8) | 0) +#define FS_C1 ((REG_TYPE_CONST << 8) | 1) +#define FS_C2 ((REG_TYPE_CONST << 8) | 2) +#define FS_C3 ((REG_TYPE_CONST << 8) | 3) + +/* Sampler regs */ +#define FS_S0 ((REG_TYPE_S << 8) | 0) +#define FS_S1 ((REG_TYPE_S << 8) | 1) +#define FS_S2 ((REG_TYPE_S << 8) | 2) +#define FS_S3 ((REG_TYPE_S << 8) | 3) + +/* Output color */ +#define FS_OC ((REG_TYPE_OC << 8) | 0) + +/* Output depth */ +#define FS_OD ((REG_TYPE_OD << 8) | 0) + +/* Unpreserved temporary regs */ +#define FS_U0 ((REG_TYPE_U << 8) | 0) +#define FS_U1 ((REG_TYPE_U << 8) | 1) +#define FS_U2 ((REG_TYPE_U << 8) | 2) +#define FS_U3 ((REG_TYPE_U << 8) | 3) + +#define REG_TYPE(reg) ((reg) >> 8) +#define REG_NR(reg) ((reg) & 0xff) + +struct i915_fs_op { + CARD32 ui[3]; +}; + +#define X_CHANNEL_VAL 1 +#define Y_CHANNEL_VAL 2 +#define Z_CHANNEL_VAL 3 +#define W_CHANNEL_VAL 4 +#define ZERO_CHANNEL_VAL 5 +#define ONE_CHANNEL_VAL 6 + +/** + * This structure represents the contents of an operand to an i915 fragment + * shader. + * + * It is not a hardware representation, though closely related. + */ +struct i915_fs_operand { + /**< REG_TYPE_* register type */ + int reg; + /**< *_CHANNEL_VAL swizzle value, with optional negation */ + int x; + /**< *_CHANNEL_VAL swizzle value, with optional negation */ + int y; + /**< *_CHANNEL_VAL swizzle value, with optional negation */ + int z; + /**< *_CHANNEL_VAL swizzle value, with optional negation */ + int w; +}; + +/** + * Construct an operand description for the fragment shader. + * + * \param regtype FS_* register used as the source value for X/Y/Z/W sources. + * \param x *_CHANNEL_VAL swizzle value prefix for operand X channel, with + * optional negation. + * \param y *_CHANNEL_VAL swizzle value prefix for operand Y channel, with + * optional negation. + * \param z *_CHANNEL_VAL swizzle value prefix for operand Z channel, with + * optional negation. + * \param w *_CHANNEL_VAL swizzle value prefix for operand W channel, with + * optional negation. + */ +#define i915_fs_operand(reg, x, y, z, w) \ + _i915_fs_operand(reg, \ + x##_CHANNEL_VAL, y##_CHANNEL_VAL, \ + z##_CHANNEL_VAL, w##_CHANNEL_VAL) + +/** + * Construct an oeprand description for using a register with no swizzling + */ +#define i915_fs_operand_reg(reg) \ + i915_fs_operand(reg, X, Y, Z, W) + +static inline struct i915_fs_operand +_i915_fs_operand(int reg, int x, int y, int z, int w) +{ + struct i915_fs_operand operand; + + operand.reg = reg; + operand.x = x; + operand.y = y; + operand.z = z; + operand.w = w; + + return operand; +} + +/** + * Returns an operand containing (0.0, 0.0, 0.0, 0.0). + */ +static inline struct i915_fs_operand +i915_fs_operand_zero(void) +{ + return i915_fs_operand(FS_R0, ZERO, ZERO, ZERO, ZERO); +} + +/** + * Returns an unused operand + */ +#define i915_fs_operand_none() i915_fs_operand_zero() + +/** + * Returns an operand containing (1.0, 1.0, 1.0, 1.0). + */ +static inline struct i915_fs_operand +i915_fs_operand_one(void) +{ + return i915_fs_operand(FS_R0, ONE, ONE, ONE, ONE); +} + +static inline int +i915_get_hardware_channel_val(int channel_val) +{ + if (channel_val < 0) + channel_val = -channel_val; + + switch (channel_val) { + case X_CHANNEL_VAL: + return SRC_X; + case Y_CHANNEL_VAL: + return SRC_Y; + case Z_CHANNEL_VAL: + return SRC_Z; + case W_CHANNEL_VAL: + return SRC_W; + case ZERO_CHANNEL_VAL: + return SRC_ZERO; + case ONE_CHANNEL_VAL: + return SRC_ONE; + } + FatalError("Bad channel value %d\n", channel_val); +} + +/** + * Outputs a fragment shader command to declare a sampler or texture register. + */ +#define i915_fs_dcl(reg) \ +do { \ + FS_OUT(_i915_fs_dcl(reg)); \ +} while (0) + +/** + * Constructs a fragment shader command to declare a sampler or texture + * register. + */ +static inline struct i915_fs_op +_i915_fs_dcl(int reg) +{ + struct i915_fs_op op; + + op.ui[0] = D0_DCL | (REG_TYPE(reg) << D0_TYPE_SHIFT) | + (REG_NR(reg) << D0_NR_SHIFT); + op.ui[1] = 0; + op.ui[2] = 0; + if (REG_TYPE(reg) != REG_TYPE_S) + op.ui[0] |= D0_CHANNEL_ALL; + + return op; +} + +/** + * Constructs a fragment shader command to load from a texture sampler. + */ +#define i915_fs_texld(dest_reg, sampler_reg, address_reg) \ +do { \ + FS_OUT(_i915_fs_texld(T0_TEXLD, dest_reg, sampler_reg, address_reg)); \ +} while (0) + +static inline struct i915_fs_op +_i915_fs_texld(int load_op, int dest_reg, int sampler_reg, int address_reg) +{ + struct i915_fs_op op; + + op.ui[0] = 0; + op.ui[1] = 0; + op.ui[2] = 0; + + if (REG_TYPE(sampler_reg) != REG_TYPE_S) + FatalError("Bad sampler reg type\n"); + + op.ui[0] |= load_op; + op.ui[0] |= REG_TYPE(dest_reg) << T0_DEST_TYPE_SHIFT; + op.ui[0] |= REG_NR(dest_reg) << T0_DEST_NR_SHIFT; + op.ui[0] |= REG_NR(sampler_reg) << T0_SAMPLER_NR_SHIFT; + op.ui[1] |= REG_TYPE(address_reg) << T1_ADDRESS_REG_TYPE_SHIFT; + op.ui[1] |= REG_NR(address_reg) << T1_ADDRESS_REG_NR_SHIFT; + + return op; +} + +#define i915_fs_arith(op, dest_reg, operand0, operand1, operand2) \ + _i915_fs_arith(A0_##op, dest_reg, operand0, operand1, operand2) + +static inline struct i915_fs_op +_i915_fs_arith(int cmd, int dest_reg, + struct i915_fs_operand operand0, + struct i915_fs_operand operand1, + struct i915_fs_operand operand2) +{ + struct i915_fs_op op; + + op.ui[0] = 0; + op.ui[1] = 0; + op.ui[2] = 0; + + /* Set up destination register and write mask */ + op.ui[0] |= cmd; + op.ui[0] |= REG_TYPE(dest_reg) << A0_DEST_TYPE_SHIFT; + op.ui[0] |= REG_NR(dest_reg) << A0_DEST_NR_SHIFT; + op.ui[0] |= A0_DEST_CHANNEL_ALL; + + /* Set up operand 0 */ + op.ui[0] |= REG_TYPE(operand0.reg) << A0_SRC0_TYPE_SHIFT; + op.ui[0] |= REG_NR(operand0.reg) << A0_SRC0_NR_SHIFT; + + op.ui[1] |= i915_get_hardware_channel_val(operand0.x) << + A1_SRC0_CHANNEL_X_SHIFT; + if (operand0.x < 0) + op.ui[1] |= A1_SRC0_CHANNEL_X_NEGATE; + + op.ui[1] |= i915_get_hardware_channel_val(operand0.y) << + A1_SRC0_CHANNEL_Y_SHIFT; + if (operand0.y < 0) + op.ui[1] |= A1_SRC0_CHANNEL_Y_NEGATE; + + op.ui[1] |= i915_get_hardware_channel_val(operand0.z) << + A1_SRC0_CHANNEL_Z_SHIFT; + if (operand0.z < 0) + op.ui[1] |= A1_SRC0_CHANNEL_Z_NEGATE; + + op.ui[1] |= i915_get_hardware_channel_val(operand0.w) << + A1_SRC0_CHANNEL_W_SHIFT; + if (operand0.w < 0) + op.ui[1] |= A1_SRC0_CHANNEL_W_NEGATE; + + /* Set up operand 1 */ + op.ui[1] |= REG_TYPE(operand1.reg) << A1_SRC1_TYPE_SHIFT; + op.ui[1] |= REG_NR(operand1.reg) << A1_SRC1_NR_SHIFT; + + op.ui[1] |= i915_get_hardware_channel_val(operand1.x) << + A1_SRC1_CHANNEL_X_SHIFT; + if (operand1.x < 0) + op.ui[1] |= A1_SRC1_CHANNEL_X_NEGATE; + + op.ui[1] |= i915_get_hardware_channel_val(operand1.y) << + A1_SRC1_CHANNEL_Y_SHIFT; + if (operand1.y < 0) + op.ui[1] |= A1_SRC1_CHANNEL_Y_NEGATE; + + op.ui[2] |= i915_get_hardware_channel_val(operand1.z) << + A2_SRC1_CHANNEL_Z_SHIFT; + if (operand1.z < 0) + op.ui[2] |= A2_SRC1_CHANNEL_Z_NEGATE; + + op.ui[2] |= i915_get_hardware_channel_val(operand1.w) << + A2_SRC1_CHANNEL_W_SHIFT; + if (operand1.w < 0) + op.ui[2] |= A2_SRC1_CHANNEL_W_NEGATE; + + /* Set up operand 2 */ + op.ui[2] |= REG_TYPE(operand2.reg) << A2_SRC2_TYPE_SHIFT; + op.ui[2] |= REG_NR(operand2.reg) << A2_SRC2_NR_SHIFT; + + op.ui[2] |= i915_get_hardware_channel_val(operand2.x) << + A2_SRC2_CHANNEL_X_SHIFT; + if (operand2.x < 0) + op.ui[2] |= A2_SRC2_CHANNEL_X_NEGATE; + + op.ui[2] |= i915_get_hardware_channel_val(operand2.y) << + A2_SRC2_CHANNEL_Y_SHIFT; + if (operand2.y < 0) + op.ui[2] |= A2_SRC2_CHANNEL_Y_NEGATE; + + op.ui[2] |= i915_get_hardware_channel_val(operand2.z) << + A2_SRC2_CHANNEL_Z_SHIFT; + if (operand2.z < 0) + op.ui[2] |= A2_SRC2_CHANNEL_Z_NEGATE; + + op.ui[2] |= i915_get_hardware_channel_val(operand2.w) << + A2_SRC2_CHANNEL_W_SHIFT; + if (operand2.w < 0) + op.ui[2] |= A2_SRC2_CHANNEL_W_NEGATE; + + return op; +} + +/** + * Move the values in operand0 to the dest reg with the masking/saturation + * specified. + */ +#define i915_fs_mov_masked(dest_reg, dest_mask, operand0) \ +do { \ + struct i915_fs_op op; \ + \ + op = i915_fs_arith(MOV, dest_reg, operand0, i915_fs_operand_none(), \ + i915_fs_operand_none()); \ + op.ui[0] &= ~A0_DEST_CHANNEL_ALL; \ + op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \ + if ((dest_mask) & MASK_SATURATE) \ + op.ui[0] |= A0_DEST_SATURATE; \ + \ + FS_OUT(op); \ +} while (0) + +/** Add operand0 and operand1 and put the result in dest_reg */ +#define i915_fs_add(dest_reg, operand0, operand1) \ +do { \ + FS_OUT(i915_fs_arith(ADD, dest_reg, operand0, operand1, \ + i915_fs_operand_none())); \ +} while (0) + +/** + * Perform a 3-component dot-product of operand0 and operand1 and put the + * resulting scalar in the channels of dest_reg specified by the dest_mask. + */ +#define i915_fs_dp3_masked(dest_reg, dest_mask, operand0, operand1) \ +do { \ + struct i915_fs_op op; \ + \ + op = i915_fs_arith(DP3, dest_reg, operand0, i915_fs_operand_none(), \ + i915_fs_operand_none()); \ + op.ui[0] &= ~A0_DEST_CHANNEL_ALL; \ + op.ui[0] |= ((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT; \ + if ((dest_mask) & MASK_SATURATE) \ + op.ui[0] |= A0_DEST_SATURATE; \ + \ + FS_OUT(op); \ +} while (0) + +/** + * Sets up local state for accumulating a fragment shader buffer. + * + * \param x maximum number of shader commands that may be used between + * a FS_START and FS_END + */ +#define FS_LOCALS(x) \ + CARD32 _shader_buf[(x) * 3]; \ + int _max_shader_commands = x; \ + int _cur_shader_commands + +#define FS_BEGIN() \ +do { \ + _cur_shader_commands = 0; \ +} while (0) + +#define FS_OUT(_shaderop) \ +do { \ + _shader_buf[_cur_shader_commands * 3 + 0] = _shaderop.ui[0]; \ + _shader_buf[_cur_shader_commands * 3 + 1] = _shaderop.ui[1]; \ + _shader_buf[_cur_shader_commands * 3 + 2] = _shaderop.ui[2]; \ + if (++_cur_shader_commands > _max_shader_commands) \ + FatalError("fragment shader command buffer exceeded (%d)\n", \ + _cur_shader_commands); \ +} while (0) + +#define FS_END() \ +do { \ + int _i; \ + BEGIN_LP_RING(_cur_shader_commands * 3 + 1); \ + OUT_RING(_3DSTATE_PIXEL_SHADER_PROGRAM | \ + (_cur_shader_commands * 3 - 1)); \ + for (_i = 0; _i < _cur_shader_commands * 3; _i++) \ + OUT_RING(_shader_buf[_i]); \ + ADVANCE_LP_RING(); \ +} while (0); diff --git a/src/i915_reg.h b/src/i915_reg.h new file mode 100644 index 00000000..6d4f8fc0 --- /dev/null +++ b/src/i915_reg.h @@ -0,0 +1,848 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + + +#ifndef _I915_REG_H_ +#define _I915_REG_H_ + +#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define CMD_3D (0x3<<29) + +#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_CLEAR_RECT (0xa<<18) +#define PRIM3D_ZONE_INIT (0xd<<18) +#define PRIM3D_MASK (0x1f<<18) + +/* p137 */ +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) + +/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ +#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) +#define BFO_ENABLE_STENCIL_REF (1<<23) +#define BFO_STENCIL_REF_SHIFT 15 +#define BFO_STENCIL_REF_MASK (0xff<<15) +#define BFO_ENABLE_STENCIL_FUNCS (1<<14) +#define BFO_STENCIL_TEST_SHIFT 11 +#define BFO_STENCIL_TEST_MASK (0x7<<11) +#define BFO_STENCIL_FAIL_SHIFT 8 +#define BFO_STENCIL_FAIL_MASK (0x7<<8) +#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 +#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) +#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 +#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) +#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) +#define BFO_STENCIL_TWO_SIDE (1<<0) + + +/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ +#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) +#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) +#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) +#define BFM_STENCIL_TEST_MASK_SHIFT 8 +#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) +#define BFM_STENCIL_WRITE_MASK_SHIFT 0 +#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) + + + +/* 3DSTATE_BIN_CONTROL p141 */ + +/* p143 */ +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +/* 3DSTATE_CHROMA_KEY */ + +/* 3DSTATE_CLEAR_PARAMETERS, p150 */ + +/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + + + +/* 3DSTATE_COORD_SET_BINDINGS, p154 */ +#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) +#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) + +/* p156 */ +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +/* p157 */ +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +/* p158 */ +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ +#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) +/* scale in dword 1 */ + + +/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ +#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<19) | 0x2) + +/* p161 */ +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define TEX_DEFAULT_COLOR_OGL (0<<30) +#define TEX_DEFAULT_COLOR_D3D (1<<30) +#define ZR_EARLY_DEPTH (1<<29) +#define LOD_PRECLAMP_OGL (1<<28) +#define LOD_PRECLAMP_D3D (0<<28) +#define DITHER_FULL_ALWAYS (0<<26) +#define DITHER_FULL_ON_FB_BLEND (1<<26) +#define DITHER_CLAMPED_ALWAYS (2<<26) +#define LINEAR_GAMMA_BLEND_32BPP (1<<25) +#define DEBUG_DISABLE_ENH_DITHER (1<<24) +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 (0<<1) +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + +/* p166 */ +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ + +/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ + + +/* _3DSTATE_FOG_COLOR, p173 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p174 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) +#define FMC1_FOGFUNC_VERTEX (0<<28) +#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) +#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) +#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) +#define FMC1_FOGFUNC_MASK (3<<28) +#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) +#define FMC1_FOGINDEX_Z (0<<25) +#define FMC1_FOGINDEX_W (1<<25) +#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) +#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) +#define FMC1_C1_ONE (1<<13) +#define FMC1_C1_MASK (0xffff<<4) +/* Dword 2 */ +#define FMC2_C2_ONE (1<<16) +/* Dword 3 */ +#define FMC3_D_ONE (1<<16) + + + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ +#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define IAB_MODIFY_ENABLE (1<<23) +#define IAB_ENABLE (1<<22) +#define IAB_MODIFY_FUNC (1<<21) +#define IAB_FUNC_SHIFT 16 +#define IAB_MODIFY_SRC_FACTOR (1<<11) +#define IAB_SRC_FACTOR_SHIFT 6 +#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) +#define IAB_MODIFY_DST_FACTOR (1<<5) +#define IAB_DST_FACTOR_SHIFT 0 +#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#define BLENDFACT_MASK 0x0f + +#define BLENDFUNC_ADD 0x0 +#define BLENDFUNC_SUBTRACT 0x1 +#define BLENDFUNC_REVERSE_SUBTRACT 0x2 +#define BLENDFUNC_MIN 0x3 +#define BLENDFUNC_MAX 0x4 +#define BLENDFUNC_MASK 0x7 + +/* 3DSTATE_LOAD_INDIRECT, p180 */ + +#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) +#define LI0_STATE_STATIC_INDIRECT (0x01<<8) +#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) +#define LI0_STATE_SAMPLER (0x04<<8) +#define LI0_STATE_MAP (0x08<<8) +#define LI0_STATE_PROGRAM (0x10<<8) +#define LI0_STATE_CONSTANTS (0x20<<8) + +#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SIS0_FORCE_LOAD (1<<1) +#define SIS0_BUFFER_VALID (1<<0) +#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) + +#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define DIS0_BUFFER_RESET (1<<1) +#define DIS0_BUFFER_VALID (1<<0) + +#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SSB0_FORCE_LOAD (1<<1) +#define SSB0_BUFFER_VALID (1<<0) +#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define MSB0_FORCE_LOAD (1<<1) +#define MSB0_BUFFER_VALID (1<<0) +#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSP0_FORCE_LOAD (1<<1) +#define PSP0_BUFFER_VALID (1<<0) +#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSC0_FORCE_LOAD (1<<1) +#define PSC0_BUFFER_VALID (1<<0) +#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) + + + + + +/* _3DSTATE_RASTERIZATION_RULES */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_TEXKILL_3D_4D (1<<10) +#define TEXKILL_3D (0<<9) +#define TEXKILL_4D (1<<9) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) + +/* _3DSTATE_SCISSOR_ENABLE, p256 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* p189 */ +#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) +#define I1_LOAD_S(n) (1<<(4+n)) + +#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_AUTO_CACHE_INV_DISABLE (1<<0) + +#define S1_VERTEX_WIDTH_SHIFT 24 +#define S1_VERTEX_WIDTH_MASK (0x3f<<24) +#define S1_VERTEX_PITCH_SHIFT 16 +#define S1_VERTEX_PITCH_MASK (0x3f<<16) + +#define TEXCOORDFMT_2D 0x0 +#define TEXCOORDFMT_3D 0x1 +#define TEXCOORDFMT_4D 0x2 +#define TEXCOORDFMT_1D 0x3 +#define TEXCOORDFMT_2D_16 0x4 +#define TEXCOORDFMT_4D_16 0x5 +#define TEXCOORDFMT_NOT_PRESENT 0xf +#define S2_TEXCOORD_FMT0_MASK 0xf +#define S2_TEXCOORD_FMT1_SHIFT 4 +#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) +#define S2_TEXCOORD_NONE (~0) + +/* S3 not interesting */ + +#define S4_POINT_WIDTH_SHIFT 23 +#define S4_POINT_WIDTH_MASK (0x1ff<<23) +#define S4_LINE_WIDTH_SHIFT 19 +#define S4_LINE_WIDTH_ONE (0x2<<19) +#define S4_LINE_WIDTH_MASK (0xf<<19) +#define S4_FLATSHADE_ALPHA (1<<18) +#define S4_FLATSHADE_FOG (1<<17) +#define S4_FLATSHADE_SPECULAR (1<<16) +#define S4_FLATSHADE_COLOR (1<<15) +#define S4_CULLMODE_BOTH (0<<13) +#define S4_CULLMODE_NONE (1<<13) +#define S4_CULLMODE_CW (2<<13) +#define S4_CULLMODE_CCW (3<<13) +#define S4_CULLMODE_MASK (3<<13) +#define S4_VFMT_POINT_WIDTH (1<<12) +#define S4_VFMT_SPEC_FOG (1<<11) +#define S4_VFMT_COLOR (1<<10) +#define S4_VFMT_DEPTH_OFFSET (1<<9) +#define S4_VFMT_XYZ (1<<6) +#define S4_VFMT_XYZW (2<<6) +#define S4_VFMT_XY (3<<6) +#define S4_VFMT_XYW (4<<6) +#define S4_VFMT_XYZW_MASK (7<<6) +#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) +#define S4_FORCE_DEFAULT_SPECULAR (1<<4) +#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) +#define S4_VFMT_FOG_PARAM (1<<2) +#define S4_SPRITE_POINT_ENABLE (1<<1) +#define S4_LINE_ANTIALIAS_ENABLE (1<<0) + +#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ + S4_VFMT_SPEC_FOG | \ + S4_VFMT_COLOR | \ + S4_VFMT_DEPTH_OFFSET | \ + S4_VFMT_XYZW_MASK | \ + S4_VFMT_FOG_PARAM) + + +#define S5_WRITEDISABLE_ALPHA (1<<31) +#define S5_WRITEDISABLE_RED (1<<30) +#define S5_WRITEDISABLE_GREEN (1<<29) +#define S5_WRITEDISABLE_BLUE (1<<28) +#define S5_WRITEDISABLE_MASK (0xf<<28) +#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) +#define S5_LAST_PIXEL_ENABLE (1<<26) +#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) +#define S5_FOG_ENABLE (1<<24) +#define S5_STENCIL_REF_SHIFT 16 +#define S5_STENCIL_REF_MASK (0xff<<16) +#define S5_STENCIL_TEST_FUNC_SHIFT 13 +#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) +#define S5_STENCIL_FAIL_SHIFT 10 +#define S5_STENCIL_FAIL_MASK (0x7<<10) +#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 +#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) +#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 +#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) +#define S5_STENCIL_WRITE_ENABLE (1<<3) +#define S5_STENCIL_TEST_ENABLE (1<<2) +#define S5_COLOR_DITHER_ENABLE (1<<1) +#define S5_LOGICOP_ENABLE (1<<0) + + +#define S6_ALPHA_TEST_ENABLE (1<<31) +#define S6_ALPHA_TEST_FUNC_SHIFT 28 +#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) +#define S6_ALPHA_REF_SHIFT 20 +#define S6_ALPHA_REF_MASK (0xff<<20) +#define S6_DEPTH_TEST_ENABLE (1<<19) +#define S6_DEPTH_TEST_FUNC_SHIFT 16 +#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) +#define S6_CBUF_BLEND_ENABLE (1<<15) +#define S6_CBUF_BLEND_FUNC_SHIFT 12 +#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) +#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 +#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) +#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 +#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) +#define S6_DEPTH_WRITE_ENABLE (1<<3) +#define S6_COLOR_WRITE_ENABLE (1<<2) +#define S6_TRISTRIP_PV_SHIFT 0 +#define S6_TRISTRIP_PV_MASK (0x3<<0) + +#define S7_DEPTH_OFFSET_CONST_MASK ~0 + +/* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ +/* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ + + +/* _3DSTATE_MODES_4, p218 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK (0xf<<18) +#define LOGICOP_COPY 0xc +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) ((x)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p220 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define PIPELINE_FLUSH_RENDER_CACHE (1<<18) +#define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) + + +/* p221 */ +#define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) +#define PS1_REG(n) (1<<(n)) +#define PS2_CONST_X(n) (n) +#define PS3_CONST_Y(n) (n) +#define PS4_CONST_Z(n) (n) +#define PS5_CONST_W(n) (n) + +/* p222 */ + + +#define I915_MAX_TEX_INDIRECT 4 +#define I915_MAX_TEX_INSN 32 +#define I915_MAX_ALU_INSN 64 +#define I915_MAX_DECL_INSN 27 +#define I915_MAX_TEMPORARY 16 + + +/* Each instruction is 3 dwords long, though most don't require all + * this space. Maximum of 123 instructions. Smaller maxes per insn + * type. + */ +#define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) + +#define REG_TYPE_R 0 /* temporary regs, no need to + * dcl, must be written before + * read -- Preserved between + * phases. + */ +#define REG_TYPE_T 1 /* Interpolated values, must be + * dcl'ed before use. + * + * 0..7: texture coord, + * 8: diffuse spec, + * 9: specular color, + * 10: fog parameter in w. + */ +#define REG_TYPE_CONST 2 /* Restriction: only one const + * can be referenced per + * instruction, though it may be + * selected for multiple inputs. + * Constants not initialized + * default to zero. + */ +#define REG_TYPE_S 3 /* sampler */ +#define REG_TYPE_OC 4 /* output color (rgba) */ +#define REG_TYPE_OD 5 /* output depth (w), xyz are + * temporaries. If not written, + * interpolated depth is used? + */ +#define REG_TYPE_U 6 /* unpreserved temporaries */ +#define REG_TYPE_MASK 0x7 +#define REG_NR_MASK 0xf + + +/* REG_TYPE_T: + */ +#define T_TEX0 0 +#define T_TEX1 1 +#define T_TEX2 2 +#define T_TEX3 3 +#define T_TEX4 4 +#define T_TEX5 5 +#define T_TEX6 6 +#define T_TEX7 7 +#define T_DIFFUSE 8 +#define T_SPECULAR 9 +#define T_FOG_W 10 /* interpolated fog is in W coord */ + +/* Arithmetic instructions */ + +/* .replicate_swizzle == selection and replication of a particular + * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww + */ +#define A0_NOP (0x0<<24) /* no operation */ +#define A0_ADD (0x1<<24) /* dst = src0 + src1 */ +#define A0_MOV (0x2<<24) /* dst = src0 */ +#define A0_MUL (0x3<<24) /* dst = src0 * src1 */ +#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ +#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ +#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ +#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ +#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ +#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ +#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ +#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ +#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ +#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ +#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ +#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ +#define A0_FLR (0x10<<24) /* dst = floor(src0) */ +#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ +#define A0_TRC (0x12<<24) /* dst = int(src0) */ +#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ +#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ +#define A0_DEST_SATURATE (1<<22) +#define A0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +#define A0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define A0_DEST_CHANNEL_X (1<<10) +#define A0_DEST_CHANNEL_Y (2<<10) +#define A0_DEST_CHANNEL_Z (4<<10) +#define A0_DEST_CHANNEL_W (8<<10) +#define A0_DEST_CHANNEL_ALL (0xf<<10) +#define A0_DEST_CHANNEL_SHIFT 10 +#define A0_SRC0_TYPE_SHIFT 7 +#define A0_SRC0_NR_SHIFT 2 + +#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) +#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) + + +#define SRC_X 0 +#define SRC_Y 1 +#define SRC_Z 2 +#define SRC_W 3 +#define SRC_ZERO 4 +#define SRC_ONE 5 + +#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) +#define A1_SRC0_CHANNEL_X_SHIFT 28 +#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) +#define A1_SRC0_CHANNEL_Y_SHIFT 24 +#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) +#define A1_SRC0_CHANNEL_Z_SHIFT 20 +#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) +#define A1_SRC0_CHANNEL_W_SHIFT 16 +#define A1_SRC1_TYPE_SHIFT 13 +#define A1_SRC1_NR_SHIFT 8 +#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) +#define A1_SRC1_CHANNEL_X_SHIFT 4 +#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) +#define A1_SRC1_CHANNEL_Y_SHIFT 0 + +#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) +#define A2_SRC1_CHANNEL_Z_SHIFT 28 +#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) +#define A2_SRC1_CHANNEL_W_SHIFT 24 +#define A2_SRC2_TYPE_SHIFT 21 +#define A2_SRC2_NR_SHIFT 16 +#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) +#define A2_SRC2_CHANNEL_X_SHIFT 12 +#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) +#define A2_SRC2_CHANNEL_Y_SHIFT 8 +#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) +#define A2_SRC2_CHANNEL_Z_SHIFT 4 +#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) +#define A2_SRC2_CHANNEL_W_SHIFT 0 + + + +/* Texture instructions */ +#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared + * sampler and address, and output + * filtered texel data to destination + * register */ +#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a + * perspective divide of the texture + * coordinate .xyz values by .w before + * sampling. */ +#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the + * computed LOD by w. Only S4.6 two's + * comp is used. This implies that a + * float to fixed conversion is + * done. */ +#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling + * operation. Simply kills the pixel + * if any channel of the address + * register is < 0.0. */ +#define T0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +/* Note: U (unpreserved) regs do not retain their values between + * phases (cannot be used for feedback) + * + * Note: oC and OD registers can only be used as the destination of a + * texture instruction once per phase (this is an implementation + * restriction). + */ +#define T0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ +#define T0_SAMPLER_NR_MASK (0xf<<0) + +#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ +/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ +#define T1_ADDRESS_REG_NR_SHIFT 17 +#define T2_MBZ 0 + +/* Declaration instructions */ +#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) + * register or an s (sampler) + * register. */ +#define D0_SAMPLE_TYPE_SHIFT 22 +#define D0_SAMPLE_TYPE_2D (0x0<<22) +#define D0_SAMPLE_TYPE_CUBE (0x1<<22) +#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) +#define D0_SAMPLE_TYPE_MASK (0x3<<22) + +#define D0_TYPE_SHIFT 19 +/* Allow: T, S */ +#define D0_NR_SHIFT 14 +/* Allow T: 0..10, S: 0..15 */ +#define D0_CHANNEL_X (1<<10) +#define D0_CHANNEL_Y (2<<10) +#define D0_CHANNEL_Z (4<<10) +#define D0_CHANNEL_W (8<<10) +#define D0_CHANNEL_ALL (0xf<<10) +#define D0_CHANNEL_NONE (0<<10) + +#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) +#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) + +/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse + * or specular declarations. + * + * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) + * + * Must be zero for S (sampler) dcls + */ +#define D1_MBZ 0 +#define D2_MBZ 0 + + + +/* p207 */ +#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) + +#define MS1_MAPMASK_SHIFT 0 +#define MS1_MAPMASK_MASK (0x8fff<<0) + +#define MS2_UNTRUSTED_SURFACE (1<<31) +#define MS2_ADDRESS_MASK 0xfffffffc +#define MS2_VERTICAL_LINE_STRIDE (1<<1) +#define MS2_VERTICAL_OFFSET (1<<1) + +#define MS3_HEIGHT_SHIFT 21 +#define MS3_WIDTH_SHIFT 10 +#define MS3_PALETTE_SELECT (1<<9) +#define MS3_MAPSURF_FORMAT_SHIFT 7 +#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) +#define MAPSURF_8BIT (1<<7) +#define MAPSURF_16BIT (2<<7) +#define MAPSURF_32BIT (3<<7) +#define MAPSURF_422 (5<<7) +#define MAPSURF_COMPRESSED (6<<7) +#define MAPSURF_4BIT_INDEXED (7<<7) +#define MS3_MT_FORMAT_MASK (0x7 << 3) +#define MS3_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_8BIT_A8 (4<<3) +#define MT_8BIT_MONO8 (5<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_I16 (7<<3) +#define MT_16BIT_L16 (8<<3) +#define MT_16BIT_A16 (9<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) +#define MT_32BIT_XBGR8888 (3<<3) +#define MT_32BIT_QWVU8888 (4<<3) +#define MT_32BIT_AXVU8888 (5<<3) +#define MT_32BIT_LXVU8888 (6<<3) +#define MT_32BIT_XLVU8888 (7<<3) +#define MT_32BIT_ARGB2101010 (8<<3) +#define MT_32BIT_ABGR2101010 (9<<3) +#define MT_32BIT_AWVU2101010 (0xA<<3) +#define MT_32BIT_GR1616 (0xB<<3) +#define MT_32BIT_VU1616 (0xC<<3) +#define MT_32BIT_xI824 (0xD<<3) +#define MT_32BIT_xA824 (0xE<<3) +#define MT_32BIT_xL824 (0xF<<3) +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define MT_COMPRESS_DXT1_RGB (4<<3) +#define MS3_USE_FENCE_REGS (1<<2) +#define MS3_TILED_SURFACE (1<<1) +#define MS3_TILE_WALK (1<<0) + +#define MS4_PITCH_SHIFT 21 +#define MS4_CUBE_FACE_ENA_NEGX (1<<20) +#define MS4_CUBE_FACE_ENA_POSX (1<<19) +#define MS4_CUBE_FACE_ENA_NEGY (1<<18) +#define MS4_CUBE_FACE_ENA_POSY (1<<17) +#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) +#define MS4_CUBE_FACE_ENA_POSZ (1<<15) +#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) +#define MS4_MAX_LOD_SHIFT 9 +#define MS4_MAX_LOD_MASK (0x3f<<9) +#define MS4_MIP_LAYOUT_LEGACY (0<<8) +#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) +#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) +#define MS4_VOLUME_DEPTH_SHIFT 0 +#define MS4_VOLUME_DEPTH_MASK (0xff<<0) + +/* p244 */ +#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) + +#define SS1_MAPMASK_SHIFT 0 +#define SS1_MAPMASK_MASK (0x8fff<<0) + +#define SS2_REVERSE_GAMMA_ENABLE (1<<31) +#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) +#define SS2_COLORSPACE_CONVERSION (1<<29) +#define SS2_CHROMAKEY_SHIFT 27 +#define SS2_BASE_MIP_LEVEL_SHIFT 22 +#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) +#define SS2_MIP_FILTER_SHIFT 20 +#define SS2_MIP_FILTER_MASK (0x3<<20) +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define SS2_MAG_FILTER_SHIFT 17 +#define SS2_MAG_FILTER_MASK (0x7<<17) +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 +#define FILTER_4X4_1 3 +#define FILTER_4X4_2 4 +#define FILTER_4X4_FLAT 5 +#define FILTER_6X5_MONO 6 /* XXX - check */ +#define SS2_MIN_FILTER_SHIFT 14 +#define SS2_MIN_FILTER_MASK (0x7<<14) +#define SS2_LOD_BIAS_SHIFT 5 +#define SS2_LOD_BIAS_ONE (0x10<<5) +#define SS2_LOD_BIAS_MASK (0x1ff<<5) +/* Shadow requires: + * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format + * FILTER_4X4_x MIN and MAG filters + */ +#define SS2_SHADOW_ENABLE (1<<4) +#define SS2_MAX_ANISO_MASK (1<<3) +#define SS2_MAX_ANISO_2 (0<<3) +#define SS2_MAX_ANISO_4 (1<<3) +#define SS2_SHADOW_FUNC_SHIFT 0 +#define SS2_SHADOW_FUNC_MASK (0x7<<0) +/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ + +#define SS3_MIN_LOD_SHIFT 24 +#define SS3_MIN_LOD_ONE (0x10<<24) +#define SS3_MIN_LOD_MASK (0xff<<24) +#define SS3_KILL_PIXEL_ENABLE (1<<17) +#define SS3_TCX_ADDR_MODE_SHIFT 12 +#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP_EDGE 2 +#define TEXCOORDMODE_CUBE 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORDMODE_MIRROR_ONCE 5 +#define SS3_TCY_ADDR_MODE_SHIFT 9 +#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) +#define SS3_TCZ_ADDR_MODE_SHIFT 6 +#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) +#define SS3_NORMALIZED_COORDS (1<<5) +#define SS3_TEXTUREMAP_INDEX_SHIFT 1 +#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) +#define SS3_DEINTERLACER_ENABLE (1<<0) + +#define SS4_BORDER_COLOR_MASK (~0) + +/* 3DSTATE_SPAN_STIPPLE, p258 + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + +#define FLUSH_MAP_CACHE (1<<0) +#define FLUSH_RENDER_CACHE (1<<1) + + +#endif |